@launchsecure/launch-kit 0.0.16 → 0.0.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/dist/chart-client/assets/index--120d9P9.css +1 -0
- package/dist/chart-client/assets/index-D7x8nz-H.js +441 -0
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/index-Bf8zdL3x.css +32 -0
- package/dist/client/assets/index-Ds9UP_cj.js +291 -0
- package/dist/client/index.html +2 -2
- package/dist/council-client/assets/index-CofZh7pS.css +1 -0
- package/dist/council-client/assets/index-Dc41S-R2.js +198 -0
- package/dist/council-client/index.html +21 -0
- package/dist/deck-client/assets/_baseUniq-2gclQXo7.js +1 -0
- package/dist/deck-client/assets/arc-DcMY5Wm0.js +1 -0
- package/dist/deck-client/assets/architectureDiagram-Q4EWVU46-B8iirmmJ.js +36 -0
- package/dist/deck-client/assets/blockDiagram-DXYQGD6D-B4JBLjmJ.js +132 -0
- package/dist/deck-client/assets/c4Diagram-AHTNJAMY-CojrJAk8.js +10 -0
- package/dist/deck-client/assets/channel-ERh5jKXV.js +1 -0
- package/dist/deck-client/assets/chunk-4BX2VUAB-Bmb_BMDo.js +1 -0
- package/dist/deck-client/assets/chunk-4TB4RGXK-CumBy8qe.js +206 -0
- package/dist/deck-client/assets/chunk-55IACEB6-Ka8Hb1wD.js +1 -0
- package/dist/deck-client/assets/chunk-EDXVE4YY-B3sIPiQo.js +1 -0
- package/dist/deck-client/assets/chunk-FMBD7UC4-C1tYkaqu.js +15 -0
- package/dist/deck-client/assets/chunk-OYMX7WX6-D7Wacbky.js +231 -0
- package/dist/deck-client/assets/chunk-QZHKN3VN-ChXI0vO3.js +1 -0
- package/dist/deck-client/assets/chunk-YZCP3GAM-BXhiqf8u.js +1 -0
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-CMi1Gaev.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-CMi1Gaev.js +1 -0
- package/dist/deck-client/assets/clone-DfWhlD4X.js +1 -0
- package/dist/deck-client/assets/cose-bilkent-S5V4N54A-Bqp3p68D.js +1 -0
- package/dist/deck-client/assets/cytoscape.esm-BQk4lpUV.js +331 -0
- package/dist/deck-client/assets/dagre-KV5264BT-BS-rtyhZ.js +4 -0
- package/dist/deck-client/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/deck-client/assets/diagram-5BDNPKRD-BIrj9YGI.js +10 -0
- package/dist/deck-client/assets/diagram-G4DWMVQ6-noHWPIg4.js +24 -0
- package/dist/deck-client/assets/diagram-MMDJMWI5-C2qHxvqV.js +43 -0
- package/dist/deck-client/assets/diagram-TYMM5635-BytnGQr-.js +24 -0
- package/dist/deck-client/assets/erDiagram-SMLLAGMA-BfK5m2YQ.js +85 -0
- package/dist/deck-client/assets/flowDiagram-DWJPFMVM-Cq925G1Z.js +162 -0
- package/dist/deck-client/assets/ganttDiagram-T4ZO3ILL-DhhHPAmj.js +292 -0
- package/dist/deck-client/assets/gitGraphDiagram-UUTBAWPF-B3Lc0h9q.js +106 -0
- package/dist/deck-client/assets/graph-RTawgVWm.js +1 -0
- package/dist/deck-client/assets/index-765AIQ9z.css +1 -0
- package/dist/deck-client/assets/index-BfIfJXmS.js +476 -0
- package/dist/deck-client/assets/infoDiagram-42DDH7IO-BlR584kX.js +2 -0
- package/dist/deck-client/assets/init-Gi6I4Gst.js +1 -0
- package/dist/deck-client/assets/ishikawaDiagram-UXIWVN3A-DygKoNGY.js +70 -0
- package/dist/deck-client/assets/journeyDiagram-VCZTEJTY-BnaiYp9N.js +139 -0
- package/dist/deck-client/assets/kanban-definition-6JOO6SKY-BQBUBzJC.js +89 -0
- package/dist/deck-client/assets/katex-DkKDou_j.js +257 -0
- package/dist/deck-client/assets/layout-DeZ8HI1T.js +1 -0
- package/dist/deck-client/assets/linear-C6roLi_9.js +1 -0
- package/dist/deck-client/assets/min-CbUksbuI.js +1 -0
- package/dist/deck-client/assets/mindmap-definition-QFDTVHPH-iNxV62yN.js +96 -0
- package/dist/deck-client/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/deck-client/assets/pieDiagram-DEJITSTG-DHVA0jaG.js +30 -0
- package/dist/deck-client/assets/quadrantDiagram-34T5L4WZ-DBeKKLUQ.js +7 -0
- package/dist/deck-client/assets/requirementDiagram-MS252O5E-CBwITx7p.js +84 -0
- package/dist/deck-client/assets/sankeyDiagram-XADWPNL6-BtE-1YTU.js +10 -0
- package/dist/deck-client/assets/sequenceDiagram-FGHM5R23-DN96yPP2.js +157 -0
- package/dist/deck-client/assets/stateDiagram-FHFEXIEX-VUkKC2uJ.js +1 -0
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CA0IjulK.js +1 -0
- package/dist/deck-client/assets/timeline-definition-GMOUNBTQ-oUeZhRns.js +120 -0
- package/dist/deck-client/assets/vennDiagram-DHZGUBPP-D87fK90n.js +34 -0
- package/dist/deck-client/assets/wardley-RL74JXVD-DYbYcpDp.js +162 -0
- package/dist/deck-client/assets/wardleyDiagram-NUSXRM2D-Ca_i0QRA.js +20 -0
- package/dist/deck-client/assets/xychartDiagram-5P7HB3ND-CUOJVIvq.js +7 -0
- package/dist/deck-client/index.html +21 -0
- package/dist/server/chart-serve.js +258 -273
- package/dist/server/cli.js +305 -713
- package/dist/server/council-entry.js +1418 -0
- package/dist/server/council-serve.js +1039 -0
- package/dist/server/deck-mcp-entry.js +1789 -0
- package/dist/server/deck-serve.js +1275 -0
- package/dist/server/deck-server/deck-mcp-entry.js +1789 -0
- package/dist/server/deck-server/deck-serve.js +1275 -0
- package/dist/server/fb-wizard.js +0 -0
- package/dist/server/graph-mcp-entry.js +268 -701
- package/dist/server/server/chart-serve.js +4643 -0
- package/dist/server/server/cli.js +13360 -0
- package/dist/server/server/fb-wizard.js +136 -0
- package/dist/server/server/graph-mcp-entry.js +6776 -0
- package/package.json +25 -18
- package/dist/chart-client/assets/index-BpQPtTuo.js +0 -441
- package/dist/chart-client/assets/index-CbZ13AXL.css +0 -1
- package/dist/client/assets/index-3ENenBk-.js +0 -291
- package/dist/client/assets/index-BCYw64M7.css +0 -32
|
@@ -90,15 +90,15 @@ function getQuery(name) {
|
|
|
90
90
|
ensureInit();
|
|
91
91
|
const cached = queryCache.get(name);
|
|
92
92
|
if (cached) return cached;
|
|
93
|
-
const scmPath = (0,
|
|
94
|
-
const scm = (0,
|
|
93
|
+
const scmPath = (0, import_node_path4.join)(queriesDir, `${name}.scm`);
|
|
94
|
+
const scm = (0, import_node_fs4.readFileSync)(scmPath, "utf-8");
|
|
95
95
|
const query = tsxLanguage.query(scm);
|
|
96
96
|
queryCache.set(name, query);
|
|
97
97
|
return query;
|
|
98
98
|
}
|
|
99
99
|
function parseSource(absPath) {
|
|
100
100
|
ensureInit();
|
|
101
|
-
const content = (0,
|
|
101
|
+
const content = (0, import_node_fs4.readFileSync)(absPath, "utf-8");
|
|
102
102
|
return parserInstance.parse(content);
|
|
103
103
|
}
|
|
104
104
|
function parseCodeTS(code) {
|
|
@@ -563,17 +563,17 @@ function extractDeep(absPath) {
|
|
|
563
563
|
}
|
|
564
564
|
return { elements, stateVars, conditions, variables, responses, params };
|
|
565
565
|
}
|
|
566
|
-
var
|
|
566
|
+
var import_node_fs4, import_node_path4, tsxLanguage, parserInstance, initPromise, initialized, queriesDir, queryCache, PRISMA_MUTATION_METHODS_BUILTIN, DB_IDENTIFIERS_FALLBACK, extraDbIdentifiers, extraMutationMethods;
|
|
567
567
|
var init_ts_extractor = __esm({
|
|
568
568
|
"src/server/graph/core/ts-extractor.ts"() {
|
|
569
569
|
"use strict";
|
|
570
|
-
|
|
571
|
-
|
|
570
|
+
import_node_fs4 = require("node:fs");
|
|
571
|
+
import_node_path4 = require("node:path");
|
|
572
572
|
initialized = false;
|
|
573
573
|
queriesDir = (() => {
|
|
574
|
-
const srcPath = (0,
|
|
574
|
+
const srcPath = (0, import_node_path4.join)((0, import_node_path4.dirname)(__filename), "..", "queries");
|
|
575
575
|
if (require("fs").existsSync(srcPath)) return srcPath;
|
|
576
|
-
return (0,
|
|
576
|
+
return (0, import_node_path4.join)((0, import_node_path4.dirname)(__filename), "graph", "queries");
|
|
577
577
|
})();
|
|
578
578
|
queryCache = /* @__PURE__ */ new Map();
|
|
579
579
|
PRISMA_MUTATION_METHODS_BUILTIN = [
|
|
@@ -601,24 +601,24 @@ __export(chart_serve_exports, {
|
|
|
601
601
|
});
|
|
602
602
|
module.exports = __toCommonJS(chart_serve_exports);
|
|
603
603
|
var import_node_http = __toESM(require("node:http"));
|
|
604
|
-
var
|
|
605
|
-
var
|
|
604
|
+
var import_node_fs18 = __toESM(require("node:fs"));
|
|
605
|
+
var import_node_path20 = __toESM(require("node:path"));
|
|
606
606
|
|
|
607
607
|
// src/server/graph/index.ts
|
|
608
|
-
var
|
|
609
|
-
var
|
|
608
|
+
var import_node_fs15 = require("node:fs");
|
|
609
|
+
var import_node_path17 = require("node:path");
|
|
610
610
|
|
|
611
611
|
// src/server/graph/core/graph-builder.ts
|
|
612
|
-
var
|
|
613
|
-
var
|
|
612
|
+
var import_node_fs12 = require("node:fs");
|
|
613
|
+
var import_node_path13 = require("node:path");
|
|
614
614
|
init_config();
|
|
615
615
|
|
|
616
616
|
// src/server/graph/core/parser-registry.ts
|
|
617
|
-
var
|
|
617
|
+
var import_node_path12 = require("node:path");
|
|
618
618
|
|
|
619
619
|
// src/server/graph/parsers/ts/typescript-project.ts
|
|
620
|
-
var
|
|
621
|
-
var
|
|
620
|
+
var import_node_fs5 = require("node:fs");
|
|
621
|
+
var import_node_path5 = require("node:path");
|
|
622
622
|
init_config();
|
|
623
623
|
|
|
624
624
|
// src/server/graph/core/resolve-paths.ts
|
|
@@ -648,6 +648,50 @@ function resolveProjectPaths(rootDir, config) {
|
|
|
648
648
|
return null;
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
+
// src/server/graph/core/walk.ts
|
|
652
|
+
var import_node_fs3 = require("node:fs");
|
|
653
|
+
var import_node_path3 = require("node:path");
|
|
654
|
+
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
655
|
+
"node_modules",
|
|
656
|
+
".git",
|
|
657
|
+
".next",
|
|
658
|
+
".launchsecure",
|
|
659
|
+
".claude",
|
|
660
|
+
"dist",
|
|
661
|
+
"build",
|
|
662
|
+
"out",
|
|
663
|
+
".turbo",
|
|
664
|
+
".vercel",
|
|
665
|
+
"coverage"
|
|
666
|
+
]);
|
|
667
|
+
function walk(dir, exts) {
|
|
668
|
+
const results = [];
|
|
669
|
+
if (!(0, import_node_fs3.existsSync)(dir)) return results;
|
|
670
|
+
for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
|
|
671
|
+
const full = (0, import_node_path3.join)(dir, entry.name);
|
|
672
|
+
if (entry.isDirectory()) {
|
|
673
|
+
results.push(...walk(full, exts));
|
|
674
|
+
} else if (exts.includes((0, import_node_path3.extname)(entry.name))) {
|
|
675
|
+
results.push(full);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return results;
|
|
679
|
+
}
|
|
680
|
+
function walkWithIgnore(dir, exts, opts = {}) {
|
|
681
|
+
const results = [];
|
|
682
|
+
if (!(0, import_node_fs3.existsSync)(dir)) return results;
|
|
683
|
+
const skip = opts.extraIgnore ? /* @__PURE__ */ new Set([...DEFAULT_IGNORE_DIRS, ...opts.extraIgnore]) : DEFAULT_IGNORE_DIRS;
|
|
684
|
+
for (const entry of (0, import_node_fs3.readdirSync)(dir, { withFileTypes: true })) {
|
|
685
|
+
if (entry.isDirectory()) {
|
|
686
|
+
if (skip.has(entry.name)) continue;
|
|
687
|
+
results.push(...walkWithIgnore((0, import_node_path3.join)(dir, entry.name), exts, opts));
|
|
688
|
+
} else if (exts.includes((0, import_node_path3.extname)(entry.name))) {
|
|
689
|
+
results.push((0, import_node_path3.join)(dir, entry.name));
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return results;
|
|
693
|
+
}
|
|
694
|
+
|
|
651
695
|
// src/server/graph/parsers/ts/typescript-project.ts
|
|
652
696
|
init_ts_extractor();
|
|
653
697
|
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]);
|
|
@@ -664,48 +708,22 @@ var CLASSIFICATION_TO_LAYER = {
|
|
|
664
708
|
"mcp-tool": "ui",
|
|
665
709
|
external: "ui"
|
|
666
710
|
};
|
|
667
|
-
function walk(dir, exts) {
|
|
668
|
-
const results = [];
|
|
669
|
-
if (!(0, import_node_fs4.existsSync)(dir)) return results;
|
|
670
|
-
for (const entry of (0, import_node_fs4.readdirSync)(dir, { withFileTypes: true })) {
|
|
671
|
-
const full = (0, import_node_path4.join)(dir, entry.name);
|
|
672
|
-
if (entry.isDirectory()) {
|
|
673
|
-
results.push(...walk(full, exts));
|
|
674
|
-
} else if (exts.includes((0, import_node_path4.extname)(entry.name))) {
|
|
675
|
-
results.push(full);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
return results;
|
|
679
|
-
}
|
|
680
|
-
function walkWithIgnore(dir, exts, ignoreDirs) {
|
|
681
|
-
const results = [];
|
|
682
|
-
if (!(0, import_node_fs4.existsSync)(dir)) return results;
|
|
683
|
-
for (const entry of (0, import_node_fs4.readdirSync)(dir, { withFileTypes: true })) {
|
|
684
|
-
if (entry.isDirectory()) {
|
|
685
|
-
if (ignoreDirs.has(entry.name)) continue;
|
|
686
|
-
results.push(...walkWithIgnore((0, import_node_path4.join)(dir, entry.name), exts, ignoreDirs));
|
|
687
|
-
} else if (exts.includes((0, import_node_path4.extname)(entry.name))) {
|
|
688
|
-
results.push((0, import_node_path4.join)(dir, entry.name));
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
return results;
|
|
692
|
-
}
|
|
693
711
|
function toNodeId(srcDir, absPath) {
|
|
694
|
-
return (0,
|
|
712
|
+
return (0, import_node_path5.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
695
713
|
}
|
|
696
714
|
function resolveImport(srcDir, specifier) {
|
|
697
715
|
if (!specifier.startsWith("@/")) return null;
|
|
698
716
|
const rel = specifier.slice(2);
|
|
699
|
-
const base = (0,
|
|
700
|
-
for (const c of [base, base + ".ts", base + ".tsx", (0,
|
|
701
|
-
if ((0,
|
|
717
|
+
const base = (0, import_node_path5.join)(srcDir, rel);
|
|
718
|
+
for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path5.join)(base, "index.ts"), (0, import_node_path5.join)(base, "index.tsx")]) {
|
|
719
|
+
if ((0, import_node_fs5.existsSync)(c) && (0, import_node_fs5.statSync)(c).isFile()) return c;
|
|
702
720
|
}
|
|
703
721
|
return null;
|
|
704
722
|
}
|
|
705
723
|
function resolveRelativeImport(fromFile, specifier) {
|
|
706
|
-
const base = (0,
|
|
707
|
-
for (const c of [base, base + ".ts", base + ".tsx", (0,
|
|
708
|
-
if ((0,
|
|
724
|
+
const base = (0, import_node_path5.join)((0, import_node_path5.dirname)(fromFile), specifier);
|
|
725
|
+
for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path5.join)(base, "index.ts"), (0, import_node_path5.join)(base, "index.tsx")]) {
|
|
726
|
+
if ((0, import_node_fs5.existsSync)(c) && (0, import_node_fs5.statSync)(c).isFile()) return c;
|
|
709
727
|
}
|
|
710
728
|
return null;
|
|
711
729
|
}
|
|
@@ -726,7 +744,7 @@ function resolveBarrelMap(barrelAbsPath, parsedByPath, memo, visiting) {
|
|
|
726
744
|
const resolved = resolveRelativeImport(barrelAbsPath, re.from);
|
|
727
745
|
if (!resolved) continue;
|
|
728
746
|
if (re.isWildcard) {
|
|
729
|
-
const targetBn = (0,
|
|
747
|
+
const targetBn = (0, import_node_path5.basename)(resolved);
|
|
730
748
|
const targetIsBarrel = targetBn === "index.ts" || targetBn === "index.tsx";
|
|
731
749
|
if (targetIsBarrel) {
|
|
732
750
|
const nested = resolveBarrelMap(resolved, parsedByPath, memo, visiting);
|
|
@@ -753,12 +771,12 @@ function buildAllBarrelMaps(srcDir, parsedByPath) {
|
|
|
753
771
|
const barrels = /* @__PURE__ */ new Map();
|
|
754
772
|
const memo = /* @__PURE__ */ new Map();
|
|
755
773
|
for (const [absPath, parsed] of parsedByPath) {
|
|
756
|
-
const bn = (0,
|
|
774
|
+
const bn = (0, import_node_path5.basename)(absPath);
|
|
757
775
|
if (bn !== "index.ts" && bn !== "index.tsx") continue;
|
|
758
776
|
if (parsed.reExports.length === 0) continue;
|
|
759
777
|
const map = resolveBarrelMap(absPath, parsedByPath, memo, /* @__PURE__ */ new Set());
|
|
760
778
|
if (map.size > 0) {
|
|
761
|
-
const barrelId = (0,
|
|
779
|
+
const barrelId = (0, import_node_path5.relative)(srcDir, (0, import_node_path5.dirname)(absPath)).replace(/\\/g, "/");
|
|
762
780
|
barrels.set(barrelId, map);
|
|
763
781
|
}
|
|
764
782
|
}
|
|
@@ -779,10 +797,10 @@ function extractRoute(id) {
|
|
|
779
797
|
return route || "/";
|
|
780
798
|
}
|
|
781
799
|
function nameFromFilename(absPath) {
|
|
782
|
-
return (0,
|
|
800
|
+
return (0, import_node_path5.basename)(absPath, (0, import_node_path5.extname)(absPath)).replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^(\w)/, (_, c) => c.toUpperCase());
|
|
783
801
|
}
|
|
784
802
|
function filePathToApiRoute(apiDir, absPath) {
|
|
785
|
-
let route = "/" + (0,
|
|
803
|
+
let route = "/" + (0, import_node_path5.relative)(apiDir, absPath).replace(/\\/g, "/").replace(/\/route\.tsx?$/, "");
|
|
786
804
|
route = route.replace(/\[([^\]]+)\]/g, ":$1");
|
|
787
805
|
route = route.replace(/\/+/g, "/");
|
|
788
806
|
if (route === "/") return "/api";
|
|
@@ -966,12 +984,9 @@ function extractEdges(srcDir, absPath, sourceId, parsed, nodeIdSet, barrelMaps,
|
|
|
966
984
|
}
|
|
967
985
|
return { edges, flagged };
|
|
968
986
|
}
|
|
969
|
-
function hasNextConfig(rootDir) {
|
|
970
|
-
return (0, import_node_fs4.existsSync)((0, import_node_path4.join)(rootDir, "next.config.ts")) || (0, import_node_fs4.existsSync)((0, import_node_path4.join)(rootDir, "next.config.js")) || (0, import_node_fs4.existsSync)((0, import_node_path4.join)(rootDir, "next.config.mjs"));
|
|
971
|
-
}
|
|
972
987
|
function detect(rootDir) {
|
|
973
988
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
974
|
-
return paths !== null
|
|
989
|
+
return paths !== null;
|
|
975
990
|
}
|
|
976
991
|
function generate(rootDir) {
|
|
977
992
|
const config = loadConfig(rootDir);
|
|
@@ -979,10 +994,10 @@ function generate(rootDir) {
|
|
|
979
994
|
const srcDir = paths.srcDir;
|
|
980
995
|
const apiDir = paths.apiDir;
|
|
981
996
|
const appFiles = walk(paths.appDir, [".tsx", ".ts"]);
|
|
982
|
-
const clientFiles = walk((0,
|
|
983
|
-
const serverFiles = walk((0,
|
|
984
|
-
const libFiles = walk((0,
|
|
985
|
-
const configFiles = walk((0,
|
|
997
|
+
const clientFiles = walk((0, import_node_path5.join)(srcDir, "client"), [".tsx", ".ts"]);
|
|
998
|
+
const serverFiles = walk((0, import_node_path5.join)(srcDir, "server"), [".ts", ".tsx"]);
|
|
999
|
+
const libFiles = walk((0, import_node_path5.join)(srcDir, "lib"), [".ts", ".tsx"]);
|
|
1000
|
+
const configFiles = walk((0, import_node_path5.join)(srcDir, "config"), [".ts", ".tsx"]);
|
|
986
1001
|
const allDiscovered = [...appFiles, ...clientFiles, ...serverFiles, ...libFiles, ...configFiles];
|
|
987
1002
|
const parsedByPath = /* @__PURE__ */ new Map();
|
|
988
1003
|
for (const absPath of allDiscovered) {
|
|
@@ -993,7 +1008,7 @@ function generate(rootDir) {
|
|
|
993
1008
|
const apiNodes = [];
|
|
994
1009
|
const nodeIdSet = /* @__PURE__ */ new Set();
|
|
995
1010
|
const routeToNodeId = /* @__PURE__ */ new Map();
|
|
996
|
-
const fileSet = allDiscovered.filter((f) => !(0,
|
|
1011
|
+
const fileSet = allDiscovered.filter((f) => !(0, import_node_path5.basename)(f).startsWith("index."));
|
|
997
1012
|
for (const absPath of fileSet) {
|
|
998
1013
|
const id = toNodeId(srcDir, absPath);
|
|
999
1014
|
const type = classifyType(absPath, id);
|
|
@@ -1010,7 +1025,7 @@ function generate(rootDir) {
|
|
|
1010
1025
|
const dbCalls = extractDbCallsTS(absPath);
|
|
1011
1026
|
const authWrappers = extractAuthWrappersTS(absPath);
|
|
1012
1027
|
const deep = extractDeep(absPath);
|
|
1013
|
-
const routePath = (0,
|
|
1028
|
+
const routePath = (0, import_node_fs5.existsSync)(apiDir) ? filePathToApiRoute(apiDir, absPath) : `/api/${id.replace(/\/route\.tsx?$/, "")}`;
|
|
1014
1029
|
const mutations = dbCalls.filter((c) => c.isMutation);
|
|
1015
1030
|
const mutates = mutations.length > 0;
|
|
1016
1031
|
const authStrategy = [...authWrappers];
|
|
@@ -1087,20 +1102,7 @@ function generate(rootDir) {
|
|
|
1087
1102
|
});
|
|
1088
1103
|
}
|
|
1089
1104
|
const externalScanned = new Set(allDiscovered.map((f) => f.replace(/\\/g, "/")));
|
|
1090
|
-
const
|
|
1091
|
-
"node_modules",
|
|
1092
|
-
".next",
|
|
1093
|
-
"dist",
|
|
1094
|
-
".launchsecure",
|
|
1095
|
-
".git",
|
|
1096
|
-
"src",
|
|
1097
|
-
"coverage",
|
|
1098
|
-
".turbo",
|
|
1099
|
-
"build",
|
|
1100
|
-
"out",
|
|
1101
|
-
".vercel"
|
|
1102
|
-
]);
|
|
1103
|
-
const externalCandidates = walkWithIgnore(rootDir, [".ts", ".tsx"], IGNORE_DIRS);
|
|
1105
|
+
const externalCandidates = walkWithIgnore(rootDir, [".ts", ".tsx"], { extraIgnore: /* @__PURE__ */ new Set(["src"]) });
|
|
1104
1106
|
for (const absPath of externalCandidates) {
|
|
1105
1107
|
const normalized = absPath.replace(/\\/g, "/");
|
|
1106
1108
|
if (externalScanned.has(normalized)) continue;
|
|
@@ -1110,7 +1112,7 @@ function generate(rootDir) {
|
|
|
1110
1112
|
} catch {
|
|
1111
1113
|
continue;
|
|
1112
1114
|
}
|
|
1113
|
-
const externalId = (0,
|
|
1115
|
+
const externalId = (0, import_node_path5.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
1114
1116
|
const edgesFromThis = [];
|
|
1115
1117
|
const seen = /* @__PURE__ */ new Set();
|
|
1116
1118
|
for (const imp of parsed.imports) {
|
|
@@ -1314,8 +1316,8 @@ var typescriptProjectParser = {
|
|
|
1314
1316
|
};
|
|
1315
1317
|
|
|
1316
1318
|
// src/server/graph/parsers/db/prisma-schema.ts
|
|
1317
|
-
var
|
|
1318
|
-
var
|
|
1319
|
+
var import_node_fs6 = require("node:fs");
|
|
1320
|
+
var import_node_path6 = require("node:path");
|
|
1319
1321
|
function parseModels(content) {
|
|
1320
1322
|
const nodes = [];
|
|
1321
1323
|
const relations = [];
|
|
@@ -1406,11 +1408,11 @@ function parseEnums(content) {
|
|
|
1406
1408
|
return nodes;
|
|
1407
1409
|
}
|
|
1408
1410
|
function detect2(rootDir) {
|
|
1409
|
-
return (0,
|
|
1411
|
+
return (0, import_node_fs6.existsSync)((0, import_node_path6.join)(rootDir, "prisma", "schema.prisma"));
|
|
1410
1412
|
}
|
|
1411
1413
|
function generate2(rootDir) {
|
|
1412
|
-
const schemaPath = (0,
|
|
1413
|
-
const content = (0,
|
|
1414
|
+
const schemaPath = (0, import_node_path6.join)(rootDir, "prisma", "schema.prisma");
|
|
1415
|
+
const content = (0, import_node_fs6.readFileSync)(schemaPath, "utf-8");
|
|
1414
1416
|
const { nodes: modelNodes, relations } = parseModels(content);
|
|
1415
1417
|
const enumNodes = parseEnums(content);
|
|
1416
1418
|
const allNodes = [...modelNodes, ...enumNodes];
|
|
@@ -1467,8 +1469,8 @@ var prismaSchemaParser = {
|
|
|
1467
1469
|
};
|
|
1468
1470
|
|
|
1469
1471
|
// src/server/graph/parsers/db/sql-migrations.ts
|
|
1470
|
-
var
|
|
1471
|
-
var
|
|
1472
|
+
var import_node_fs7 = require("node:fs");
|
|
1473
|
+
var import_node_path7 = require("node:path");
|
|
1472
1474
|
var PG_TO_PRISMA = {
|
|
1473
1475
|
"TEXT": "String",
|
|
1474
1476
|
"VARCHAR": "String",
|
|
@@ -1618,19 +1620,19 @@ function parseUniqueIndex(sql, state) {
|
|
|
1618
1620
|
}
|
|
1619
1621
|
}
|
|
1620
1622
|
function parseMigrations(rootDir) {
|
|
1621
|
-
const migrationsDir = (0,
|
|
1623
|
+
const migrationsDir = (0, import_node_path7.join)(rootDir, "prisma", "migrations");
|
|
1622
1624
|
const state = {
|
|
1623
1625
|
tables: /* @__PURE__ */ new Map(),
|
|
1624
1626
|
enums: /* @__PURE__ */ new Map(),
|
|
1625
1627
|
fks: [],
|
|
1626
1628
|
uniqueIndexes: /* @__PURE__ */ new Map()
|
|
1627
1629
|
};
|
|
1628
|
-
if (!(0,
|
|
1629
|
-
const dirs = (0,
|
|
1630
|
+
if (!(0, import_node_fs7.existsSync)(migrationsDir)) return state;
|
|
1631
|
+
const dirs = (0, import_node_fs7.readdirSync)(migrationsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
|
|
1630
1632
|
for (const dir of dirs) {
|
|
1631
|
-
const sqlPath = (0,
|
|
1632
|
-
if (!(0,
|
|
1633
|
-
const sql = (0,
|
|
1633
|
+
const sqlPath = (0, import_node_path7.join)(migrationsDir, dir, "migration.sql");
|
|
1634
|
+
if (!(0, import_node_fs7.existsSync)(sqlPath)) continue;
|
|
1635
|
+
const sql = (0, import_node_fs7.readFileSync)(sqlPath, "utf-8");
|
|
1634
1636
|
parseCreateEnum(sql, state);
|
|
1635
1637
|
parseCreateTable(sql, state);
|
|
1636
1638
|
parseAlterTable(sql, state);
|
|
@@ -1641,9 +1643,9 @@ function parseMigrations(rootDir) {
|
|
|
1641
1643
|
return state;
|
|
1642
1644
|
}
|
|
1643
1645
|
function loadPrismaState(rootDir) {
|
|
1644
|
-
const schemaPath = (0,
|
|
1645
|
-
if (!(0,
|
|
1646
|
-
const content = (0,
|
|
1646
|
+
const schemaPath = (0, import_node_path7.join)(rootDir, "prisma", "schema.prisma");
|
|
1647
|
+
if (!(0, import_node_fs7.existsSync)(schemaPath)) return null;
|
|
1648
|
+
const content = (0, import_node_fs7.readFileSync)(schemaPath, "utf-8");
|
|
1647
1649
|
const tables = /* @__PURE__ */ new Map();
|
|
1648
1650
|
const enums = /* @__PURE__ */ new Map();
|
|
1649
1651
|
const relations = [];
|
|
@@ -1808,9 +1810,9 @@ function verify(sqlState, prisma) {
|
|
|
1808
1810
|
return { contradictions, flaggedEdges };
|
|
1809
1811
|
}
|
|
1810
1812
|
function detect3(rootDir) {
|
|
1811
|
-
const migrationsDir = (0,
|
|
1812
|
-
if (!(0,
|
|
1813
|
-
return (0,
|
|
1813
|
+
const migrationsDir = (0, import_node_path7.join)(rootDir, "prisma", "migrations");
|
|
1814
|
+
if (!(0, import_node_fs7.existsSync)(migrationsDir)) return false;
|
|
1815
|
+
return (0, import_node_fs7.readdirSync)(migrationsDir, { withFileTypes: true }).some((d) => d.isDirectory() && (0, import_node_fs7.existsSync)((0, import_node_path7.join)(migrationsDir, d.name, "migration.sql")));
|
|
1814
1816
|
}
|
|
1815
1817
|
function generate3(rootDir) {
|
|
1816
1818
|
const sqlState = parseMigrations(rootDir);
|
|
@@ -2098,32 +2100,32 @@ var fetchResolverParser = {
|
|
|
2098
2100
|
};
|
|
2099
2101
|
|
|
2100
2102
|
// src/server/graph/parsers/crosslayer/api-annotations.ts
|
|
2101
|
-
var
|
|
2102
|
-
var
|
|
2103
|
+
var import_node_fs8 = require("node:fs");
|
|
2104
|
+
var import_node_path8 = require("node:path");
|
|
2103
2105
|
var API_ANNOTATION_RE = /@api\s+(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+(\/\S+)/g;
|
|
2104
2106
|
function walk2(dir, exts) {
|
|
2105
|
-
if (!(0,
|
|
2107
|
+
if (!(0, import_node_fs8.existsSync)(dir)) return [];
|
|
2106
2108
|
const results = [];
|
|
2107
|
-
for (const entry of (0,
|
|
2109
|
+
for (const entry of (0, import_node_fs8.readdirSync)(dir, { withFileTypes: true })) {
|
|
2108
2110
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
2109
|
-
const full = (0,
|
|
2111
|
+
const full = (0, import_node_path8.join)(dir, entry.name);
|
|
2110
2112
|
if (entry.isDirectory()) {
|
|
2111
2113
|
results.push(...walk2(full, exts));
|
|
2112
|
-
} else if (exts.includes((0,
|
|
2114
|
+
} else if (exts.includes((0, import_node_path8.extname)(entry.name))) {
|
|
2113
2115
|
results.push(full);
|
|
2114
2116
|
}
|
|
2115
2117
|
}
|
|
2116
2118
|
return results;
|
|
2117
2119
|
}
|
|
2118
2120
|
function toNodeId2(srcDir, absPath) {
|
|
2119
|
-
return (0,
|
|
2121
|
+
return (0, import_node_path8.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
2120
2122
|
}
|
|
2121
2123
|
var apiAnnotationsParser = {
|
|
2122
2124
|
id: "api-annotations",
|
|
2123
2125
|
layer: "crosslayer",
|
|
2124
2126
|
concern: "api-binding",
|
|
2125
2127
|
detect(rootDir) {
|
|
2126
|
-
return (0,
|
|
2128
|
+
return (0, import_node_fs8.existsSync)((0, import_node_path8.join)(rootDir, "src"));
|
|
2127
2129
|
},
|
|
2128
2130
|
generate(rootDir, layerOutputs) {
|
|
2129
2131
|
const apiOutput = layerOutputs.get("api");
|
|
@@ -2134,13 +2136,13 @@ var apiAnnotationsParser = {
|
|
|
2134
2136
|
const uiNodeIds = new Set(uiOutput?.nodes.map((n) => n.id) ?? []);
|
|
2135
2137
|
const apiRoutes = loadApiRoutesFromOutput(apiOutput);
|
|
2136
2138
|
const apiPathMap = buildApiPathMap(apiRoutes);
|
|
2137
|
-
const srcDir = (0,
|
|
2139
|
+
const srcDir = (0, import_node_path8.join)(rootDir, "src");
|
|
2138
2140
|
const files = walk2(srcDir, [".ts", ".tsx"]);
|
|
2139
2141
|
const crossRefs = [];
|
|
2140
2142
|
const flaggedEdges = [];
|
|
2141
2143
|
const seen = /* @__PURE__ */ new Set();
|
|
2142
2144
|
for (const absPath of files) {
|
|
2143
|
-
const content = (0,
|
|
2145
|
+
const content = (0, import_node_fs8.readFileSync)(absPath, "utf-8");
|
|
2144
2146
|
const sourceId = toNodeId2(srcDir, absPath);
|
|
2145
2147
|
if (!uiNodeIds.has(sourceId)) continue;
|
|
2146
2148
|
let match;
|
|
@@ -2184,26 +2186,26 @@ var apiAnnotationsParser = {
|
|
|
2184
2186
|
};
|
|
2185
2187
|
|
|
2186
2188
|
// src/server/graph/parsers/crosslayer/url-literal-scanner.ts
|
|
2187
|
-
var
|
|
2188
|
-
var
|
|
2189
|
+
var import_node_fs9 = require("node:fs");
|
|
2190
|
+
var import_node_path9 = require("node:path");
|
|
2189
2191
|
init_config();
|
|
2190
2192
|
var URL_LITERAL_RE = /['"`](\/api\/[^'"`\s]+?)['"`]/g;
|
|
2191
2193
|
function walk3(dir, exts) {
|
|
2192
|
-
if (!(0,
|
|
2194
|
+
if (!(0, import_node_fs9.existsSync)(dir)) return [];
|
|
2193
2195
|
const results = [];
|
|
2194
|
-
for (const entry of (0,
|
|
2196
|
+
for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true })) {
|
|
2195
2197
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
2196
|
-
const full = (0,
|
|
2198
|
+
const full = (0, import_node_path9.join)(dir, entry.name);
|
|
2197
2199
|
if (entry.isDirectory()) {
|
|
2198
2200
|
results.push(...walk3(full, exts));
|
|
2199
|
-
} else if (exts.includes((0,
|
|
2201
|
+
} else if (exts.includes((0, import_node_path9.extname)(entry.name))) {
|
|
2200
2202
|
results.push(full);
|
|
2201
2203
|
}
|
|
2202
2204
|
}
|
|
2203
2205
|
return results;
|
|
2204
2206
|
}
|
|
2205
2207
|
function toNodeId3(srcDir, absPath) {
|
|
2206
|
-
return (0,
|
|
2208
|
+
return (0, import_node_path9.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
2207
2209
|
}
|
|
2208
2210
|
var urlLiteralScannerParser = {
|
|
2209
2211
|
id: "url-literal-scanner",
|
|
@@ -2224,7 +2226,7 @@ var urlLiteralScannerParser = {
|
|
|
2224
2226
|
const apiPathMap = buildApiPathMap(apiRoutes);
|
|
2225
2227
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
2226
2228
|
const srcDir = paths.srcDir;
|
|
2227
|
-
const clientDir = (0,
|
|
2229
|
+
const clientDir = (0, import_node_path9.join)(srcDir, "client");
|
|
2228
2230
|
const files = [
|
|
2229
2231
|
...walk3(clientDir, [".ts", ".tsx"]),
|
|
2230
2232
|
...walk3(paths.appDir, [".ts", ".tsx"])
|
|
@@ -2234,7 +2236,7 @@ var urlLiteralScannerParser = {
|
|
|
2234
2236
|
for (const absPath of files) {
|
|
2235
2237
|
const sourceId = toNodeId3(srcDir, absPath);
|
|
2236
2238
|
if (!uiNodeIds.has(sourceId)) continue;
|
|
2237
|
-
const content = (0,
|
|
2239
|
+
const content = (0, import_node_fs9.readFileSync)(absPath, "utf-8");
|
|
2238
2240
|
let match;
|
|
2239
2241
|
URL_LITERAL_RE.lastIndex = 0;
|
|
2240
2242
|
while ((match = URL_LITERAL_RE.exec(content)) !== null) {
|
|
@@ -2265,8 +2267,8 @@ var urlLiteralScannerParser = {
|
|
|
2265
2267
|
};
|
|
2266
2268
|
|
|
2267
2269
|
// src/server/graph/parsers/static/static-values.ts
|
|
2268
|
-
var
|
|
2269
|
-
var
|
|
2270
|
+
var import_node_fs10 = require("node:fs");
|
|
2271
|
+
var import_node_path10 = require("node:path");
|
|
2270
2272
|
var parseCode = null;
|
|
2271
2273
|
function tryLoadTreeSitter() {
|
|
2272
2274
|
if (parseCode) return true;
|
|
@@ -2299,19 +2301,19 @@ function extractEnumValues(rootDir) {
|
|
|
2299
2301
|
const nodes = [];
|
|
2300
2302
|
const edges = [];
|
|
2301
2303
|
const schemaPaths = [
|
|
2302
|
-
(0,
|
|
2303
|
-
(0,
|
|
2304
|
+
(0, import_node_path10.join)(rootDir, "prisma", "schema.prisma"),
|
|
2305
|
+
(0, import_node_path10.join)(rootDir, "prisma", "schema")
|
|
2304
2306
|
];
|
|
2305
2307
|
let content = "";
|
|
2306
2308
|
for (const p of schemaPaths) {
|
|
2307
|
-
if ((0,
|
|
2309
|
+
if ((0, import_node_fs10.existsSync)(p)) {
|
|
2308
2310
|
try {
|
|
2309
|
-
const stat = (0,
|
|
2311
|
+
const stat = (0, import_node_fs10.statSync)(p);
|
|
2310
2312
|
if (stat.isFile()) {
|
|
2311
|
-
content = (0,
|
|
2313
|
+
content = (0, import_node_fs10.readFileSync)(p, "utf-8");
|
|
2312
2314
|
} else if (stat.isDirectory()) {
|
|
2313
|
-
const files = (0,
|
|
2314
|
-
content = files.map((f) => (0,
|
|
2315
|
+
const files = (0, import_node_fs10.readdirSync)(p).filter((f) => f.endsWith(".prisma"));
|
|
2316
|
+
content = files.map((f) => (0, import_node_fs10.readFileSync)((0, import_node_path10.join)(p, f), "utf-8")).join("\n");
|
|
2315
2317
|
}
|
|
2316
2318
|
} catch {
|
|
2317
2319
|
continue;
|
|
@@ -2385,7 +2387,7 @@ function extractStringArrayFromNode(node) {
|
|
|
2385
2387
|
return values;
|
|
2386
2388
|
}
|
|
2387
2389
|
function findArrayDecl(root, varName) {
|
|
2388
|
-
function
|
|
2390
|
+
function walk4(node) {
|
|
2389
2391
|
if (node.type === "variable_declarator") {
|
|
2390
2392
|
const nameNode = node.childForFieldName("name");
|
|
2391
2393
|
const valueNode = node.childForFieldName("value");
|
|
@@ -2398,12 +2400,12 @@ function findArrayDecl(root, varName) {
|
|
|
2398
2400
|
}
|
|
2399
2401
|
}
|
|
2400
2402
|
for (const child of node.namedChildren) {
|
|
2401
|
-
const found =
|
|
2403
|
+
const found = walk4(child);
|
|
2402
2404
|
if (found) return found;
|
|
2403
2405
|
}
|
|
2404
2406
|
return null;
|
|
2405
2407
|
}
|
|
2406
|
-
return
|
|
2408
|
+
return walk4(root);
|
|
2407
2409
|
}
|
|
2408
2410
|
function extractObjectPropsRegex(objStr) {
|
|
2409
2411
|
const props = {};
|
|
@@ -2467,14 +2469,14 @@ function extractSeedData(rootDir) {
|
|
|
2467
2469
|
const nodes = [];
|
|
2468
2470
|
const edges = [];
|
|
2469
2471
|
const seedFiles = [
|
|
2470
|
-
(0,
|
|
2471
|
-
(0,
|
|
2472
|
-
(0,
|
|
2473
|
-
].filter(
|
|
2472
|
+
(0, import_node_path10.join)(rootDir, "prisma", "seed.ts"),
|
|
2473
|
+
(0, import_node_path10.join)(rootDir, "prisma", "seed.js"),
|
|
2474
|
+
(0, import_node_path10.join)(rootDir, "src", "server", "lib", "system-tags.ts")
|
|
2475
|
+
].filter(import_node_fs10.existsSync);
|
|
2474
2476
|
const useTreeSitter = tryLoadTreeSitter();
|
|
2475
2477
|
for (const filePath of seedFiles) {
|
|
2476
|
-
const content = (0,
|
|
2477
|
-
const relPath = (0,
|
|
2478
|
+
const content = (0, import_node_fs10.readFileSync)(filePath, "utf-8");
|
|
2479
|
+
const relPath = (0, import_node_path10.relative)(rootDir, filePath);
|
|
2478
2480
|
const seeded = detectSeededArrays(content, relPath);
|
|
2479
2481
|
let astRoot = null;
|
|
2480
2482
|
if (useTreeSitter && parseCode) {
|
|
@@ -2568,11 +2570,11 @@ function extractSeedData(rootDir) {
|
|
|
2568
2570
|
return { nodes, edges };
|
|
2569
2571
|
}
|
|
2570
2572
|
function walkDir(dir, exts) {
|
|
2571
|
-
if (!(0,
|
|
2573
|
+
if (!(0, import_node_fs10.existsSync)(dir)) return [];
|
|
2572
2574
|
const results = [];
|
|
2573
|
-
for (const entry of (0,
|
|
2575
|
+
for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true })) {
|
|
2574
2576
|
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
|
|
2575
|
-
const full = (0,
|
|
2577
|
+
const full = (0, import_node_path10.join)(dir, entry.name);
|
|
2576
2578
|
if (entry.isDirectory()) results.push(...walkDir(full, exts));
|
|
2577
2579
|
else if (exts.some((ext) => entry.name.endsWith(ext))) results.push(full);
|
|
2578
2580
|
}
|
|
@@ -2580,11 +2582,11 @@ function walkDir(dir, exts) {
|
|
|
2580
2582
|
}
|
|
2581
2583
|
function extractConstants(rootDir) {
|
|
2582
2584
|
const nodes = [];
|
|
2583
|
-
const srcDir = (0,
|
|
2584
|
-
if (!(0,
|
|
2585
|
+
const srcDir = (0, import_node_path10.join)(rootDir, "src");
|
|
2586
|
+
if (!(0, import_node_fs10.existsSync)(srcDir)) return { nodes };
|
|
2585
2587
|
for (const filePath of walkDir(srcDir, [".ts", ".tsx"])) {
|
|
2586
|
-
const content = (0,
|
|
2587
|
-
const relPath = (0,
|
|
2588
|
+
const content = (0, import_node_fs10.readFileSync)(filePath, "utf-8");
|
|
2589
|
+
const relPath = (0, import_node_path10.relative)(rootDir, filePath);
|
|
2588
2590
|
const constArrayRe = /export\s+const\s+([A-Z][A-Z_0-9]+)\s*(?::[^=]+)?\s*=\s*\[/g;
|
|
2589
2591
|
let cm;
|
|
2590
2592
|
while ((cm = constArrayRe.exec(content)) !== null) {
|
|
@@ -2617,7 +2619,7 @@ function extractConstants(rootDir) {
|
|
|
2617
2619
|
return { nodes };
|
|
2618
2620
|
}
|
|
2619
2621
|
function detect4(rootDir) {
|
|
2620
|
-
return (0,
|
|
2622
|
+
return (0, import_node_fs10.existsSync)((0, import_node_path10.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs10.existsSync)((0, import_node_path10.join)(rootDir, "prisma", "seed.ts"));
|
|
2621
2623
|
}
|
|
2622
2624
|
function generate4(rootDir) {
|
|
2623
2625
|
const enumResult = extractEnumValues(rootDir);
|
|
@@ -2692,26 +2694,9 @@ var staticValuesParser = {
|
|
|
2692
2694
|
};
|
|
2693
2695
|
|
|
2694
2696
|
// src/server/graph/parsers/crosslayer/static-ref-scanner.ts
|
|
2695
|
-
var
|
|
2696
|
-
var
|
|
2697
|
+
var import_node_fs11 = require("node:fs");
|
|
2698
|
+
var import_node_path11 = require("node:path");
|
|
2697
2699
|
init_config();
|
|
2698
|
-
function walk4(dir, exts) {
|
|
2699
|
-
if (!(0, import_node_fs10.existsSync)(dir)) return [];
|
|
2700
|
-
const results = [];
|
|
2701
|
-
function recurse(d) {
|
|
2702
|
-
for (const entry of (0, import_node_fs10.readdirSync)(d, { withFileTypes: true })) {
|
|
2703
|
-
const full = (0, import_node_path10.join)(d, entry.name);
|
|
2704
|
-
if (entry.isDirectory()) {
|
|
2705
|
-
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
|
|
2706
|
-
recurse(full);
|
|
2707
|
-
} else if (exts.some((ext) => entry.name.endsWith(ext))) {
|
|
2708
|
-
results.push(full);
|
|
2709
|
-
}
|
|
2710
|
-
}
|
|
2711
|
-
}
|
|
2712
|
-
recurse(dir);
|
|
2713
|
-
return results;
|
|
2714
|
-
}
|
|
2715
2700
|
var MIN_VALUE_LENGTH = 4;
|
|
2716
2701
|
var SKIP_VALUES = /* @__PURE__ */ new Set([
|
|
2717
2702
|
"true",
|
|
@@ -2854,11 +2839,11 @@ var staticRefScannerParser = {
|
|
|
2854
2839
|
if (!paths) return { cross_refs: [], flagged_edges: [], warnings: [] };
|
|
2855
2840
|
const srcDir = paths.srcDir;
|
|
2856
2841
|
const files = [
|
|
2857
|
-
...
|
|
2858
|
-
...
|
|
2859
|
-
...
|
|
2860
|
-
...
|
|
2861
|
-
...
|
|
2842
|
+
...walkWithIgnore((0, import_node_path11.join)(srcDir, "client"), [".ts", ".tsx"]),
|
|
2843
|
+
...walkWithIgnore(paths.appDir, [".ts", ".tsx"]),
|
|
2844
|
+
...walkWithIgnore((0, import_node_path11.join)(srcDir, "server"), [".ts", ".tsx"]),
|
|
2845
|
+
...walkWithIgnore((0, import_node_path11.join)(srcDir, "lib"), [".ts", ".tsx"]),
|
|
2846
|
+
...walkWithIgnore((0, import_node_path11.join)(srcDir, "config"), [".ts", ".tsx"])
|
|
2862
2847
|
];
|
|
2863
2848
|
const uiOutput = layerOutputs.get("ui");
|
|
2864
2849
|
const apiOutput = layerOutputs.get("api");
|
|
@@ -2876,10 +2861,10 @@ var staticRefScannerParser = {
|
|
|
2876
2861
|
const seen = /* @__PURE__ */ new Set();
|
|
2877
2862
|
let filesScanned = 0;
|
|
2878
2863
|
for (const absPath of files) {
|
|
2879
|
-
const sourceId = (0,
|
|
2864
|
+
const sourceId = (0, import_node_path11.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
2880
2865
|
const sourceLayer = uiNodeIds.has(sourceId) ? "ui" : apiNodeIds.has(sourceId) ? "api" : null;
|
|
2881
2866
|
if (!sourceLayer) continue;
|
|
2882
|
-
const content = (0,
|
|
2867
|
+
const content = (0, import_node_fs11.readFileSync)(absPath, "utf-8");
|
|
2883
2868
|
filesScanned++;
|
|
2884
2869
|
let fileRefs;
|
|
2885
2870
|
if (parseCode2) {
|
|
@@ -2995,7 +2980,7 @@ function registerBuiltins(registry, disabled) {
|
|
|
2995
2980
|
function loadCustomParsers(registry, config, rootDir, disabled) {
|
|
2996
2981
|
for (const entry of config.parsers?.custom ?? []) {
|
|
2997
2982
|
try {
|
|
2998
|
-
const absPath = (0,
|
|
2983
|
+
const absPath = (0, import_node_path12.resolve)(rootDir, entry.path);
|
|
2999
2984
|
const mod = require(absPath);
|
|
3000
2985
|
const parser = "default" in mod ? mod.default : mod;
|
|
3001
2986
|
if (disabled.has(parser.id)) continue;
|
|
@@ -3125,10 +3110,10 @@ function applyCrossLayerResults(uiOutput, results) {
|
|
|
3125
3110
|
|
|
3126
3111
|
// src/server/graph/core/graph-builder.ts
|
|
3127
3112
|
function readGraphFromDisk(rootDir, layer) {
|
|
3128
|
-
const filePath = (0,
|
|
3129
|
-
if (!(0,
|
|
3113
|
+
const filePath = (0, import_node_path13.join)(rootDir, ".launchsecure", "graphs", `${layer}.json`);
|
|
3114
|
+
if (!(0, import_node_fs12.existsSync)(filePath)) return null;
|
|
3130
3115
|
try {
|
|
3131
|
-
return JSON.parse((0,
|
|
3116
|
+
return JSON.parse((0, import_node_fs12.readFileSync)(filePath, "utf-8"));
|
|
3132
3117
|
} catch {
|
|
3133
3118
|
return null;
|
|
3134
3119
|
}
|
|
@@ -3229,11 +3214,11 @@ function generateAll(rootDir) {
|
|
|
3229
3214
|
init_config();
|
|
3230
3215
|
|
|
3231
3216
|
// src/server/graph/core/tagger-registry.ts
|
|
3232
|
-
var
|
|
3217
|
+
var import_node_path15 = require("node:path");
|
|
3233
3218
|
|
|
3234
3219
|
// src/server/graph/taggers/module-tagger.ts
|
|
3235
|
-
var
|
|
3236
|
-
var
|
|
3220
|
+
var import_node_fs13 = require("node:fs");
|
|
3221
|
+
var import_node_path14 = require("node:path");
|
|
3237
3222
|
function matchGlob(pattern, id) {
|
|
3238
3223
|
const patParts = pattern.split("/");
|
|
3239
3224
|
const idParts = id.split("/");
|
|
@@ -3266,18 +3251,18 @@ function detectConventionDirs(rootDir, extraConventionDirs = []) {
|
|
|
3266
3251
|
const conventionDirs = [...CONVENTION_DIRS_BUILTIN, ...extraConventionDirs];
|
|
3267
3252
|
const searchDirs = [
|
|
3268
3253
|
rootDir,
|
|
3269
|
-
(0,
|
|
3270
|
-
(0,
|
|
3271
|
-
(0,
|
|
3254
|
+
(0, import_node_path14.join)(rootDir, "src"),
|
|
3255
|
+
(0, import_node_path14.join)(rootDir, "app"),
|
|
3256
|
+
(0, import_node_path14.join)(rootDir, "lib")
|
|
3272
3257
|
];
|
|
3273
3258
|
for (const base of searchDirs) {
|
|
3274
3259
|
for (const convention of conventionDirs) {
|
|
3275
|
-
const dir = (0,
|
|
3276
|
-
if (!(0,
|
|
3260
|
+
const dir = (0, import_node_path14.join)(base, convention);
|
|
3261
|
+
if (!(0, import_node_fs13.existsSync)(dir)) continue;
|
|
3277
3262
|
try {
|
|
3278
|
-
const stat = (0,
|
|
3263
|
+
const stat = (0, import_node_fs13.statSync)(dir);
|
|
3279
3264
|
if (!stat.isDirectory()) continue;
|
|
3280
|
-
const entries = (0,
|
|
3265
|
+
const entries = (0, import_node_fs13.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
3281
3266
|
if (entries.length > 0) {
|
|
3282
3267
|
const relPath = dir.replace(rootDir + "/", "").replace(rootDir + "\\", "");
|
|
3283
3268
|
result.set(relPath, entries);
|
|
@@ -3571,7 +3556,7 @@ function loadCustomTaggers(registry, config, rootDir, disabled) {
|
|
|
3571
3556
|
for (const entry of config.taggers?.custom ?? []) {
|
|
3572
3557
|
if (disabled.has(entry.id)) continue;
|
|
3573
3558
|
try {
|
|
3574
|
-
const absPath = (0,
|
|
3559
|
+
const absPath = (0, import_node_path15.resolve)(rootDir, entry.path);
|
|
3575
3560
|
const mod = require(absPath);
|
|
3576
3561
|
const tagger = "default" in mod ? mod.default : mod;
|
|
3577
3562
|
const override = config.taggers?.trackUntagged?.[tagger.id];
|
|
@@ -3594,24 +3579,24 @@ function createTaggerRegistry(config, rootDir) {
|
|
|
3594
3579
|
}
|
|
3595
3580
|
|
|
3596
3581
|
// src/server/graph/core/tag-store.ts
|
|
3597
|
-
var
|
|
3598
|
-
var
|
|
3582
|
+
var import_node_fs14 = require("node:fs");
|
|
3583
|
+
var import_node_path16 = require("node:path");
|
|
3599
3584
|
var TAGS_FILENAME = "tags.json";
|
|
3600
3585
|
var GRAPHS_DIR = ".launchsecure/graphs";
|
|
3601
3586
|
var tagCache = /* @__PURE__ */ new Map();
|
|
3602
3587
|
function tagsFilePath(rootDir) {
|
|
3603
|
-
return (0,
|
|
3588
|
+
return (0, import_node_path16.join)(rootDir, GRAPHS_DIR, TAGS_FILENAME);
|
|
3604
3589
|
}
|
|
3605
3590
|
function readTagStore(rootDir) {
|
|
3606
3591
|
const filePath = tagsFilePath(rootDir);
|
|
3607
|
-
if (!(0,
|
|
3608
|
-
const stat = (0,
|
|
3592
|
+
if (!(0, import_node_fs14.existsSync)(filePath)) return {};
|
|
3593
|
+
const stat = (0, import_node_fs14.statSync)(filePath);
|
|
3609
3594
|
const cached = tagCache.get(filePath);
|
|
3610
3595
|
if (cached && cached.mtimeMs === stat.mtimeMs) {
|
|
3611
3596
|
return cached.store;
|
|
3612
3597
|
}
|
|
3613
3598
|
try {
|
|
3614
|
-
const content = (0,
|
|
3599
|
+
const content = (0, import_node_fs14.readFileSync)(filePath, "utf-8");
|
|
3615
3600
|
const store = JSON.parse(content);
|
|
3616
3601
|
tagCache.set(filePath, { mtimeMs: stat.mtimeMs, store });
|
|
3617
3602
|
return store;
|
|
@@ -3621,15 +3606,15 @@ function readTagStore(rootDir) {
|
|
|
3621
3606
|
}
|
|
3622
3607
|
function writeTagStore(rootDir, store) {
|
|
3623
3608
|
const filePath = tagsFilePath(rootDir);
|
|
3624
|
-
const dir = (0,
|
|
3625
|
-
(0,
|
|
3609
|
+
const dir = (0, import_node_path16.dirname)(filePath);
|
|
3610
|
+
(0, import_node_fs14.mkdirSync)(dir, { recursive: true });
|
|
3626
3611
|
const cleaned = {};
|
|
3627
3612
|
for (const [nodeId, tags] of Object.entries(store)) {
|
|
3628
3613
|
if (Object.keys(tags).length > 0) {
|
|
3629
3614
|
cleaned[nodeId] = tags;
|
|
3630
3615
|
}
|
|
3631
3616
|
}
|
|
3632
|
-
(0,
|
|
3617
|
+
(0, import_node_fs14.writeFileSync)(filePath, JSON.stringify(cleaned, null, 2) + "\n", "utf-8");
|
|
3633
3618
|
tagCache.delete(filePath);
|
|
3634
3619
|
}
|
|
3635
3620
|
function setTag(rootDir, nodeId, key, value) {
|
|
@@ -3652,24 +3637,24 @@ function removeTag(rootDir, nodeId, key) {
|
|
|
3652
3637
|
init_ts_extractor();
|
|
3653
3638
|
var GRAPHS_DIR2 = ".launchsecure/graphs";
|
|
3654
3639
|
function getAvailableLayers(rootDir) {
|
|
3655
|
-
const dir = (0,
|
|
3656
|
-
if (!(0,
|
|
3657
|
-
return (0,
|
|
3640
|
+
const dir = (0, import_node_path17.join)(rootDir, GRAPHS_DIR2);
|
|
3641
|
+
if (!(0, import_node_fs15.existsSync)(dir)) return [];
|
|
3642
|
+
return (0, import_node_fs15.readdirSync)(dir).filter((f) => f.endsWith(".json") && f !== "tags.json").map((f) => f.replace(".json", ""));
|
|
3658
3643
|
}
|
|
3659
3644
|
var graphCache = /* @__PURE__ */ new Map();
|
|
3660
3645
|
var taggedCache = /* @__PURE__ */ new Map();
|
|
3661
3646
|
function graphsDir(rootDir) {
|
|
3662
|
-
return (0,
|
|
3647
|
+
return (0, import_node_path17.join)(rootDir, GRAPHS_DIR2);
|
|
3663
3648
|
}
|
|
3664
3649
|
function graphFilePath(rootDir, layer) {
|
|
3665
|
-
return (0,
|
|
3650
|
+
return (0, import_node_path17.join)(graphsDir(rootDir), `${layer}.json`);
|
|
3666
3651
|
}
|
|
3667
3652
|
function tagsFilePath2(rootDir) {
|
|
3668
|
-
return (0,
|
|
3653
|
+
return (0, import_node_path17.join)(graphsDir(rootDir), "tags.json");
|
|
3669
3654
|
}
|
|
3670
3655
|
function getMtimeMs(filePath) {
|
|
3671
|
-
if (!(0,
|
|
3672
|
-
return (0,
|
|
3656
|
+
if (!(0, import_node_fs15.existsSync)(filePath)) return 0;
|
|
3657
|
+
return (0, import_node_fs15.statSync)(filePath).mtimeMs;
|
|
3673
3658
|
}
|
|
3674
3659
|
function invalidateCache(filePath) {
|
|
3675
3660
|
graphCache.delete(filePath);
|
|
@@ -3708,20 +3693,20 @@ function applyTags(graph, layer, rootDir) {
|
|
|
3708
3693
|
}
|
|
3709
3694
|
function readGraphRaw(rootDir, layer) {
|
|
3710
3695
|
const filePath = graphFilePath(rootDir, layer);
|
|
3711
|
-
if (!(0,
|
|
3712
|
-
const stat = (0,
|
|
3696
|
+
if (!(0, import_node_fs15.existsSync)(filePath)) return null;
|
|
3697
|
+
const stat = (0, import_node_fs15.statSync)(filePath);
|
|
3713
3698
|
const cached = graphCache.get(filePath);
|
|
3714
3699
|
if (cached && cached.mtimeMs === stat.mtimeMs) {
|
|
3715
3700
|
return cached.graph;
|
|
3716
3701
|
}
|
|
3717
|
-
const content = (0,
|
|
3702
|
+
const content = (0, import_node_fs15.readFileSync)(filePath, "utf-8");
|
|
3718
3703
|
const graph = JSON.parse(content);
|
|
3719
3704
|
graphCache.set(filePath, { mtimeMs: stat.mtimeMs, graph });
|
|
3720
3705
|
return graph;
|
|
3721
3706
|
}
|
|
3722
3707
|
function readGraph(rootDir, layer) {
|
|
3723
3708
|
const rawFilePath = graphFilePath(rootDir, layer);
|
|
3724
|
-
if (!(0,
|
|
3709
|
+
if (!(0, import_node_fs15.existsSync)(rawFilePath)) return null;
|
|
3725
3710
|
const rawMtime = getMtimeMs(rawFilePath);
|
|
3726
3711
|
const tagsMtime = getMtimeMs(tagsFilePath2(rootDir));
|
|
3727
3712
|
const cacheKey = `${rootDir}:${layer}`;
|
|
@@ -3751,11 +3736,11 @@ async function generateGraph(rootDir, layer) {
|
|
|
3751
3736
|
mutationMethods: config.parsers?.patterns?.mutationMethods
|
|
3752
3737
|
});
|
|
3753
3738
|
const dir = graphsDir(rootDir);
|
|
3754
|
-
(0,
|
|
3739
|
+
(0, import_node_fs15.mkdirSync)(dir, { recursive: true });
|
|
3755
3740
|
const results = layer ? [generateLayer(rootDir, layer)].filter((r) => r !== null) : generateAll(rootDir);
|
|
3756
3741
|
for (const result of results) {
|
|
3757
3742
|
const filePath = graphFilePath(rootDir, result.layer);
|
|
3758
|
-
(0,
|
|
3743
|
+
(0, import_node_fs15.writeFileSync)(filePath, JSON.stringify(result.output, null, 2) + "\n", "utf-8");
|
|
3759
3744
|
invalidateCache(filePath);
|
|
3760
3745
|
invalidateTaggedCache(rootDir, result.layer);
|
|
3761
3746
|
}
|
|
@@ -3764,28 +3749,28 @@ async function generateGraph(rootDir, layer) {
|
|
|
3764
3749
|
|
|
3765
3750
|
// src/server/lockfile.ts
|
|
3766
3751
|
var import_node_child_process = require("node:child_process");
|
|
3767
|
-
var
|
|
3752
|
+
var import_node_fs16 = require("node:fs");
|
|
3768
3753
|
var import_node_os = require("node:os");
|
|
3769
|
-
var
|
|
3754
|
+
var import_node_path18 = require("node:path");
|
|
3770
3755
|
function lockDir(projectRoot) {
|
|
3771
3756
|
if (projectRoot) {
|
|
3772
|
-
return (0,
|
|
3757
|
+
return (0, import_node_path18.join)(projectRoot, ".launchsecure");
|
|
3773
3758
|
}
|
|
3774
|
-
return (0,
|
|
3759
|
+
return (0, import_node_path18.join)((0, import_node_os.homedir)(), ".launchsecure");
|
|
3775
3760
|
}
|
|
3776
3761
|
function lockPath(projectRoot) {
|
|
3777
|
-
return (0,
|
|
3762
|
+
return (0, import_node_path18.join)(lockDir(projectRoot), "launch-chart.lock");
|
|
3778
3763
|
}
|
|
3779
3764
|
var _activeProjectRoot;
|
|
3780
3765
|
function readLock(projectRoot) {
|
|
3781
3766
|
const root = projectRoot ?? _activeProjectRoot;
|
|
3782
3767
|
const p = lockPath(root);
|
|
3783
|
-
if (!(0,
|
|
3768
|
+
if (!(0, import_node_fs16.existsSync)(p)) {
|
|
3784
3769
|
if (root) {
|
|
3785
3770
|
const globalP = lockPath();
|
|
3786
|
-
if ((0,
|
|
3771
|
+
if ((0, import_node_fs16.existsSync)(globalP)) {
|
|
3787
3772
|
try {
|
|
3788
|
-
const data = JSON.parse((0,
|
|
3773
|
+
const data = JSON.parse((0, import_node_fs16.readFileSync)(globalP, "utf-8"));
|
|
3789
3774
|
if (typeof data.pid === "number" && typeof data.port === "number" && data.cwd === root) {
|
|
3790
3775
|
return data;
|
|
3791
3776
|
}
|
|
@@ -3796,7 +3781,7 @@ function readLock(projectRoot) {
|
|
|
3796
3781
|
return null;
|
|
3797
3782
|
}
|
|
3798
3783
|
try {
|
|
3799
|
-
const data = JSON.parse((0,
|
|
3784
|
+
const data = JSON.parse((0, import_node_fs16.readFileSync)(p, "utf-8"));
|
|
3800
3785
|
if (typeof data.pid !== "number" || typeof data.port !== "number") return null;
|
|
3801
3786
|
return data;
|
|
3802
3787
|
} catch {
|
|
@@ -3833,7 +3818,7 @@ function getLiveLock(projectRoot) {
|
|
|
3833
3818
|
const live = listenerPid !== null ? listenerPid === lock.pid : isPidAlive(lock.pid);
|
|
3834
3819
|
if (!live) {
|
|
3835
3820
|
try {
|
|
3836
|
-
(0,
|
|
3821
|
+
(0, import_node_fs16.unlinkSync)(lockPath(root));
|
|
3837
3822
|
} catch {
|
|
3838
3823
|
}
|
|
3839
3824
|
return null;
|
|
@@ -3842,14 +3827,14 @@ function getLiveLock(projectRoot) {
|
|
|
3842
3827
|
}
|
|
3843
3828
|
function writeLock(data, projectRoot) {
|
|
3844
3829
|
const root = projectRoot ?? _activeProjectRoot;
|
|
3845
|
-
(0,
|
|
3846
|
-
(0,
|
|
3830
|
+
(0, import_node_fs16.mkdirSync)(lockDir(root), { recursive: true });
|
|
3831
|
+
(0, import_node_fs16.writeFileSync)(lockPath(root), JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
3847
3832
|
if (root) _activeProjectRoot = root;
|
|
3848
3833
|
}
|
|
3849
3834
|
function clearLock(projectRoot) {
|
|
3850
3835
|
const root = projectRoot ?? _activeProjectRoot;
|
|
3851
3836
|
try {
|
|
3852
|
-
(0,
|
|
3837
|
+
(0, import_node_fs16.unlinkSync)(lockPath(root));
|
|
3853
3838
|
} catch {
|
|
3854
3839
|
}
|
|
3855
3840
|
}
|
|
@@ -3858,13 +3843,13 @@ function clearLock(projectRoot) {
|
|
|
3858
3843
|
init_config();
|
|
3859
3844
|
|
|
3860
3845
|
// src/server/graph/core/audit-core.ts
|
|
3861
|
-
var
|
|
3862
|
-
var
|
|
3846
|
+
var import_node_fs17 = require("node:fs");
|
|
3847
|
+
var import_node_path19 = require("node:path");
|
|
3863
3848
|
function readGraphFile(rootDir, layer) {
|
|
3864
|
-
const filePath = (0,
|
|
3865
|
-
if (!(0,
|
|
3849
|
+
const filePath = (0, import_node_path19.join)(rootDir, ".launchsecure", "graphs", `${layer}.json`);
|
|
3850
|
+
if (!(0, import_node_fs17.existsSync)(filePath)) return null;
|
|
3866
3851
|
try {
|
|
3867
|
-
return JSON.parse((0,
|
|
3852
|
+
return JSON.parse((0, import_node_fs17.readFileSync)(filePath, "utf-8"));
|
|
3868
3853
|
} catch {
|
|
3869
3854
|
return null;
|
|
3870
3855
|
}
|
|
@@ -3908,10 +3893,10 @@ function checkUnprotectedRoutes(rootDir) {
|
|
|
3908
3893
|
const api = readGraphFile(rootDir, "api");
|
|
3909
3894
|
const staticGraph = readGraphFile(rootDir, "static");
|
|
3910
3895
|
if (!api) return buildReport("api", "unprotected_routes", findings);
|
|
3911
|
-
const routePermsPath = (0,
|
|
3896
|
+
const routePermsPath = (0, import_node_path19.join)(rootDir, "src", "config", "route-permissions.ts");
|
|
3912
3897
|
let routePermsContent = "";
|
|
3913
|
-
if ((0,
|
|
3914
|
-
routePermsContent = (0,
|
|
3898
|
+
if ((0, import_node_fs17.existsSync)(routePermsPath)) {
|
|
3899
|
+
routePermsContent = (0, import_node_fs17.readFileSync)(routePermsPath, "utf-8");
|
|
3915
3900
|
}
|
|
3916
3901
|
const registeredRoutes = /* @__PURE__ */ new Set();
|
|
3917
3902
|
const routeEntryRe = /path:\s*'([^']+)'/g;
|
|
@@ -3988,10 +3973,10 @@ function checkUnenforcedPermissions(rootDir) {
|
|
|
3988
3973
|
const staticGraph = readGraphFile(rootDir, "static");
|
|
3989
3974
|
if (!staticGraph) return buildReport("static", "unenforced_permissions", findings);
|
|
3990
3975
|
const permissions = staticGraph.nodes.filter((n) => n.type === "seed_permission").map((n) => ({ id: n.id, key: n.value, name: n.name }));
|
|
3991
|
-
const routePermsPath = (0,
|
|
3976
|
+
const routePermsPath = (0, import_node_path19.join)(rootDir, "src", "config", "route-permissions.ts");
|
|
3992
3977
|
let routePermsContent = "";
|
|
3993
|
-
if ((0,
|
|
3994
|
-
routePermsContent = (0,
|
|
3978
|
+
if ((0, import_node_fs17.existsSync)(routePermsPath)) {
|
|
3979
|
+
routePermsContent = (0, import_node_fs17.readFileSync)(routePermsPath, "utf-8");
|
|
3995
3980
|
}
|
|
3996
3981
|
for (const perm of permissions) {
|
|
3997
3982
|
const regex = new RegExp(`permission:\\s*['"]${perm.key}['"]`);
|
|
@@ -4021,9 +4006,9 @@ function checkHardcodedValues(rootDir) {
|
|
|
4021
4006
|
const seen = /* @__PURE__ */ new Set();
|
|
4022
4007
|
for (const node of api.nodes) {
|
|
4023
4008
|
if (node.type !== "endpoint") continue;
|
|
4024
|
-
const filePath = (0,
|
|
4025
|
-
if (!(0,
|
|
4026
|
-
const content = (0,
|
|
4009
|
+
const filePath = (0, import_node_path19.join)(rootDir, "src", node.id);
|
|
4010
|
+
if (!(0, import_node_fs17.existsSync)(filePath)) continue;
|
|
4011
|
+
const content = (0, import_node_fs17.readFileSync)(filePath, "utf-8");
|
|
4027
4012
|
let m;
|
|
4028
4013
|
allCapsRe.lastIndex = 0;
|
|
4029
4014
|
while ((m = allCapsRe.exec(content)) !== null) {
|
|
@@ -4153,16 +4138,16 @@ var MIME_TYPES = {
|
|
|
4153
4138
|
function findProjectRoot(startDir) {
|
|
4154
4139
|
let dir = startDir;
|
|
4155
4140
|
for (let i = 0; i < 8; i++) {
|
|
4156
|
-
const graphsDir2 =
|
|
4157
|
-
if (
|
|
4158
|
-
const parent =
|
|
4141
|
+
const graphsDir2 = import_node_path20.default.join(dir, ".launchsecure", "graphs");
|
|
4142
|
+
if (import_node_fs18.default.existsSync(import_node_path20.default.join(graphsDir2, "ui.json")) || import_node_fs18.default.existsSync(import_node_path20.default.join(graphsDir2, "api.json")) || import_node_fs18.default.existsSync(import_node_path20.default.join(graphsDir2, "db.json"))) return dir;
|
|
4143
|
+
const parent = import_node_path20.default.dirname(dir);
|
|
4159
4144
|
if (parent === dir) break;
|
|
4160
4145
|
dir = parent;
|
|
4161
4146
|
}
|
|
4162
4147
|
dir = startDir;
|
|
4163
4148
|
for (let i = 0; i < 8; i++) {
|
|
4164
|
-
if (
|
|
4165
|
-
const parent =
|
|
4149
|
+
if (import_node_fs18.default.existsSync(import_node_path20.default.join(dir, ".git"))) return dir;
|
|
4150
|
+
const parent = import_node_path20.default.dirname(dir);
|
|
4166
4151
|
if (parent === dir) break;
|
|
4167
4152
|
dir = parent;
|
|
4168
4153
|
}
|
|
@@ -4171,7 +4156,7 @@ function findProjectRoot(startDir) {
|
|
|
4171
4156
|
function resolveRequestRoot(url, monorepoRoot, projects) {
|
|
4172
4157
|
const projectParam = url.searchParams.get("project");
|
|
4173
4158
|
if (!projectParam || projects.length === 0) return monorepoRoot;
|
|
4174
|
-
const resolved =
|
|
4159
|
+
const resolved = import_node_path20.default.resolve(monorepoRoot, projectParam);
|
|
4175
4160
|
if (!resolved.startsWith(monorepoRoot)) {
|
|
4176
4161
|
throw new Error("Project path outside monorepo root");
|
|
4177
4162
|
}
|
|
@@ -4222,16 +4207,16 @@ async function buildMergedGraph(root) {
|
|
|
4222
4207
|
};
|
|
4223
4208
|
}
|
|
4224
4209
|
function serveStatic(res, filePath) {
|
|
4225
|
-
if (!
|
|
4226
|
-
const ext =
|
|
4210
|
+
if (!import_node_fs18.default.existsSync(filePath) || !import_node_fs18.default.statSync(filePath).isFile()) return false;
|
|
4211
|
+
const ext = import_node_path20.default.extname(filePath).toLowerCase();
|
|
4227
4212
|
const mime = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
4228
4213
|
res.writeHead(200, { "Content-Type": mime, "Cache-Control": "no-cache" });
|
|
4229
|
-
|
|
4214
|
+
import_node_fs18.default.createReadStream(filePath).pipe(res);
|
|
4230
4215
|
return true;
|
|
4231
4216
|
}
|
|
4232
4217
|
function serveIndex(res, clientDir) {
|
|
4233
|
-
const indexPath =
|
|
4234
|
-
if (!
|
|
4218
|
+
const indexPath = import_node_path20.default.join(clientDir, "index.html");
|
|
4219
|
+
if (!import_node_fs18.default.existsSync(indexPath)) {
|
|
4235
4220
|
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
4236
4221
|
res.end(`LaunchChart client bundle not found at ${clientDir}. Run 'npm run build:chart-client'.`);
|
|
4237
4222
|
return;
|
|
@@ -4283,7 +4268,7 @@ async function startChartServer(opts = {}) {
|
|
|
4283
4268
|
}
|
|
4284
4269
|
return { port: existing.port, url: existing.url };
|
|
4285
4270
|
}
|
|
4286
|
-
const clientDir = opts.clientDir ??
|
|
4271
|
+
const clientDir = opts.clientDir ?? import_node_path20.default.join(__dirname, "..", "chart-client");
|
|
4287
4272
|
const rootConfig = loadConfig(projectRoot);
|
|
4288
4273
|
const projects = rootConfig.projects ?? [];
|
|
4289
4274
|
const server = import_node_http.default.createServer((req, res) => {
|
|
@@ -4299,11 +4284,11 @@ async function startChartServer(opts = {}) {
|
|
|
4299
4284
|
}
|
|
4300
4285
|
if (req.method === "GET" && url2.pathname === "/api/projects") {
|
|
4301
4286
|
const projectList = projects.length > 0 ? projects.map((p) => {
|
|
4302
|
-
const absRoot =
|
|
4303
|
-
const hasGraphs =
|
|
4304
|
-
const
|
|
4305
|
-
return { name: p.name, root: p.root, hasGraphs, hasNextConfig
|
|
4306
|
-
}) : [{ name:
|
|
4287
|
+
const absRoot = import_node_path20.default.resolve(projectRoot, p.root);
|
|
4288
|
+
const hasGraphs = import_node_fs18.default.existsSync(import_node_path20.default.join(absRoot, ".launchsecure", "graphs"));
|
|
4289
|
+
const hasNextConfig = import_node_fs18.default.existsSync(import_node_path20.default.join(absRoot, "next.config.ts")) || import_node_fs18.default.existsSync(import_node_path20.default.join(absRoot, "next.config.js")) || import_node_fs18.default.existsSync(import_node_path20.default.join(absRoot, "next.config.mjs"));
|
|
4290
|
+
return { name: p.name, root: p.root, hasGraphs, hasNextConfig };
|
|
4291
|
+
}) : [{ name: import_node_path20.default.basename(projectRoot), root: ".", hasGraphs: import_node_fs18.default.existsSync(import_node_path20.default.join(projectRoot, ".launchsecure", "graphs")), hasNextConfig: true }];
|
|
4307
4292
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4308
4293
|
res.end(JSON.stringify({ projects: projectList, monorepoRoot: projectRoot }));
|
|
4309
4294
|
return;
|
|
@@ -4349,20 +4334,20 @@ async function startChartServer(opts = {}) {
|
|
|
4349
4334
|
}
|
|
4350
4335
|
if (req.method === "GET" && url2.pathname === "/api/file-content") {
|
|
4351
4336
|
const relPath = url2.searchParams.get("path");
|
|
4352
|
-
if (!relPath || relPath.includes("..") ||
|
|
4337
|
+
if (!relPath || relPath.includes("..") || import_node_path20.default.isAbsolute(relPath)) {
|
|
4353
4338
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
4354
4339
|
res.end(JSON.stringify({ error: "Invalid path" }));
|
|
4355
4340
|
return;
|
|
4356
4341
|
}
|
|
4357
|
-
const filePath =
|
|
4358
|
-
if (!filePath.startsWith(reqRoot) || !
|
|
4342
|
+
const filePath = import_node_path20.default.join(reqRoot, relPath);
|
|
4343
|
+
if (!filePath.startsWith(reqRoot) || !import_node_fs18.default.existsSync(filePath) || !import_node_fs18.default.statSync(filePath).isFile()) {
|
|
4359
4344
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
4360
4345
|
res.end(JSON.stringify({ error: "File not found" }));
|
|
4361
4346
|
return;
|
|
4362
4347
|
}
|
|
4363
|
-
const ext =
|
|
4348
|
+
const ext = import_node_path20.default.extname(filePath).toLowerCase();
|
|
4364
4349
|
const langMap = { ".ts": "typescript", ".tsx": "tsx", ".js": "javascript", ".jsx": "jsx", ".prisma": "prisma", ".json": "json", ".css": "css" };
|
|
4365
|
-
const content =
|
|
4350
|
+
const content = import_node_fs18.default.readFileSync(filePath, "utf-8");
|
|
4366
4351
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4367
4352
|
res.end(JSON.stringify({ content, language: langMap[ext] ?? "text", path: relPath }));
|
|
4368
4353
|
return;
|
|
@@ -4404,8 +4389,8 @@ async function startChartServer(opts = {}) {
|
|
|
4404
4389
|
req.on("end", () => {
|
|
4405
4390
|
try {
|
|
4406
4391
|
const newConfig = JSON.parse(body);
|
|
4407
|
-
const configPath =
|
|
4408
|
-
|
|
4392
|
+
const configPath = import_node_path20.default.join(reqRoot, ".launchchart.json");
|
|
4393
|
+
import_node_fs18.default.writeFileSync(configPath, JSON.stringify(newConfig, null, 2) + "\n", "utf-8");
|
|
4409
4394
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4410
4395
|
res.end(JSON.stringify({ ok: true }));
|
|
4411
4396
|
} catch (err) {
|
|
@@ -4438,8 +4423,8 @@ async function startChartServer(opts = {}) {
|
|
|
4438
4423
|
const taggerConfig = JSON.parse(body);
|
|
4439
4424
|
const config2 = loadConfig(reqRoot);
|
|
4440
4425
|
config2.taggers = taggerConfig;
|
|
4441
|
-
const configPath =
|
|
4442
|
-
|
|
4426
|
+
const configPath = import_node_path20.default.join(reqRoot, ".launchchart.json");
|
|
4427
|
+
import_node_fs18.default.writeFileSync(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
4443
4428
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4444
4429
|
res.end(JSON.stringify({ ok: true }));
|
|
4445
4430
|
} catch (err) {
|
|
@@ -4512,10 +4497,10 @@ async function startChartServer(opts = {}) {
|
|
|
4512
4497
|
res.end(JSON.stringify({
|
|
4513
4498
|
projectRoot: reqRoot,
|
|
4514
4499
|
detected: paths ? {
|
|
4515
|
-
srcDir:
|
|
4516
|
-
appDir:
|
|
4517
|
-
apiDir:
|
|
4518
|
-
dbDir: paths.dbDir ?
|
|
4500
|
+
srcDir: import_node_path20.default.relative(reqRoot, paths.srcDir) || ".",
|
|
4501
|
+
appDir: import_node_path20.default.relative(reqRoot, paths.appDir),
|
|
4502
|
+
apiDir: import_node_path20.default.relative(reqRoot, paths.apiDir),
|
|
4503
|
+
dbDir: paths.dbDir ? import_node_path20.default.relative(reqRoot, paths.dbDir) : null
|
|
4519
4504
|
} : null,
|
|
4520
4505
|
overrides,
|
|
4521
4506
|
isOverride: overrides.appDir
|
|
@@ -4524,19 +4509,19 @@ async function startChartServer(opts = {}) {
|
|
|
4524
4509
|
}
|
|
4525
4510
|
if (req.method === "GET" && url2.pathname === "/api/browse-dir") {
|
|
4526
4511
|
const browsePath = url2.searchParams.get("path") || projectRoot;
|
|
4527
|
-
const abs =
|
|
4528
|
-
const twoUp =
|
|
4512
|
+
const abs = import_node_path20.default.resolve(browsePath);
|
|
4513
|
+
const twoUp = import_node_path20.default.resolve(projectRoot, "..", "..");
|
|
4529
4514
|
if (!abs.startsWith(twoUp)) {
|
|
4530
4515
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
4531
4516
|
res.end(JSON.stringify({ ok: false, error: "Path outside allowed range" }));
|
|
4532
4517
|
return;
|
|
4533
4518
|
}
|
|
4534
4519
|
try {
|
|
4535
|
-
const entries =
|
|
4520
|
+
const entries = import_node_fs18.default.readdirSync(abs, { withFileTypes: true });
|
|
4536
4521
|
const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules" && e.name !== "dist" && e.name !== ".next").map((e) => e.name).sort();
|
|
4537
|
-
const parent = abs !== twoUp ?
|
|
4522
|
+
const parent = abs !== twoUp ? import_node_path20.default.dirname(abs) : null;
|
|
4538
4523
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4539
|
-
res.end(JSON.stringify({ current: abs, parent, dirs, relative:
|
|
4524
|
+
res.end(JSON.stringify({ current: abs, parent, dirs, relative: import_node_path20.default.relative(projectRoot, abs) || "." }));
|
|
4540
4525
|
} catch (err) {
|
|
4541
4526
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
4542
4527
|
res.end(JSON.stringify({ ok: false, error: String(err) }));
|
|
@@ -4562,8 +4547,8 @@ async function startChartServer(opts = {}) {
|
|
|
4562
4547
|
const { projects: newProjects } = JSON.parse(body);
|
|
4563
4548
|
const config2 = loadConfig(projectRoot);
|
|
4564
4549
|
config2.projects = newProjects.length > 0 ? newProjects : void 0;
|
|
4565
|
-
const configPath =
|
|
4566
|
-
|
|
4550
|
+
const configPath = import_node_path20.default.join(projectRoot, ".launchchart.json");
|
|
4551
|
+
import_node_fs18.default.writeFileSync(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
4567
4552
|
projects.length = 0;
|
|
4568
4553
|
if (config2.projects) projects.push(...config2.projects);
|
|
4569
4554
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -4576,7 +4561,7 @@ async function startChartServer(opts = {}) {
|
|
|
4576
4561
|
return;
|
|
4577
4562
|
}
|
|
4578
4563
|
if (url2.pathname !== "/") {
|
|
4579
|
-
const staticPath =
|
|
4564
|
+
const staticPath = import_node_path20.default.join(clientDir, url2.pathname);
|
|
4580
4565
|
if (serveStatic(res, staticPath)) return;
|
|
4581
4566
|
}
|
|
4582
4567
|
serveIndex(res, clientDir);
|