@launchsecure/launch-kit 0.0.39 → 0.0.40
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-CWJFFDPu.css +1 -0
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/index-CTzFcfGV.css +32 -0
- package/dist/client/index.html +2 -2
- package/dist/council-client/assets/index-ArgRc5mN.css +1 -0
- package/dist/council-client/index.html +2 -2
- package/dist/deck-client/assets/{_baseUniq-DOrnEQMI.js → _baseUniq-BZP7n41F.js} +1 -1
- package/dist/deck-client/assets/{arc-DOWK7V3m.js → arc-31biU3Az.js} +1 -1
- package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-DPhzvk7q.js → architectureDiagram-Q4EWVU46-DHg6Ss--.js} +1 -1
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-CwAGy9lU.js → blockDiagram-DXYQGD6D-CUdblaWk.js} +1 -1
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-L_g_SS21.js → c4Diagram-AHTNJAMY-MfAO5lak.js} +1 -1
- package/dist/deck-client/assets/channel-BBkRLdnC.js +1 -0
- package/dist/deck-client/assets/{chunk-4BX2VUAB-RKm0LXpu.js → chunk-4BX2VUAB-DQ1MrGgN.js} +1 -1
- package/dist/deck-client/assets/{chunk-4TB4RGXK-Bk0FUbxU.js → chunk-4TB4RGXK-BUJtZ7jO.js} +1 -1
- package/dist/deck-client/assets/{chunk-55IACEB6-Cl3hja-M.js → chunk-55IACEB6-BdSnXB6g.js} +1 -1
- package/dist/deck-client/assets/{chunk-EDXVE4YY-CNIMQCV2.js → chunk-EDXVE4YY-94yZIUI8.js} +1 -1
- package/dist/deck-client/assets/{chunk-FMBD7UC4-DqOvWr1k.js → chunk-FMBD7UC4-PnZ9v6ey.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-1Kd7yK5u.js → chunk-OYMX7WX6-DXrWNOsV.js} +1 -1
- package/dist/deck-client/assets/{chunk-QZHKN3VN-6_kraYpP.js → chunk-QZHKN3VN-CsIGIDKX.js} +1 -1
- package/dist/deck-client/assets/{chunk-YZCP3GAM-FgAwIWlo.js → chunk-YZCP3GAM-DVkBO9tn.js} +1 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-DFCaeF-7.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-DFCaeF-7.js +1 -0
- package/dist/deck-client/assets/clone-GCEVRScB.js +1 -0
- package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-CigVnnPr.js → cose-bilkent-S5V4N54A-m126Oh3b.js} +1 -1
- package/dist/deck-client/assets/{dagre-KV5264BT-DHZXTktX.js → dagre-KV5264BT-C2aig8U5.js} +1 -1
- package/dist/deck-client/assets/{diagram-5BDNPKRD-H5k0eauU.js → diagram-5BDNPKRD-CKpoRfGn.js} +1 -1
- package/dist/deck-client/assets/{diagram-G4DWMVQ6-Bg3dFhSY.js → diagram-G4DWMVQ6-Cjh115Ep.js} +1 -1
- package/dist/deck-client/assets/{diagram-MMDJMWI5-CQLC410N.js → diagram-MMDJMWI5-DKlBv_2L.js} +1 -1
- package/dist/deck-client/assets/{diagram-TYMM5635-DFTCHVkP.js → diagram-TYMM5635-CdBh4cEn.js} +1 -1
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-aiv9GZnL.js → erDiagram-SMLLAGMA-56pn_93p.js} +1 -1
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-C6Fhvtsy.js → flowDiagram-DWJPFMVM-BtV3M5xJ.js} +1 -1
- package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DSaGMPM4.js → ganttDiagram-T4ZO3ILL-DTIsC6Zg.js} +1 -1
- package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-DMjL2Vix.js → gitGraphDiagram-UUTBAWPF-CJYeyCLe.js} +1 -1
- package/dist/deck-client/assets/{graph-B7Vn5lkK.js → graph-BDvMu1Ss.js} +1 -1
- package/dist/deck-client/assets/index-D4eSxcBn.css +1 -0
- package/dist/deck-client/assets/{index-BD36e-tD.js → index-QnGVE9PZ.js} +72 -72
- package/dist/deck-client/assets/{infoDiagram-42DDH7IO-mNi4iygG.js → infoDiagram-42DDH7IO-BWyKJnpW.js} +1 -1
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-BwCUmUVt.js → ishikawaDiagram-UXIWVN3A-DXYkdO3T.js} +1 -1
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-C6qoqJmJ.js → journeyDiagram-VCZTEJTY-C2zBr-J5.js} +1 -1
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-Dz1Tt3sA.js → kanban-definition-6JOO6SKY-CdoYLS4Z.js} +1 -1
- package/dist/deck-client/assets/{layout-CZTyRhOG.js → layout-vOnxnCQU.js} +1 -1
- package/dist/deck-client/assets/{linear--7n7iEvd.js → linear-B0J0WCGz.js} +1 -1
- package/dist/deck-client/assets/{min-Bh130DN8.js → min-B0AXlT9L.js} +1 -1
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-CfXcK1qH.js → mindmap-definition-QFDTVHPH-oAybLedr.js} +1 -1
- package/dist/deck-client/assets/{pieDiagram-DEJITSTG-DjVHLAVw.js → pieDiagram-DEJITSTG-BjHyHxGk.js} +1 -1
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-CXwvZ1i1.js → quadrantDiagram-34T5L4WZ-dtluDZXs.js} +1 -1
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-Cl6xm0fR.js → requirementDiagram-MS252O5E-Cq8l7bOl.js} +1 -1
- package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-BOH9sLyh.js → sankeyDiagram-XADWPNL6-C1Vih91z.js} +1 -1
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-BC1MYBn6.js → sequenceDiagram-FGHM5R23-CYkd7oQK.js} +1 -1
- package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-kNp9bv8K.js → stateDiagram-FHFEXIEX-CtyG8wBK.js} +1 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BLyKWfcN.js +1 -0
- package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-DKnITsD4.js → timeline-definition-GMOUNBTQ-DZIxSyd1.js} +1 -1
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-BdajXRrh.js → vennDiagram-DHZGUBPP-Ct4JVRDM.js} +1 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-V29ycxOW.js +162 -0
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-B2hDCDl2.js → wardleyDiagram-NUSXRM2D-D-Ua6Cmi.js} +1 -1
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-CvnYFs51.js → xychartDiagram-5P7HB3ND-BPCOuRVl.js} +1 -1
- package/dist/deck-client/index.html +2 -2
- package/dist/server/beacon-monitor-entry.js +106 -24
- package/dist/server/chart-serve.js +544 -247
- package/dist/server/cli.js +743 -324
- package/dist/server/council-entry.js +16 -3
- package/dist/server/council-serve.js +15 -2
- package/dist/server/deck-mcp-entry.js +267 -107
- package/dist/server/deck-serve.js +98 -22
- package/dist/server/graph-mcp-entry.js +866 -357
- package/dist/server/orbit-entry.js +91 -7
- package/dist/server/recall-entry.js +94 -12
- package/dist/server/rover-entry.js +1 -1
- package/package.json +1 -1
- package/scaffolds/statusline/statusline-mcp.sh +68 -19
- package/scaffolds/statusline/statusline-wrapper.sh +12 -9
- package/dist/chart-client/assets/index-ysGpLeOW.css +0 -1
- package/dist/client/assets/index-CMN3tlGP.css +0 -32
- package/dist/council-client/assets/index-ChmNX6bZ.css +0 -1
- package/dist/deck-client/assets/channel-DqiACUUq.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-D23cq2C3.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-D23cq2C3.js +0 -1
- package/dist/deck-client/assets/clone-C7jSigGq.js +0 -1
- package/dist/deck-client/assets/index-CGbNOpk9.css +0 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-hRsAFc2t.js +0 -1
- package/dist/deck-client/assets/wardley-RL74JXVD-BL802-su.js +0 -162
- /package/dist/chart-client/assets/{index-BlsuXuQ1.js → index-Dzlj-oCj.js} +0 -0
- /package/dist/client/assets/{index-BA7BHBWT.js → index-tTg_ezUF.js} +0 -0
- /package/dist/council-client/assets/{index-jjBWyhry.js → index-B1v46vTE.js} +0 -0
|
@@ -131,8 +131,8 @@ function getQuery(name) {
|
|
|
131
131
|
ensureInit();
|
|
132
132
|
const cached = queryCache.get(name);
|
|
133
133
|
if (cached) return cached;
|
|
134
|
-
const scmPath = (0,
|
|
135
|
-
const scm = (0,
|
|
134
|
+
const scmPath = (0, import_node_path16.join)(queriesDir, `${name}.scm`);
|
|
135
|
+
const scm = (0, import_node_fs12.readFileSync)(scmPath, "utf-8");
|
|
136
136
|
const query = tsxLanguage.query(scm);
|
|
137
137
|
queryCache.set(name, query);
|
|
138
138
|
return query;
|
|
@@ -152,13 +152,13 @@ function parseSource(absPath) {
|
|
|
152
152
|
ensureInit();
|
|
153
153
|
let content;
|
|
154
154
|
try {
|
|
155
|
-
const stat = (0,
|
|
155
|
+
const stat = (0, import_node_fs12.statSync)(absPath);
|
|
156
156
|
if (stat.size > MAX_PARSEABLE_BYTES) {
|
|
157
157
|
process.stderr.write(`[lc-extractor] skipping ${absPath}: ${stat.size} bytes exceeds max ${MAX_PARSEABLE_BYTES}
|
|
158
158
|
`);
|
|
159
159
|
return null;
|
|
160
160
|
}
|
|
161
|
-
content = (0,
|
|
161
|
+
content = (0, import_node_fs12.readFileSync)(absPath, "utf-8");
|
|
162
162
|
} catch (e) {
|
|
163
163
|
process.stderr.write(`[lc-extractor] read failed for ${absPath}: ${e instanceof Error ? e.message : String(e)}
|
|
164
164
|
`);
|
|
@@ -1192,18 +1192,18 @@ function collectUiLabels(root) {
|
|
|
1192
1192
|
visit(root);
|
|
1193
1193
|
return out;
|
|
1194
1194
|
}
|
|
1195
|
-
var
|
|
1195
|
+
var import_node_fs12, import_node_path16, tsxLanguage, parserInstance, TreeSitterCtor, initPromise, initialized, queriesDir, queryCache, MAX_PARSEABLE_BYTES, MAX_CONSECUTIVE_PARSE_FAILURES, consecutiveParseFailures, ParseCascadeError, PRISMA_MUTATION_METHODS_BUILTIN, SUPABASE_MUTATION_METHODS_BUILTIN, DB_IDENTIFIERS_FALLBACK, extraDbIdentifiers, extraMutationMethods, INLINE_AUTH_IMPORTS, EXEMPT_NAME_PATTERNS, PROTECT_NAME_PATTERNS, TRUST_AS_PROTECT_KEYS, TIMER_FNS, DOM_METHOD_NAMES, CLASSLIST_METHODS, STORAGE_OBJECTS, HISTORY_METHODS, LOCATION_METHODS, ASSIGN_DOM_PROPS, UI_LABEL_KEYS, UI_LABELS_MAX, NOTE_REGEX, NOTES_MAX;
|
|
1196
1196
|
var init_ts_extractor = __esm({
|
|
1197
1197
|
"src/server/graph/core/ts-extractor.ts"() {
|
|
1198
1198
|
"use strict";
|
|
1199
|
-
|
|
1200
|
-
|
|
1199
|
+
import_node_fs12 = require("node:fs");
|
|
1200
|
+
import_node_path16 = require("node:path");
|
|
1201
1201
|
init_parse_failure_cache();
|
|
1202
1202
|
initialized = false;
|
|
1203
1203
|
queriesDir = (() => {
|
|
1204
|
-
const srcPath = (0,
|
|
1204
|
+
const srcPath = (0, import_node_path16.join)((0, import_node_path16.dirname)(__filename), "..", "queries");
|
|
1205
1205
|
if (require("fs").existsSync(srcPath)) return srcPath;
|
|
1206
|
-
return (0,
|
|
1206
|
+
return (0, import_node_path16.join)((0, import_node_path16.dirname)(__filename), "graph", "queries");
|
|
1207
1207
|
})();
|
|
1208
1208
|
queryCache = /* @__PURE__ */ new Map();
|
|
1209
1209
|
MAX_PARSEABLE_BYTES = 2 * 1024 * 1024;
|
|
@@ -1343,13 +1343,13 @@ __export(chart_serve_exports, {
|
|
|
1343
1343
|
});
|
|
1344
1344
|
module.exports = __toCommonJS(chart_serve_exports);
|
|
1345
1345
|
var import_node_http = __toESM(require("node:http"));
|
|
1346
|
-
var
|
|
1347
|
-
var
|
|
1346
|
+
var import_node_fs22 = __toESM(require("node:fs"));
|
|
1347
|
+
var import_node_path27 = __toESM(require("node:path"));
|
|
1348
1348
|
init_launch_kit_paths();
|
|
1349
1349
|
|
|
1350
1350
|
// src/server/graph/index.ts
|
|
1351
|
-
var
|
|
1352
|
-
var
|
|
1351
|
+
var import_node_fs8 = require("node:fs");
|
|
1352
|
+
var import_node_path12 = require("node:path");
|
|
1353
1353
|
init_config();
|
|
1354
1354
|
|
|
1355
1355
|
// src/server/graph/core/tagger-registry.ts
|
|
@@ -1813,7 +1813,7 @@ function resolveWorkerPath() {
|
|
|
1813
1813
|
);
|
|
1814
1814
|
}
|
|
1815
1815
|
function runParseInWorker(req) {
|
|
1816
|
-
return new Promise((
|
|
1816
|
+
return new Promise((resolve5, reject) => {
|
|
1817
1817
|
let workerPath;
|
|
1818
1818
|
try {
|
|
1819
1819
|
workerPath = resolveWorkerPath();
|
|
@@ -1832,7 +1832,7 @@ function runParseInWorker(req) {
|
|
|
1832
1832
|
};
|
|
1833
1833
|
worker.on("message", (reply) => {
|
|
1834
1834
|
if (reply.ok) {
|
|
1835
|
-
finish(() =>
|
|
1835
|
+
finish(() => resolve5({ results: reply.results, failedFiles: reply.failedFiles }));
|
|
1836
1836
|
} else {
|
|
1837
1837
|
const err = new Error(reply.error.message);
|
|
1838
1838
|
err.name = reply.error.name;
|
|
@@ -1910,9 +1910,297 @@ function writeEffectsIndex(rootDir, idx) {
|
|
|
1910
1910
|
return path2;
|
|
1911
1911
|
}
|
|
1912
1912
|
|
|
1913
|
-
// src/server/graph/core/
|
|
1913
|
+
// src/server/graph/core/context-map.ts
|
|
1914
|
+
var import_node_path10 = require("node:path");
|
|
1915
|
+
init_launch_kit_paths();
|
|
1916
|
+
init_config();
|
|
1917
|
+
|
|
1918
|
+
// src/server/graph/core/context/registry.ts
|
|
1919
|
+
var import_node_path9 = require("node:path");
|
|
1920
|
+
|
|
1921
|
+
// src/server/graph/core/context/types.ts
|
|
1922
|
+
var CONTEXT_NODE_ACTION = "action";
|
|
1923
|
+
var CONTEXT_NODE_STATE = "state";
|
|
1924
|
+
var CONFIDENCE_RANK = { low: 0, medium: 1, high: 2 };
|
|
1925
|
+
function higherConfidence(a, b) {
|
|
1926
|
+
return CONFIDENCE_RANK[a] >= CONFIDENCE_RANK[b] ? a : b;
|
|
1927
|
+
}
|
|
1928
|
+
function stateId(token) {
|
|
1929
|
+
return `state:${token}`;
|
|
1930
|
+
}
|
|
1931
|
+
function actionId(key) {
|
|
1932
|
+
return `action:${key}`;
|
|
1933
|
+
}
|
|
1934
|
+
function stateNode(token, label) {
|
|
1935
|
+
return { id: stateId(token), type: CONTEXT_NODE_STATE, name: token, label };
|
|
1936
|
+
}
|
|
1937
|
+
function actionNode(key, name, meta = {}) {
|
|
1938
|
+
return { id: actionId(key), type: CONTEXT_NODE_ACTION, name, ...meta };
|
|
1939
|
+
}
|
|
1940
|
+
function contextEdge(fromActionId, toStateId, type, confidence, origin) {
|
|
1941
|
+
return { source: fromActionId, target: toStateId, type, label: `${type} (${origin})`, confidence, origin };
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
// src/server/graph/core/context/providers/nextjs-prisma.ts
|
|
1945
|
+
var PRODUCING_METHODS = /* @__PURE__ */ new Set(["create", "createMany", "upsert"]);
|
|
1946
|
+
function isPublic(auth) {
|
|
1947
|
+
if (!auth || auth.length === 0) return true;
|
|
1948
|
+
return auth.every((a) => a === "public");
|
|
1949
|
+
}
|
|
1950
|
+
function notFoundEntity(consequence) {
|
|
1951
|
+
if (!consequence) return null;
|
|
1952
|
+
const m = consequence.match(/notFound\(\s*['"]([A-Za-z0-9_]+)['"]/);
|
|
1953
|
+
return m ? m[1] : null;
|
|
1954
|
+
}
|
|
1955
|
+
var nextjsPrismaContextProvider = {
|
|
1956
|
+
id: "nextjs-prisma",
|
|
1957
|
+
detect(layerOutputs) {
|
|
1958
|
+
const api = layerOutputs["api"];
|
|
1959
|
+
return !!api && (api.nodes ?? []).some((n) => n.type === "endpoint");
|
|
1960
|
+
},
|
|
1961
|
+
derive(layerOutputs) {
|
|
1962
|
+
const api = layerOutputs["api"];
|
|
1963
|
+
const states = /* @__PURE__ */ new Map();
|
|
1964
|
+
const actions = [];
|
|
1965
|
+
const edges = [];
|
|
1966
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
1967
|
+
const ensureState = (token, label) => {
|
|
1968
|
+
const id = stateId(token);
|
|
1969
|
+
if (!states.has(id)) states.set(id, stateNode(token, label));
|
|
1970
|
+
return id;
|
|
1971
|
+
};
|
|
1972
|
+
const addEdge = (from, to, type, confidence, origin) => {
|
|
1973
|
+
const key = `${from}|${type}|${to}`;
|
|
1974
|
+
if (seenEdge.has(key)) return;
|
|
1975
|
+
seenEdge.add(key);
|
|
1976
|
+
edges.push(contextEdge(from, to, type, confidence, origin));
|
|
1977
|
+
};
|
|
1978
|
+
const endpoints = (api?.nodes ?? []).filter((n) => n.type === "endpoint");
|
|
1979
|
+
for (const ep of endpoints) {
|
|
1980
|
+
const aId = actionId(ep.id);
|
|
1981
|
+
actions.push(actionNode(ep.id, ep.name, { methods: ep.methods ?? [], endpoint: ep.id }));
|
|
1982
|
+
if (!isPublic(ep.auth)) {
|
|
1983
|
+
addEdge(aId, ensureState("session", "Authenticated session"), "requires", "high", "auth-wrapper");
|
|
1984
|
+
}
|
|
1985
|
+
for (const op of ep.db_operations ?? []) {
|
|
1986
|
+
const [model, method] = op.split(".");
|
|
1987
|
+
if (!model || !PRODUCING_METHODS.has(method ?? "")) continue;
|
|
1988
|
+
addEdge(aId, ensureState(model, `${model} record exists`), "produces", "medium", `db:${op}`);
|
|
1989
|
+
}
|
|
1990
|
+
for (const cond of ep.conditions ?? []) {
|
|
1991
|
+
const entity = notFoundEntity(cond.consequence);
|
|
1992
|
+
if (!entity) continue;
|
|
1993
|
+
const token = entity.toLowerCase();
|
|
1994
|
+
addEdge(aId, ensureState(token, `${token} record exists`), "requires", "low", "guard:notFound");
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
return { nodes: [...actions, ...states.values()], edges };
|
|
1998
|
+
}
|
|
1999
|
+
};
|
|
2000
|
+
|
|
2001
|
+
// src/server/graph/core/context/overlay.ts
|
|
1914
2002
|
var import_node_fs6 = require("node:fs");
|
|
1915
2003
|
var import_node_path8 = require("node:path");
|
|
2004
|
+
var OVERLAY_FILE = ".launchchart.context.json";
|
|
2005
|
+
function overlayPath(rootDir) {
|
|
2006
|
+
return (0, import_node_path8.join)(rootDir, OVERLAY_FILE);
|
|
2007
|
+
}
|
|
2008
|
+
function loadOverlay(rootDir) {
|
|
2009
|
+
const path2 = overlayPath(rootDir);
|
|
2010
|
+
if (!(0, import_node_fs6.existsSync)(path2)) return null;
|
|
2011
|
+
try {
|
|
2012
|
+
return JSON.parse((0, import_node_fs6.readFileSync)(path2, "utf-8"));
|
|
2013
|
+
} catch (e) {
|
|
2014
|
+
process.stderr.write(`[launch-chart] failed to parse ${OVERLAY_FILE}: ${e.message}
|
|
2015
|
+
`);
|
|
2016
|
+
return null;
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
var overlayProvider = {
|
|
2020
|
+
id: "overlay",
|
|
2021
|
+
detect(_layerOutputs, rootDir) {
|
|
2022
|
+
return (0, import_node_fs6.existsSync)(overlayPath(rootDir));
|
|
2023
|
+
},
|
|
2024
|
+
derive(_layerOutputs, rootDir) {
|
|
2025
|
+
const overlay = loadOverlay(rootDir);
|
|
2026
|
+
if (!overlay) return { nodes: [], edges: [] };
|
|
2027
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
2028
|
+
const edges = [];
|
|
2029
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
2030
|
+
const ensureState = (token, label) => {
|
|
2031
|
+
const id = stateId(token);
|
|
2032
|
+
if (!nodes.has(id)) nodes.set(id, stateNode(token, label ?? `${token} (overlay)`));
|
|
2033
|
+
return id;
|
|
2034
|
+
};
|
|
2035
|
+
const ensureAction = (key, name) => {
|
|
2036
|
+
const id = actionId(key);
|
|
2037
|
+
if (!nodes.has(id)) nodes.set(id, actionNode(key, name ?? key, { source: "overlay" }));
|
|
2038
|
+
return id;
|
|
2039
|
+
};
|
|
2040
|
+
for (const s of overlay.states ?? []) ensureState(s.token, s.label);
|
|
2041
|
+
for (const a of overlay.actions ?? []) ensureAction(a.id, a.name);
|
|
2042
|
+
for (const e of overlay.edges ?? []) {
|
|
2043
|
+
const aId = ensureAction(e.action);
|
|
2044
|
+
const link = (token, type) => {
|
|
2045
|
+
const sId = ensureState(token);
|
|
2046
|
+
const key = `${aId}|${type}|${sId}`;
|
|
2047
|
+
if (seenEdge.has(key)) return;
|
|
2048
|
+
seenEdge.add(key);
|
|
2049
|
+
edges.push(contextEdge(aId, sId, type, "high", "overlay"));
|
|
2050
|
+
};
|
|
2051
|
+
for (const token of e.requires ?? []) link(token, "requires");
|
|
2052
|
+
for (const token of e.produces ?? []) link(token, "produces");
|
|
2053
|
+
}
|
|
2054
|
+
return { nodes: [...nodes.values()], edges };
|
|
2055
|
+
}
|
|
2056
|
+
};
|
|
2057
|
+
function applyOverlayRejections(edges, rootDir) {
|
|
2058
|
+
const overlay = loadOverlay(rootDir);
|
|
2059
|
+
const rejects = overlay?.reject ?? [];
|
|
2060
|
+
if (rejects.length === 0) return edges;
|
|
2061
|
+
const rejectKeys = new Set(
|
|
2062
|
+
rejects.map((r) => `${actionId(r.action)}|${r.type}|${stateId(r.state)}`)
|
|
2063
|
+
);
|
|
2064
|
+
return edges.filter((e) => !rejectKeys.has(`${e.source}|${e.type}|${e.target}`));
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
// src/server/graph/core/context/registry.ts
|
|
2068
|
+
var ContextProviderRegistry = class {
|
|
2069
|
+
constructor() {
|
|
2070
|
+
this.providers = [];
|
|
2071
|
+
this.ids = /* @__PURE__ */ new Set();
|
|
2072
|
+
}
|
|
2073
|
+
register(provider) {
|
|
2074
|
+
if (this.ids.has(provider.id)) {
|
|
2075
|
+
throw new Error(`Duplicate context provider id: ${provider.id}`);
|
|
2076
|
+
}
|
|
2077
|
+
this.ids.add(provider.id);
|
|
2078
|
+
this.providers.push(provider);
|
|
2079
|
+
}
|
|
2080
|
+
getAll() {
|
|
2081
|
+
return [...this.providers];
|
|
2082
|
+
}
|
|
2083
|
+
};
|
|
2084
|
+
function registerBuiltins2(registry, disabled) {
|
|
2085
|
+
const builtins = [nextjsPrismaContextProvider, overlayProvider];
|
|
2086
|
+
for (const provider of builtins) {
|
|
2087
|
+
if (disabled.has(provider.id)) continue;
|
|
2088
|
+
registry.register(provider);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
function loadCustomProviders(registry, config, rootDir, disabled) {
|
|
2092
|
+
for (const entry of config.context?.providers ?? []) {
|
|
2093
|
+
try {
|
|
2094
|
+
const absPath = (0, import_node_path9.resolve)(rootDir, entry.path);
|
|
2095
|
+
const mod = require(absPath);
|
|
2096
|
+
const provider = "default" in mod ? mod.default : mod;
|
|
2097
|
+
if (disabled.has(provider.id)) continue;
|
|
2098
|
+
registry.register(provider);
|
|
2099
|
+
} catch (err) {
|
|
2100
|
+
process.stderr.write(`[launch-chart] failed to load custom context provider from ${entry.path}: ${err}
|
|
2101
|
+
`);
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
function createContextProviderRegistry(config, rootDir) {
|
|
2106
|
+
const registry = new ContextProviderRegistry();
|
|
2107
|
+
const disabled = new Set(config.context?.disabled ?? []);
|
|
2108
|
+
registerBuiltins2(registry, disabled);
|
|
2109
|
+
loadCustomProviders(registry, config, rootDir, disabled);
|
|
2110
|
+
return registry;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
// src/server/graph/core/context-map.ts
|
|
2114
|
+
function buildContextMap(layerOutputs, rootDir) {
|
|
2115
|
+
const generated = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2116
|
+
const config = loadConfig(rootDir);
|
|
2117
|
+
const registry = createContextProviderRegistry(config, rootDir);
|
|
2118
|
+
const nodesById = /* @__PURE__ */ new Map();
|
|
2119
|
+
const edgesByKey = /* @__PURE__ */ new Map();
|
|
2120
|
+
const providerStats = {};
|
|
2121
|
+
const usedProviders = [];
|
|
2122
|
+
for (const provider of registry.getAll()) {
|
|
2123
|
+
let detected = false;
|
|
2124
|
+
try {
|
|
2125
|
+
detected = provider.detect(layerOutputs, rootDir);
|
|
2126
|
+
} catch (e) {
|
|
2127
|
+
process.stderr.write(`[launch-chart] context provider "${provider.id}" detect failed: ${e.message}
|
|
2128
|
+
`);
|
|
2129
|
+
continue;
|
|
2130
|
+
}
|
|
2131
|
+
if (!detected) continue;
|
|
2132
|
+
let contribution;
|
|
2133
|
+
try {
|
|
2134
|
+
contribution = provider.derive(layerOutputs, rootDir);
|
|
2135
|
+
} catch (e) {
|
|
2136
|
+
process.stderr.write(`[launch-chart] context provider "${provider.id}" derive failed: ${e.message}
|
|
2137
|
+
`);
|
|
2138
|
+
continue;
|
|
2139
|
+
}
|
|
2140
|
+
usedProviders.push(provider.id);
|
|
2141
|
+
providerStats[provider.id] = { nodes: contribution.nodes.length, edges: contribution.edges.length };
|
|
2142
|
+
for (const node of contribution.nodes) {
|
|
2143
|
+
if (!nodesById.has(node.id)) nodesById.set(node.id, node);
|
|
2144
|
+
}
|
|
2145
|
+
for (const edge of contribution.edges) {
|
|
2146
|
+
const key = `${edge.source}|${edge.type}|${edge.target}`;
|
|
2147
|
+
const existing = edgesByKey.get(key);
|
|
2148
|
+
const edgeConf = edge.confidence ?? "low";
|
|
2149
|
+
if (!existing) {
|
|
2150
|
+
edgesByKey.set(key, { ...edge, providers: [provider.id] });
|
|
2151
|
+
} else {
|
|
2152
|
+
const existingConf = existing.confidence ?? "low";
|
|
2153
|
+
existing.confidence = higherConfidence(existingConf, edgeConf);
|
|
2154
|
+
const provs = existing.providers ?? [];
|
|
2155
|
+
if (!provs.includes(provider.id)) provs.push(provider.id);
|
|
2156
|
+
existing.providers = provs;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
const merged = [...edgesByKey.values()];
|
|
2161
|
+
const edges = applyOverlayRejections(merged, rootDir);
|
|
2162
|
+
const rejectedCount = merged.length - edges.length;
|
|
2163
|
+
const flagged = edges.map((e) => ({
|
|
2164
|
+
source: e.source,
|
|
2165
|
+
target: e.target,
|
|
2166
|
+
type: e.type,
|
|
2167
|
+
label: e.label ?? `${e.type}`,
|
|
2168
|
+
confidence: e.confidence ?? "low"
|
|
2169
|
+
}));
|
|
2170
|
+
const nodes = [...nodesById.values()];
|
|
2171
|
+
const stateCount = nodes.filter((n) => n.type === CONTEXT_NODE_STATE).length;
|
|
2172
|
+
return {
|
|
2173
|
+
metadata: {
|
|
2174
|
+
generated,
|
|
2175
|
+
scope: "derived",
|
|
2176
|
+
layer: "context",
|
|
2177
|
+
source: "context-map-builder",
|
|
2178
|
+
derived: true,
|
|
2179
|
+
providers: usedProviders,
|
|
2180
|
+
provider_stats: providerStats,
|
|
2181
|
+
action_count: nodes.length - stateCount,
|
|
2182
|
+
state_count: stateCount,
|
|
2183
|
+
candidate_edge_count: edges.length,
|
|
2184
|
+
rejected_edge_count: rejectedCount,
|
|
2185
|
+
note: "Edges are candidates (see flagged_edges + confidence) from the context providers. Promote via the curation overlay."
|
|
2186
|
+
},
|
|
2187
|
+
nodes,
|
|
2188
|
+
edges,
|
|
2189
|
+
cross_refs: [],
|
|
2190
|
+
contradictions: [],
|
|
2191
|
+
warnings: [],
|
|
2192
|
+
flagged_edges: flagged
|
|
2193
|
+
};
|
|
2194
|
+
}
|
|
2195
|
+
function writeContextMap(rootDir, output) {
|
|
2196
|
+
const path2 = (0, import_node_path10.join)(rootDir, LAUNCHSECURE_DIR, "graphs", "context.json");
|
|
2197
|
+
atomicWriteFileSync(path2, JSON.stringify(output, null, 2) + "\n");
|
|
2198
|
+
return path2;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// src/server/graph/core/freshness.ts
|
|
2202
|
+
var import_node_fs7 = require("node:fs");
|
|
2203
|
+
var import_node_path11 = require("node:path");
|
|
1916
2204
|
init_launch_kit_paths();
|
|
1917
2205
|
function exactFilenameRegex(name) {
|
|
1918
2206
|
return new RegExp(`^${name.replace(/\./g, "\\.")}$`);
|
|
@@ -1934,7 +2222,7 @@ function isHardEscalation(relativePath) {
|
|
|
1934
2222
|
var FreshnessTracker = class {
|
|
1935
2223
|
constructor(rootDir) {
|
|
1936
2224
|
this.dirty = false;
|
|
1937
|
-
this.filePath = (0,
|
|
2225
|
+
this.filePath = (0, import_node_path11.join)(rootDir, LAUNCHSECURE_DIR, "graphs", ".freshness.json");
|
|
1938
2226
|
this.snapshot = this.load() ?? {
|
|
1939
2227
|
state: "fresh",
|
|
1940
2228
|
lastFullRegenAt: null,
|
|
@@ -2021,9 +2309,9 @@ var FreshnessTracker = class {
|
|
|
2021
2309
|
}
|
|
2022
2310
|
}
|
|
2023
2311
|
load() {
|
|
2024
|
-
if (!(0,
|
|
2312
|
+
if (!(0, import_node_fs7.existsSync)(this.filePath)) return null;
|
|
2025
2313
|
try {
|
|
2026
|
-
const parsed = JSON.parse((0,
|
|
2314
|
+
const parsed = JSON.parse((0, import_node_fs7.readFileSync)(this.filePath, "utf-8"));
|
|
2027
2315
|
if (parsed.schemaVersion !== SCHEMA_VERSION) return null;
|
|
2028
2316
|
return {
|
|
2029
2317
|
state: parsed.state,
|
|
@@ -2053,24 +2341,24 @@ function getFreshnessTracker(rootDir) {
|
|
|
2053
2341
|
var GRAPHS_DIR2 = ".launchsecure/graphs";
|
|
2054
2342
|
var NON_LAYER_GRAPH_FILES = /* @__PURE__ */ new Set(["tags.json", "effects-index.json"]);
|
|
2055
2343
|
function getAvailableLayers(rootDir) {
|
|
2056
|
-
const dir = (0,
|
|
2057
|
-
if (!(0,
|
|
2058
|
-
return (0,
|
|
2344
|
+
const dir = (0, import_node_path12.join)(rootDir, GRAPHS_DIR2);
|
|
2345
|
+
if (!(0, import_node_fs8.existsSync)(dir)) return [];
|
|
2346
|
+
return (0, import_node_fs8.readdirSync)(dir).filter((f) => f.endsWith(".json") && !f.startsWith(".") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
|
|
2059
2347
|
}
|
|
2060
2348
|
var graphCache = /* @__PURE__ */ new Map();
|
|
2061
2349
|
var taggedCache = /* @__PURE__ */ new Map();
|
|
2062
2350
|
function graphsDir(rootDir) {
|
|
2063
|
-
return (0,
|
|
2351
|
+
return (0, import_node_path12.join)(rootDir, GRAPHS_DIR2);
|
|
2064
2352
|
}
|
|
2065
2353
|
function graphFilePath(rootDir, layer) {
|
|
2066
|
-
return (0,
|
|
2354
|
+
return (0, import_node_path12.join)(graphsDir(rootDir), `${layer}.json`);
|
|
2067
2355
|
}
|
|
2068
2356
|
function tagsFilePath2(rootDir) {
|
|
2069
|
-
return (0,
|
|
2357
|
+
return (0, import_node_path12.join)(graphsDir(rootDir), "tags.json");
|
|
2070
2358
|
}
|
|
2071
2359
|
function getMtimeMs(filePath) {
|
|
2072
|
-
if (!(0,
|
|
2073
|
-
return (0,
|
|
2360
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) return 0;
|
|
2361
|
+
return (0, import_node_fs8.statSync)(filePath).mtimeMs;
|
|
2074
2362
|
}
|
|
2075
2363
|
function invalidateCache(filePath) {
|
|
2076
2364
|
graphCache.delete(filePath);
|
|
@@ -2109,20 +2397,20 @@ function applyTags(graph, layer, rootDir) {
|
|
|
2109
2397
|
}
|
|
2110
2398
|
function readGraphRaw(rootDir, layer) {
|
|
2111
2399
|
const filePath = graphFilePath(rootDir, layer);
|
|
2112
|
-
if (!(0,
|
|
2113
|
-
const stat = (0,
|
|
2400
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) return null;
|
|
2401
|
+
const stat = (0, import_node_fs8.statSync)(filePath);
|
|
2114
2402
|
const cached = graphCache.get(filePath);
|
|
2115
2403
|
if (cached && cached.mtimeMs === stat.mtimeMs) {
|
|
2116
2404
|
return cached.graph;
|
|
2117
2405
|
}
|
|
2118
|
-
const content = (0,
|
|
2406
|
+
const content = (0, import_node_fs8.readFileSync)(filePath, "utf-8");
|
|
2119
2407
|
const graph = JSON.parse(content);
|
|
2120
2408
|
graphCache.set(filePath, { mtimeMs: stat.mtimeMs, graph });
|
|
2121
2409
|
return graph;
|
|
2122
2410
|
}
|
|
2123
2411
|
function readGraph(rootDir, layer) {
|
|
2124
2412
|
const rawFilePath = graphFilePath(rootDir, layer);
|
|
2125
|
-
if (!(0,
|
|
2413
|
+
if (!(0, import_node_fs8.existsSync)(rawFilePath)) return null;
|
|
2126
2414
|
const rawMtime = getMtimeMs(rawFilePath);
|
|
2127
2415
|
const tagsMtime = getMtimeMs(tagsFilePath2(rootDir));
|
|
2128
2416
|
const cacheKey = `${rootDir}:${layer}`;
|
|
@@ -2146,7 +2434,7 @@ function readAllGraphs(rootDir) {
|
|
|
2146
2434
|
}
|
|
2147
2435
|
async function generateGraph(rootDir, layer) {
|
|
2148
2436
|
const dir = graphsDir(rootDir);
|
|
2149
|
-
(0,
|
|
2437
|
+
(0, import_node_fs8.mkdirSync)(dir, { recursive: true });
|
|
2150
2438
|
const { results, failedFiles } = await runParseInWorker({ rootDir, layer });
|
|
2151
2439
|
for (const result of results) {
|
|
2152
2440
|
const filePath = graphFilePath(rootDir, result.layer);
|
|
@@ -2157,13 +2445,13 @@ async function generateGraph(rootDir, layer) {
|
|
|
2157
2445
|
if (!layer) {
|
|
2158
2446
|
const producedLayers = new Set(results.map((r) => r.layer));
|
|
2159
2447
|
try {
|
|
2160
|
-
for (const f of (0,
|
|
2161
|
-
if (!f.endsWith(".json") || f === "tags.json" || f === "effects-index.json") continue;
|
|
2448
|
+
for (const f of (0, import_node_fs8.readdirSync)(dir)) {
|
|
2449
|
+
if (!f.endsWith(".json") || f === "tags.json" || f === "effects-index.json" || f === "context.json") continue;
|
|
2162
2450
|
const layerName = f.replace(/\.json$/, "");
|
|
2163
2451
|
if (producedLayers.has(layerName)) continue;
|
|
2164
|
-
const orphan = (0,
|
|
2452
|
+
const orphan = (0, import_node_path12.join)(dir, f);
|
|
2165
2453
|
try {
|
|
2166
|
-
(0,
|
|
2454
|
+
(0, import_node_fs8.unlinkSync)(orphan);
|
|
2167
2455
|
invalidateCache(orphan);
|
|
2168
2456
|
invalidateTaggedCache(rootDir, layerName);
|
|
2169
2457
|
process.stderr.write(`[launch-chart] removed orphan layer file: ${f} (no parser produced ${layerName} this run)
|
|
@@ -2174,22 +2462,31 @@ async function generateGraph(rootDir, layer) {
|
|
|
2174
2462
|
} catch {
|
|
2175
2463
|
}
|
|
2176
2464
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
if (existing) allLayers[layerName] = existing;
|
|
2187
|
-
}
|
|
2465
|
+
const allLayers = {};
|
|
2466
|
+
for (const r of results) allLayers[r.layer] = r.output;
|
|
2467
|
+
if (layer) {
|
|
2468
|
+
for (const f of (0, import_node_fs8.readdirSync)(dir)) {
|
|
2469
|
+
if (!f.endsWith(".json") || f.startsWith(".") || f === "tags.json" || f === "effects-index.json" || f === "context.json") continue;
|
|
2470
|
+
const layerName = f.replace(/\.json$/, "");
|
|
2471
|
+
if (allLayers[layerName]) continue;
|
|
2472
|
+
const existing = readGraphRaw(rootDir, layerName);
|
|
2473
|
+
if (existing) allLayers[layerName] = existing;
|
|
2188
2474
|
}
|
|
2475
|
+
}
|
|
2476
|
+
try {
|
|
2189
2477
|
const idx = buildEffectsIndex(allLayers);
|
|
2190
2478
|
writeEffectsIndex(rootDir, idx);
|
|
2191
2479
|
} catch (e) {
|
|
2192
2480
|
process.stderr.write(`[launch-chart] effects-index build failed: ${e.message}
|
|
2481
|
+
`);
|
|
2482
|
+
}
|
|
2483
|
+
try {
|
|
2484
|
+
const ctx = buildContextMap(allLayers, rootDir);
|
|
2485
|
+
const ctxPath = writeContextMap(rootDir, ctx);
|
|
2486
|
+
invalidateCache(ctxPath);
|
|
2487
|
+
invalidateTaggedCache(rootDir, "context");
|
|
2488
|
+
} catch (e) {
|
|
2489
|
+
process.stderr.write(`[launch-chart] context-map build failed: ${e.message}
|
|
2193
2490
|
`);
|
|
2194
2491
|
}
|
|
2195
2492
|
try {
|
|
@@ -2208,29 +2505,29 @@ async function generateGraph(rootDir, layer) {
|
|
|
2208
2505
|
|
|
2209
2506
|
// src/server/lockfile.ts
|
|
2210
2507
|
var import_node_child_process = require("node:child_process");
|
|
2211
|
-
var
|
|
2508
|
+
var import_node_fs9 = require("node:fs");
|
|
2212
2509
|
var import_node_os = require("node:os");
|
|
2213
|
-
var
|
|
2510
|
+
var import_node_path13 = require("node:path");
|
|
2214
2511
|
init_launch_kit_paths();
|
|
2215
2512
|
function lockDir(projectRoot) {
|
|
2216
2513
|
if (projectRoot) {
|
|
2217
|
-
return (0,
|
|
2514
|
+
return (0, import_node_path13.join)(projectRoot, LAUNCHSECURE_DIR);
|
|
2218
2515
|
}
|
|
2219
|
-
return (0,
|
|
2516
|
+
return (0, import_node_path13.join)((0, import_node_os.homedir)(), LAUNCHSECURE_DIR);
|
|
2220
2517
|
}
|
|
2221
2518
|
function lockPath(projectRoot) {
|
|
2222
|
-
return (0,
|
|
2519
|
+
return (0, import_node_path13.join)(lockDir(projectRoot), "launch-chart.lock");
|
|
2223
2520
|
}
|
|
2224
2521
|
var _activeProjectRoot;
|
|
2225
2522
|
function readLock(projectRoot) {
|
|
2226
2523
|
const root = projectRoot ?? _activeProjectRoot;
|
|
2227
2524
|
const p = lockPath(root);
|
|
2228
|
-
if (!(0,
|
|
2525
|
+
if (!(0, import_node_fs9.existsSync)(p)) {
|
|
2229
2526
|
if (root) {
|
|
2230
2527
|
const globalP = lockPath();
|
|
2231
|
-
if ((0,
|
|
2528
|
+
if ((0, import_node_fs9.existsSync)(globalP)) {
|
|
2232
2529
|
try {
|
|
2233
|
-
const data = JSON.parse((0,
|
|
2530
|
+
const data = JSON.parse((0, import_node_fs9.readFileSync)(globalP, "utf-8"));
|
|
2234
2531
|
if (typeof data.pid === "number" && typeof data.port === "number" && data.cwd === root) {
|
|
2235
2532
|
return data;
|
|
2236
2533
|
}
|
|
@@ -2241,7 +2538,7 @@ function readLock(projectRoot) {
|
|
|
2241
2538
|
return null;
|
|
2242
2539
|
}
|
|
2243
2540
|
try {
|
|
2244
|
-
const data = JSON.parse((0,
|
|
2541
|
+
const data = JSON.parse((0, import_node_fs9.readFileSync)(p, "utf-8"));
|
|
2245
2542
|
if (typeof data.pid !== "number" || typeof data.port !== "number") return null;
|
|
2246
2543
|
return data;
|
|
2247
2544
|
} catch {
|
|
@@ -2278,7 +2575,7 @@ function getLiveLock(projectRoot) {
|
|
|
2278
2575
|
const live = listenerPid !== null ? listenerPid === lock.pid : isPidAlive(lock.pid);
|
|
2279
2576
|
if (!live) {
|
|
2280
2577
|
try {
|
|
2281
|
-
(0,
|
|
2578
|
+
(0, import_node_fs9.unlinkSync)(lockPath(root));
|
|
2282
2579
|
} catch {
|
|
2283
2580
|
}
|
|
2284
2581
|
return null;
|
|
@@ -2287,14 +2584,14 @@ function getLiveLock(projectRoot) {
|
|
|
2287
2584
|
}
|
|
2288
2585
|
function writeLock(data, projectRoot) {
|
|
2289
2586
|
const root = projectRoot ?? _activeProjectRoot;
|
|
2290
|
-
(0,
|
|
2291
|
-
(0,
|
|
2587
|
+
(0, import_node_fs9.mkdirSync)(lockDir(root), { recursive: true });
|
|
2588
|
+
(0, import_node_fs9.writeFileSync)(lockPath(root), JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
2292
2589
|
if (root) _activeProjectRoot = root;
|
|
2293
2590
|
}
|
|
2294
2591
|
function clearLock(projectRoot) {
|
|
2295
2592
|
const root = projectRoot ?? _activeProjectRoot;
|
|
2296
2593
|
try {
|
|
2297
|
-
(0,
|
|
2594
|
+
(0, import_node_fs9.unlinkSync)(lockPath(root));
|
|
2298
2595
|
} catch {
|
|
2299
2596
|
}
|
|
2300
2597
|
}
|
|
@@ -2303,20 +2600,20 @@ function clearLock(projectRoot) {
|
|
|
2303
2600
|
init_config();
|
|
2304
2601
|
|
|
2305
2602
|
// src/server/graph/core/parser-registry.ts
|
|
2306
|
-
var
|
|
2603
|
+
var import_node_path24 = require("node:path");
|
|
2307
2604
|
|
|
2308
2605
|
// src/server/graph/parsers/ts/typescript-project.ts
|
|
2309
|
-
var
|
|
2310
|
-
var
|
|
2606
|
+
var import_node_fs13 = require("node:fs");
|
|
2607
|
+
var import_node_path17 = require("node:path");
|
|
2311
2608
|
init_config();
|
|
2312
2609
|
|
|
2313
2610
|
// src/server/graph/core/resolve-paths.ts
|
|
2314
|
-
var
|
|
2315
|
-
var
|
|
2611
|
+
var import_node_fs11 = require("node:fs");
|
|
2612
|
+
var import_node_path15 = require("node:path");
|
|
2316
2613
|
|
|
2317
2614
|
// src/server/graph/core/walk.ts
|
|
2318
|
-
var
|
|
2319
|
-
var
|
|
2615
|
+
var import_node_fs10 = require("node:fs");
|
|
2616
|
+
var import_node_path14 = require("node:path");
|
|
2320
2617
|
var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
2321
2618
|
"node_modules",
|
|
2322
2619
|
"dist",
|
|
@@ -2326,12 +2623,12 @@ var DEFAULT_IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
|
2326
2623
|
]);
|
|
2327
2624
|
function walk(dir, exts) {
|
|
2328
2625
|
const results = [];
|
|
2329
|
-
if (!(0,
|
|
2330
|
-
for (const entry of (0,
|
|
2331
|
-
const full = (0,
|
|
2626
|
+
if (!(0, import_node_fs10.existsSync)(dir)) return results;
|
|
2627
|
+
for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true })) {
|
|
2628
|
+
const full = (0, import_node_path14.join)(dir, entry.name);
|
|
2332
2629
|
if (entry.isDirectory()) {
|
|
2333
2630
|
results.push(...walk(full, exts));
|
|
2334
|
-
} else if (exts.includes((0,
|
|
2631
|
+
} else if (exts.includes((0, import_node_path14.extname)(entry.name))) {
|
|
2335
2632
|
results.push(full);
|
|
2336
2633
|
}
|
|
2337
2634
|
}
|
|
@@ -2339,15 +2636,15 @@ function walk(dir, exts) {
|
|
|
2339
2636
|
}
|
|
2340
2637
|
function walkWithIgnore(dir, exts, opts = {}) {
|
|
2341
2638
|
const results = [];
|
|
2342
|
-
if (!(0,
|
|
2639
|
+
if (!(0, import_node_fs10.existsSync)(dir)) return results;
|
|
2343
2640
|
const skip = opts.extraIgnore ? /* @__PURE__ */ new Set([...DEFAULT_IGNORE_DIRS, ...opts.extraIgnore]) : DEFAULT_IGNORE_DIRS;
|
|
2344
|
-
for (const entry of (0,
|
|
2641
|
+
for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true })) {
|
|
2345
2642
|
if (entry.isDirectory()) {
|
|
2346
2643
|
if (entry.name.startsWith(".")) continue;
|
|
2347
2644
|
if (skip.has(entry.name)) continue;
|
|
2348
|
-
results.push(...walkWithIgnore((0,
|
|
2349
|
-
} else if (exts.includes((0,
|
|
2350
|
-
results.push((0,
|
|
2645
|
+
results.push(...walkWithIgnore((0, import_node_path14.join)(dir, entry.name), exts, opts));
|
|
2646
|
+
} else if (exts.includes((0, import_node_path14.extname)(entry.name))) {
|
|
2647
|
+
results.push((0, import_node_path14.join)(dir, entry.name));
|
|
2351
2648
|
}
|
|
2352
2649
|
}
|
|
2353
2650
|
return results;
|
|
@@ -2355,9 +2652,9 @@ function walkWithIgnore(dir, exts, opts = {}) {
|
|
|
2355
2652
|
|
|
2356
2653
|
// src/server/graph/core/resolve-paths.ts
|
|
2357
2654
|
function hasSqlFiles(dir) {
|
|
2358
|
-
if (!(0,
|
|
2655
|
+
if (!(0, import_node_fs11.existsSync)(dir)) return false;
|
|
2359
2656
|
try {
|
|
2360
|
-
return (0,
|
|
2657
|
+
return (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true }).some(
|
|
2361
2658
|
(e) => e.isFile() && e.name.endsWith(".sql")
|
|
2362
2659
|
);
|
|
2363
2660
|
} catch {
|
|
@@ -2365,27 +2662,27 @@ function hasSqlFiles(dir) {
|
|
|
2365
2662
|
}
|
|
2366
2663
|
}
|
|
2367
2664
|
function hasNestedMigrationSql(dir) {
|
|
2368
|
-
if (!(0,
|
|
2665
|
+
if (!(0, import_node_fs11.existsSync)(dir)) return false;
|
|
2369
2666
|
try {
|
|
2370
|
-
return (0,
|
|
2371
|
-
(e) => e.isDirectory() && (0,
|
|
2667
|
+
return (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true }).some(
|
|
2668
|
+
(e) => e.isDirectory() && (0, import_node_fs11.existsSync)((0, import_node_path15.join)(dir, e.name, "migration.sql"))
|
|
2372
2669
|
);
|
|
2373
2670
|
} catch {
|
|
2374
2671
|
return false;
|
|
2375
2672
|
}
|
|
2376
2673
|
}
|
|
2377
2674
|
function resolveDbFromDir(dir) {
|
|
2378
|
-
if (!(0,
|
|
2379
|
-
const schemaPath = (0,
|
|
2380
|
-
if ((0,
|
|
2381
|
-
const migrationsDir2 = (0,
|
|
2675
|
+
if (!(0, import_node_fs11.existsSync)(dir)) return { kind: "none", schemaPath: null, migrationsDir: null };
|
|
2676
|
+
const schemaPath = (0, import_node_path15.join)(dir, "schema.prisma");
|
|
2677
|
+
if ((0, import_node_fs11.existsSync)(schemaPath)) {
|
|
2678
|
+
const migrationsDir2 = (0, import_node_path15.join)(dir, "migrations");
|
|
2382
2679
|
return {
|
|
2383
2680
|
kind: "prisma",
|
|
2384
2681
|
schemaPath,
|
|
2385
|
-
migrationsDir: (0,
|
|
2682
|
+
migrationsDir: (0, import_node_fs11.existsSync)(migrationsDir2) ? migrationsDir2 : null
|
|
2386
2683
|
};
|
|
2387
2684
|
}
|
|
2388
|
-
const migrationsDir = (0,
|
|
2685
|
+
const migrationsDir = (0, import_node_path15.join)(dir, "migrations");
|
|
2389
2686
|
if (hasSqlFiles(migrationsDir) || hasNestedMigrationSql(migrationsDir)) {
|
|
2390
2687
|
return { kind: "sql-migrations", migrationsDir, schemaPath: null };
|
|
2391
2688
|
}
|
|
@@ -2396,19 +2693,19 @@ function resolveDbFromDir(dir) {
|
|
|
2396
2693
|
}
|
|
2397
2694
|
function detectDbConfig(rootDir, config) {
|
|
2398
2695
|
if (config.paths?.dbDir) {
|
|
2399
|
-
return resolveDbFromDir((0,
|
|
2696
|
+
return resolveDbFromDir((0, import_node_path15.join)(rootDir, config.paths.dbDir));
|
|
2400
2697
|
}
|
|
2401
|
-
const candidates = ["prisma", "supabase", "drizzle", (0,
|
|
2698
|
+
const candidates = ["prisma", "supabase", "drizzle", (0, import_node_path15.join)("db", "migrations"), "migrations"];
|
|
2402
2699
|
for (const c of candidates) {
|
|
2403
|
-
const dir = (0,
|
|
2700
|
+
const dir = (0, import_node_path15.join)(rootDir, c);
|
|
2404
2701
|
const resolved = resolveDbFromDir(dir);
|
|
2405
2702
|
if (resolved.kind !== "none") return resolved;
|
|
2406
2703
|
}
|
|
2407
2704
|
return { kind: "none", schemaPath: null, migrationsDir: null };
|
|
2408
2705
|
}
|
|
2409
2706
|
function detectDbDir(rootDir, config, dbConfig) {
|
|
2410
|
-
if (config.paths?.dbDir) return (0,
|
|
2411
|
-
if (dbConfig.kind === "prisma") return (0,
|
|
2707
|
+
if (config.paths?.dbDir) return (0, import_node_path15.join)(rootDir, config.paths.dbDir);
|
|
2708
|
+
if (dbConfig.kind === "prisma") return (0, import_node_path15.dirname)(dbConfig.schemaPath);
|
|
2412
2709
|
if (dbConfig.kind === "sql-migrations") return dbConfig.migrationsDir;
|
|
2413
2710
|
return null;
|
|
2414
2711
|
}
|
|
@@ -2439,16 +2736,16 @@ var NON_SOURCE_DIRS = /* @__PURE__ */ new Set([
|
|
|
2439
2736
|
"libs"
|
|
2440
2737
|
]);
|
|
2441
2738
|
function dirHasTSFiles(dir) {
|
|
2442
|
-
if (!(0,
|
|
2739
|
+
if (!(0, import_node_fs11.existsSync)(dir)) return false;
|
|
2443
2740
|
try {
|
|
2444
2741
|
const stack = [dir];
|
|
2445
2742
|
while (stack.length > 0) {
|
|
2446
2743
|
const cur = stack.pop();
|
|
2447
|
-
const entries = (0,
|
|
2744
|
+
const entries = (0, import_node_fs11.readdirSync)(cur, { withFileTypes: true });
|
|
2448
2745
|
for (const e of entries) {
|
|
2449
2746
|
if (e.isFile() && (e.name.endsWith(".ts") || e.name.endsWith(".tsx"))) return true;
|
|
2450
2747
|
if (e.isDirectory() && !e.name.startsWith(".") && !DEFAULT_IGNORE_DIRS.has(e.name)) {
|
|
2451
|
-
stack.push((0,
|
|
2748
|
+
stack.push((0, import_node_path15.join)(cur, e.name));
|
|
2452
2749
|
}
|
|
2453
2750
|
}
|
|
2454
2751
|
}
|
|
@@ -2457,15 +2754,15 @@ function dirHasTSFiles(dir) {
|
|
|
2457
2754
|
return false;
|
|
2458
2755
|
}
|
|
2459
2756
|
function collectCodeBearingChildren(dir, extraSkip) {
|
|
2460
|
-
if (!(0,
|
|
2757
|
+
if (!(0, import_node_fs11.existsSync)(dir)) return [];
|
|
2461
2758
|
const out = [];
|
|
2462
2759
|
try {
|
|
2463
|
-
for (const entry of (0,
|
|
2760
|
+
for (const entry of (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true })) {
|
|
2464
2761
|
if (!entry.isDirectory()) continue;
|
|
2465
2762
|
if (entry.name.startsWith(".")) continue;
|
|
2466
2763
|
if (NON_SOURCE_DIRS.has(entry.name)) continue;
|
|
2467
2764
|
if (extraSkip?.has(entry.name)) continue;
|
|
2468
|
-
const full = (0,
|
|
2765
|
+
const full = (0, import_node_path15.join)(dir, entry.name);
|
|
2469
2766
|
if (dirHasTSFiles(full)) out.push(full);
|
|
2470
2767
|
}
|
|
2471
2768
|
} catch {
|
|
@@ -2477,7 +2774,7 @@ function detectSrcRoots(rootDir, srcDir, appDir, config) {
|
|
|
2477
2774
|
const roots2 = /* @__PURE__ */ new Set();
|
|
2478
2775
|
roots2.add(appDir);
|
|
2479
2776
|
for (const r of config.paths.srcRoots) {
|
|
2480
|
-
const abs = (0,
|
|
2777
|
+
const abs = (0, import_node_path15.isAbsolute)(r) ? r : (0, import_node_path15.resolve)(rootDir, r);
|
|
2481
2778
|
roots2.add(abs);
|
|
2482
2779
|
}
|
|
2483
2780
|
return [...roots2];
|
|
@@ -2486,7 +2783,7 @@ function detectSrcRoots(rootDir, srcDir, appDir, config) {
|
|
|
2486
2783
|
roots.add(appDir);
|
|
2487
2784
|
for (const c of collectCodeBearingChildren(srcDir)) roots.add(c);
|
|
2488
2785
|
if (srcDir !== rootDir) {
|
|
2489
|
-
const skipSrcWrapper = /* @__PURE__ */ new Set([(0,
|
|
2786
|
+
const skipSrcWrapper = /* @__PURE__ */ new Set([(0, import_node_path15.basename)(srcDir)]);
|
|
2490
2787
|
for (const c of collectCodeBearingChildren(rootDir, skipSrcWrapper)) roots.add(c);
|
|
2491
2788
|
}
|
|
2492
2789
|
return [...roots];
|
|
@@ -2498,10 +2795,10 @@ function detectConventionFiles(rootDir, srcDir) {
|
|
|
2498
2795
|
const dirs = srcDir === rootDir ? [rootDir] : [srcDir, rootDir];
|
|
2499
2796
|
for (const dir of dirs) {
|
|
2500
2797
|
for (const name of CONVENTION_NAMES) {
|
|
2501
|
-
const full = (0,
|
|
2502
|
-
if (!seen.has(full) && (0,
|
|
2798
|
+
const full = (0, import_node_path15.join)(dir, name);
|
|
2799
|
+
if (!seen.has(full) && (0, import_node_fs11.existsSync)(full)) {
|
|
2503
2800
|
try {
|
|
2504
|
-
if ((0,
|
|
2801
|
+
if ((0, import_node_fs11.statSync)(full).isFile()) {
|
|
2505
2802
|
seen.add(full);
|
|
2506
2803
|
out.push(full);
|
|
2507
2804
|
}
|
|
@@ -2516,22 +2813,22 @@ function resolveProjectPaths(rootDir, config) {
|
|
|
2516
2813
|
let srcDir;
|
|
2517
2814
|
let appDir;
|
|
2518
2815
|
if (config.paths?.appDir) {
|
|
2519
|
-
appDir = (0,
|
|
2520
|
-
srcDir = config.paths.srcDir ? (0,
|
|
2816
|
+
appDir = (0, import_node_path15.join)(rootDir, config.paths.appDir);
|
|
2817
|
+
srcDir = config.paths.srcDir ? (0, import_node_path15.join)(rootDir, config.paths.srcDir) : (0, import_node_path15.dirname)(appDir);
|
|
2521
2818
|
} else {
|
|
2522
|
-
const srcApp = (0,
|
|
2523
|
-
const rootApp = (0,
|
|
2524
|
-
if ((0,
|
|
2525
|
-
srcDir = (0,
|
|
2819
|
+
const srcApp = (0, import_node_path15.join)(rootDir, "src", "app");
|
|
2820
|
+
const rootApp = (0, import_node_path15.join)(rootDir, "app");
|
|
2821
|
+
if ((0, import_node_fs11.existsSync)(srcApp)) {
|
|
2822
|
+
srcDir = (0, import_node_path15.join)(rootDir, "src");
|
|
2526
2823
|
appDir = srcApp;
|
|
2527
|
-
} else if ((0,
|
|
2824
|
+
} else if ((0, import_node_fs11.existsSync)(rootApp)) {
|
|
2528
2825
|
srcDir = rootDir;
|
|
2529
2826
|
appDir = rootApp;
|
|
2530
2827
|
} else {
|
|
2531
2828
|
return null;
|
|
2532
2829
|
}
|
|
2533
2830
|
}
|
|
2534
|
-
const apiDir = (0,
|
|
2831
|
+
const apiDir = (0, import_node_path15.join)(appDir, "api");
|
|
2535
2832
|
const dbConfig = detectDbConfig(rootDir, config);
|
|
2536
2833
|
const dbDir = detectDbDir(rootDir, config, dbConfig);
|
|
2537
2834
|
const srcRoots = detectSrcRoots(rootDir, srcDir, appDir, config);
|
|
@@ -2558,25 +2855,25 @@ var CLASSIFICATION_TO_LAYER = {
|
|
|
2558
2855
|
external: "ui"
|
|
2559
2856
|
};
|
|
2560
2857
|
function toNodeId(srcDir, rootDir, absPath) {
|
|
2561
|
-
const relFromSrc = (0,
|
|
2858
|
+
const relFromSrc = (0, import_node_path17.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
2562
2859
|
if (relFromSrc.startsWith("..")) {
|
|
2563
|
-
return (0,
|
|
2860
|
+
return (0, import_node_path17.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
2564
2861
|
}
|
|
2565
2862
|
return relFromSrc;
|
|
2566
2863
|
}
|
|
2567
2864
|
function resolveImport(srcDir, specifier) {
|
|
2568
2865
|
if (!specifier.startsWith("@/")) return null;
|
|
2569
2866
|
const rel = specifier.slice(2);
|
|
2570
|
-
const base = (0,
|
|
2571
|
-
for (const c of [base, base + ".ts", base + ".tsx", (0,
|
|
2572
|
-
if ((0,
|
|
2867
|
+
const base = (0, import_node_path17.join)(srcDir, rel);
|
|
2868
|
+
for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path17.join)(base, "index.ts"), (0, import_node_path17.join)(base, "index.tsx")]) {
|
|
2869
|
+
if ((0, import_node_fs13.existsSync)(c) && (0, import_node_fs13.statSync)(c).isFile()) return c;
|
|
2573
2870
|
}
|
|
2574
2871
|
return null;
|
|
2575
2872
|
}
|
|
2576
2873
|
function resolveRelativeImport(fromFile, specifier) {
|
|
2577
|
-
const base = (0,
|
|
2578
|
-
for (const c of [base, base + ".ts", base + ".tsx", (0,
|
|
2579
|
-
if ((0,
|
|
2874
|
+
const base = (0, import_node_path17.join)((0, import_node_path17.dirname)(fromFile), specifier);
|
|
2875
|
+
for (const c of [base, base + ".ts", base + ".tsx", (0, import_node_path17.join)(base, "index.ts"), (0, import_node_path17.join)(base, "index.tsx")]) {
|
|
2876
|
+
if ((0, import_node_fs13.existsSync)(c) && (0, import_node_fs13.statSync)(c).isFile()) return c;
|
|
2580
2877
|
}
|
|
2581
2878
|
return null;
|
|
2582
2879
|
}
|
|
@@ -2597,7 +2894,7 @@ function resolveBarrelMap(barrelAbsPath, parsedByPath, memo, visiting) {
|
|
|
2597
2894
|
const resolved = resolveRelativeImport(barrelAbsPath, re.from);
|
|
2598
2895
|
if (!resolved) continue;
|
|
2599
2896
|
if (re.isWildcard) {
|
|
2600
|
-
const targetBn = (0,
|
|
2897
|
+
const targetBn = (0, import_node_path17.basename)(resolved);
|
|
2601
2898
|
const targetIsBarrel = targetBn === "index.ts" || targetBn === "index.tsx";
|
|
2602
2899
|
if (targetIsBarrel) {
|
|
2603
2900
|
const nested = resolveBarrelMap(resolved, parsedByPath, memo, visiting);
|
|
@@ -2624,12 +2921,12 @@ function buildAllBarrelMaps(srcDir, parsedByPath) {
|
|
|
2624
2921
|
const barrels = /* @__PURE__ */ new Map();
|
|
2625
2922
|
const memo = /* @__PURE__ */ new Map();
|
|
2626
2923
|
for (const [absPath, parsed] of parsedByPath) {
|
|
2627
|
-
const bn = (0,
|
|
2924
|
+
const bn = (0, import_node_path17.basename)(absPath);
|
|
2628
2925
|
if (bn !== "index.ts" && bn !== "index.tsx") continue;
|
|
2629
2926
|
if (parsed.reExports.length === 0) continue;
|
|
2630
2927
|
const map = resolveBarrelMap(absPath, parsedByPath, memo, /* @__PURE__ */ new Set());
|
|
2631
2928
|
if (map.size > 0) {
|
|
2632
|
-
const barrelId = (0,
|
|
2929
|
+
const barrelId = (0, import_node_path17.relative)(srcDir, (0, import_node_path17.dirname)(absPath)).replace(/\\/g, "/");
|
|
2633
2930
|
barrels.set(barrelId, map);
|
|
2634
2931
|
}
|
|
2635
2932
|
}
|
|
@@ -2654,10 +2951,10 @@ function extractRoute(id) {
|
|
|
2654
2951
|
return route || "/";
|
|
2655
2952
|
}
|
|
2656
2953
|
function nameFromFilename(absPath) {
|
|
2657
|
-
return (0,
|
|
2954
|
+
return (0, import_node_path17.basename)(absPath, (0, import_node_path17.extname)(absPath)).replace(/[-_](\w)/g, (_, c) => c.toUpperCase()).replace(/^(\w)/, (_, c) => c.toUpperCase());
|
|
2658
2955
|
}
|
|
2659
2956
|
function filePathToAppRoute(appDir, absPath) {
|
|
2660
|
-
let route = ("/" + (0,
|
|
2957
|
+
let route = ("/" + (0, import_node_path17.relative)(appDir, absPath).replace(/\\/g, "/")).replace(/\/route\.tsx?$/, "");
|
|
2661
2958
|
route = route.replace(/\/\([^)]+\)/g, "");
|
|
2662
2959
|
route = route.replace(/\[\[\.\.\.([^\]]+)\]\]/g, "*$1?");
|
|
2663
2960
|
route = route.replace(/\[\.\.\.([^\]]+)\]/g, "*$1");
|
|
@@ -2905,7 +3202,7 @@ function generate(rootDir) {
|
|
|
2905
3202
|
const apiNodes = [];
|
|
2906
3203
|
const nodeIdSet = /* @__PURE__ */ new Set();
|
|
2907
3204
|
const routeToNodeId = /* @__PURE__ */ new Map();
|
|
2908
|
-
const fileSet = allDiscovered.filter((f) => !(0,
|
|
3205
|
+
const fileSet = allDiscovered.filter((f) => !(0, import_node_path17.basename)(f).startsWith("index."));
|
|
2909
3206
|
for (const absPath of fileSet) {
|
|
2910
3207
|
const id = toNodeId(srcDir, rootDir, absPath);
|
|
2911
3208
|
const type = classifyType(absPath, id);
|
|
@@ -3065,7 +3362,7 @@ function generate(rootDir) {
|
|
|
3065
3362
|
} catch {
|
|
3066
3363
|
continue;
|
|
3067
3364
|
}
|
|
3068
|
-
const externalId = (0,
|
|
3365
|
+
const externalId = (0, import_node_path17.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
3069
3366
|
const edgesFromThis = [];
|
|
3070
3367
|
const seen = /* @__PURE__ */ new Set();
|
|
3071
3368
|
for (const imp of parsed.imports) {
|
|
@@ -3415,7 +3712,7 @@ var typescriptProjectParser = {
|
|
|
3415
3712
|
};
|
|
3416
3713
|
|
|
3417
3714
|
// src/server/graph/parsers/db/prisma-schema.ts
|
|
3418
|
-
var
|
|
3715
|
+
var import_node_fs14 = require("node:fs");
|
|
3419
3716
|
init_config();
|
|
3420
3717
|
function parseModels(content) {
|
|
3421
3718
|
const nodes = [];
|
|
@@ -3508,7 +3805,7 @@ function parseEnums(content) {
|
|
|
3508
3805
|
}
|
|
3509
3806
|
function detect2(rootDir) {
|
|
3510
3807
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
3511
|
-
return paths?.dbConfig.kind === "prisma" && (0,
|
|
3808
|
+
return paths?.dbConfig.kind === "prisma" && (0, import_node_fs14.existsSync)(paths.dbConfig.schemaPath);
|
|
3512
3809
|
}
|
|
3513
3810
|
function generate2(rootDir) {
|
|
3514
3811
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
@@ -3525,7 +3822,7 @@ function generate2(rootDir) {
|
|
|
3525
3822
|
};
|
|
3526
3823
|
}
|
|
3527
3824
|
const schemaPath = paths.dbConfig.schemaPath;
|
|
3528
|
-
const content = (0,
|
|
3825
|
+
const content = (0, import_node_fs14.readFileSync)(schemaPath, "utf-8");
|
|
3529
3826
|
const { nodes: modelNodes, relations } = parseModels(content);
|
|
3530
3827
|
const enumNodes = parseEnums(content);
|
|
3531
3828
|
const allNodes = [...modelNodes, ...enumNodes];
|
|
@@ -3582,8 +3879,8 @@ var prismaSchemaParser = {
|
|
|
3582
3879
|
};
|
|
3583
3880
|
|
|
3584
3881
|
// src/server/graph/parsers/db/sql-migrations.ts
|
|
3585
|
-
var
|
|
3586
|
-
var
|
|
3882
|
+
var import_node_fs15 = require("node:fs");
|
|
3883
|
+
var import_node_path18 = require("node:path");
|
|
3587
3884
|
var import_pgsql_parser = require("pgsql-parser");
|
|
3588
3885
|
init_config();
|
|
3589
3886
|
var PG_TO_PRISMA = {
|
|
@@ -3617,15 +3914,15 @@ function pgTypeToPrisma(pgType) {
|
|
|
3617
3914
|
return PG_TO_PRISMA[upper] ?? upper;
|
|
3618
3915
|
}
|
|
3619
3916
|
function discoverMigrationFiles(migrationsDir) {
|
|
3620
|
-
if (!(0,
|
|
3917
|
+
if (!(0, import_node_fs15.existsSync)(migrationsDir)) return [];
|
|
3621
3918
|
const out = [];
|
|
3622
|
-
const entries = (0,
|
|
3919
|
+
const entries = (0, import_node_fs15.readdirSync)(migrationsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
3623
3920
|
for (const entry of entries) {
|
|
3624
3921
|
if (entry.isDirectory()) {
|
|
3625
|
-
const sqlPath = (0,
|
|
3626
|
-
if ((0,
|
|
3922
|
+
const sqlPath = (0, import_node_path18.join)(migrationsDir, entry.name, "migration.sql");
|
|
3923
|
+
if ((0, import_node_fs15.existsSync)(sqlPath)) out.push(sqlPath);
|
|
3627
3924
|
} else if (entry.isFile() && entry.name.endsWith(".sql")) {
|
|
3628
|
-
out.push((0,
|
|
3925
|
+
out.push((0, import_node_path18.join)(migrationsDir, entry.name));
|
|
3629
3926
|
}
|
|
3630
3927
|
}
|
|
3631
3928
|
return out;
|
|
@@ -3670,7 +3967,7 @@ function parseMigrations(migrationsDir, dialect = postgresDialect) {
|
|
|
3670
3967
|
};
|
|
3671
3968
|
if (!migrationsDir) return state;
|
|
3672
3969
|
for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
|
|
3673
|
-
const sql = (0,
|
|
3970
|
+
const sql = (0, import_node_fs15.readFileSync)(sqlPath, "utf-8");
|
|
3674
3971
|
let ast;
|
|
3675
3972
|
try {
|
|
3676
3973
|
ast = dialect.parse(sql);
|
|
@@ -4239,8 +4536,8 @@ function indexIsPrismaUncoverable(idx) {
|
|
|
4239
4536
|
return idx.hasPredicate || idx.hasExpressions || idx.method !== "btree";
|
|
4240
4537
|
}
|
|
4241
4538
|
function loadPrismaState(schemaPath) {
|
|
4242
|
-
if (!schemaPath || !(0,
|
|
4243
|
-
const content = (0,
|
|
4539
|
+
if (!schemaPath || !(0, import_node_fs15.existsSync)(schemaPath)) return null;
|
|
4540
|
+
const content = (0, import_node_fs15.readFileSync)(schemaPath, "utf-8");
|
|
4244
4541
|
const tables = /* @__PURE__ */ new Map();
|
|
4245
4542
|
const enums = /* @__PURE__ */ new Map();
|
|
4246
4543
|
const relations = [];
|
|
@@ -4647,7 +4944,7 @@ function generate3(rootDir) {
|
|
|
4647
4944
|
const migrationFiles = migrationsDir ? discoverMigrationFiles(migrationsDir) : [];
|
|
4648
4945
|
let migrationNodeCount = 0;
|
|
4649
4946
|
for (const sqlPath of migrationFiles) {
|
|
4650
|
-
const sql = (0,
|
|
4947
|
+
const sql = (0, import_node_fs15.readFileSync)(sqlPath, "utf-8");
|
|
4651
4948
|
const name = deriveMigrationName(sqlPath);
|
|
4652
4949
|
let ast;
|
|
4653
4950
|
try {
|
|
@@ -4965,14 +5262,14 @@ var fetchResolverParser = {
|
|
|
4965
5262
|
};
|
|
4966
5263
|
|
|
4967
5264
|
// src/server/graph/parsers/crosslayer/api-annotations.ts
|
|
4968
|
-
var
|
|
4969
|
-
var
|
|
5265
|
+
var import_node_fs16 = require("node:fs");
|
|
5266
|
+
var import_node_path19 = require("node:path");
|
|
4970
5267
|
init_config();
|
|
4971
5268
|
var API_ANNOTATION_RE = /@api\s+(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+(\/\S+)/g;
|
|
4972
5269
|
function toNodeId2(srcDir, rootDir, absPath) {
|
|
4973
|
-
const relFromSrc = (0,
|
|
5270
|
+
const relFromSrc = (0, import_node_path19.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
4974
5271
|
if (relFromSrc.startsWith("..")) {
|
|
4975
|
-
return (0,
|
|
5272
|
+
return (0, import_node_path19.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
4976
5273
|
}
|
|
4977
5274
|
return relFromSrc;
|
|
4978
5275
|
}
|
|
@@ -5017,7 +5314,7 @@ var apiAnnotationsParser = {
|
|
|
5017
5314
|
const flaggedEdges = [];
|
|
5018
5315
|
const seenEdge = /* @__PURE__ */ new Set();
|
|
5019
5316
|
for (const absPath of files) {
|
|
5020
|
-
const content = (0,
|
|
5317
|
+
const content = (0, import_node_fs16.readFileSync)(absPath, "utf-8");
|
|
5021
5318
|
const sourceId = toNodeId2(srcDir, rootDir, absPath);
|
|
5022
5319
|
if (!uiNodeIds.has(sourceId)) continue;
|
|
5023
5320
|
let match;
|
|
@@ -5061,14 +5358,14 @@ var apiAnnotationsParser = {
|
|
|
5061
5358
|
};
|
|
5062
5359
|
|
|
5063
5360
|
// src/server/graph/parsers/crosslayer/url-literal-scanner.ts
|
|
5064
|
-
var
|
|
5065
|
-
var
|
|
5361
|
+
var import_node_fs17 = require("node:fs");
|
|
5362
|
+
var import_node_path20 = require("node:path");
|
|
5066
5363
|
init_config();
|
|
5067
5364
|
var URL_LITERAL_RE = /['"`](\/[a-zA-Z][^'"`\s]*?)['"`]/g;
|
|
5068
5365
|
function toNodeId3(srcDir, rootDir, absPath) {
|
|
5069
|
-
const relFromSrc = (0,
|
|
5366
|
+
const relFromSrc = (0, import_node_path20.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
5070
5367
|
if (relFromSrc.startsWith("..")) {
|
|
5071
|
-
return (0,
|
|
5368
|
+
return (0, import_node_path20.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
5072
5369
|
}
|
|
5073
5370
|
return relFromSrc;
|
|
5074
5371
|
}
|
|
@@ -5112,7 +5409,7 @@ var urlLiteralScannerParser = {
|
|
|
5112
5409
|
for (const absPath of files) {
|
|
5113
5410
|
const sourceId = toNodeId3(srcDir, rootDir, absPath);
|
|
5114
5411
|
if (!uiNodeIds.has(sourceId)) continue;
|
|
5115
|
-
const content = (0,
|
|
5412
|
+
const content = (0, import_node_fs17.readFileSync)(absPath, "utf-8");
|
|
5116
5413
|
let match;
|
|
5117
5414
|
URL_LITERAL_RE.lastIndex = 0;
|
|
5118
5415
|
while ((match = URL_LITERAL_RE.exec(content)) !== null) {
|
|
@@ -5143,8 +5440,8 @@ var urlLiteralScannerParser = {
|
|
|
5143
5440
|
};
|
|
5144
5441
|
|
|
5145
5442
|
// src/server/graph/parsers/static/static-values.ts
|
|
5146
|
-
var
|
|
5147
|
-
var
|
|
5443
|
+
var import_node_fs18 = require("node:fs");
|
|
5444
|
+
var import_node_path21 = require("node:path");
|
|
5148
5445
|
init_config();
|
|
5149
5446
|
var parseCode = null;
|
|
5150
5447
|
function tryLoadTreeSitter() {
|
|
@@ -5181,21 +5478,21 @@ function extractEnumValues(rootDir) {
|
|
|
5181
5478
|
const schemaPaths = [];
|
|
5182
5479
|
if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath) {
|
|
5183
5480
|
schemaPaths.push(paths.dbConfig.schemaPath);
|
|
5184
|
-
schemaPaths.push((0,
|
|
5481
|
+
schemaPaths.push((0, import_node_path21.join)((0, import_node_path21.dirname)(paths.dbConfig.schemaPath), "schema"));
|
|
5185
5482
|
} else {
|
|
5186
|
-
schemaPaths.push((0,
|
|
5187
|
-
schemaPaths.push((0,
|
|
5483
|
+
schemaPaths.push((0, import_node_path21.join)(rootDir, "prisma", "schema.prisma"));
|
|
5484
|
+
schemaPaths.push((0, import_node_path21.join)(rootDir, "prisma", "schema"));
|
|
5188
5485
|
}
|
|
5189
5486
|
let content = "";
|
|
5190
5487
|
for (const p of schemaPaths) {
|
|
5191
|
-
if ((0,
|
|
5488
|
+
if ((0, import_node_fs18.existsSync)(p)) {
|
|
5192
5489
|
try {
|
|
5193
|
-
const stat = (0,
|
|
5490
|
+
const stat = (0, import_node_fs18.statSync)(p);
|
|
5194
5491
|
if (stat.isFile()) {
|
|
5195
|
-
content = (0,
|
|
5492
|
+
content = (0, import_node_fs18.readFileSync)(p, "utf-8");
|
|
5196
5493
|
} else if (stat.isDirectory()) {
|
|
5197
|
-
const files = (0,
|
|
5198
|
-
content = files.map((f) => (0,
|
|
5494
|
+
const files = (0, import_node_fs18.readdirSync)(p).filter((f) => f.endsWith(".prisma"));
|
|
5495
|
+
content = files.map((f) => (0, import_node_fs18.readFileSync)((0, import_node_path21.join)(p, f), "utf-8")).join("\n");
|
|
5199
5496
|
}
|
|
5200
5497
|
} catch {
|
|
5201
5498
|
continue;
|
|
@@ -5353,27 +5650,27 @@ function extractSeedData(rootDir) {
|
|
|
5353
5650
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
5354
5651
|
const candidates = [];
|
|
5355
5652
|
if (paths?.dbDir) {
|
|
5356
|
-
candidates.push((0,
|
|
5357
|
-
candidates.push((0,
|
|
5653
|
+
candidates.push((0, import_node_path21.join)(paths.dbDir, "seed.ts"));
|
|
5654
|
+
candidates.push((0, import_node_path21.join)(paths.dbDir, "seed.js"));
|
|
5358
5655
|
} else {
|
|
5359
|
-
candidates.push((0,
|
|
5360
|
-
candidates.push((0,
|
|
5656
|
+
candidates.push((0, import_node_path21.join)(rootDir, "prisma", "seed.ts"));
|
|
5657
|
+
candidates.push((0, import_node_path21.join)(rootDir, "prisma", "seed.js"));
|
|
5361
5658
|
}
|
|
5362
|
-
const baseRoots = paths?.srcRoots ?? [(0,
|
|
5659
|
+
const baseRoots = paths?.srcRoots ?? [(0, import_node_path21.join)(rootDir, "src")];
|
|
5363
5660
|
for (const root of baseRoots) {
|
|
5364
|
-
candidates.push((0,
|
|
5661
|
+
candidates.push((0, import_node_path21.join)(root, "server", "lib", "system-tags.ts"));
|
|
5365
5662
|
}
|
|
5366
5663
|
const seedFiles = candidates.filter((p) => {
|
|
5367
5664
|
try {
|
|
5368
|
-
return (0,
|
|
5665
|
+
return (0, import_node_fs18.existsSync)(p) && (0, import_node_fs18.statSync)(p).isFile();
|
|
5369
5666
|
} catch {
|
|
5370
5667
|
return false;
|
|
5371
5668
|
}
|
|
5372
5669
|
});
|
|
5373
5670
|
const useTreeSitter = tryLoadTreeSitter();
|
|
5374
5671
|
for (const filePath of seedFiles) {
|
|
5375
|
-
const content = (0,
|
|
5376
|
-
const relPath = (0,
|
|
5672
|
+
const content = (0, import_node_fs18.readFileSync)(filePath, "utf-8");
|
|
5673
|
+
const relPath = (0, import_node_path21.relative)(rootDir, filePath);
|
|
5377
5674
|
const seeded = detectSeededArrays(content, relPath);
|
|
5378
5675
|
let astRoot = null;
|
|
5379
5676
|
if (useTreeSitter && parseCode) {
|
|
@@ -5467,11 +5764,11 @@ function extractSeedData(rootDir) {
|
|
|
5467
5764
|
return { nodes, edges };
|
|
5468
5765
|
}
|
|
5469
5766
|
function walkDir(dir, exts) {
|
|
5470
|
-
if (!(0,
|
|
5767
|
+
if (!(0, import_node_fs18.existsSync)(dir)) return [];
|
|
5471
5768
|
const results = [];
|
|
5472
|
-
for (const entry of (0,
|
|
5769
|
+
for (const entry of (0, import_node_fs18.readdirSync)(dir, { withFileTypes: true })) {
|
|
5473
5770
|
if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
|
|
5474
|
-
const full = (0,
|
|
5771
|
+
const full = (0, import_node_path21.join)(dir, entry.name);
|
|
5475
5772
|
if (entry.isDirectory()) results.push(...walkDir(full, exts));
|
|
5476
5773
|
else if (exts.some((ext) => entry.name.endsWith(ext))) results.push(full);
|
|
5477
5774
|
}
|
|
@@ -5480,7 +5777,7 @@ function walkDir(dir, exts) {
|
|
|
5480
5777
|
function extractConstants(rootDir) {
|
|
5481
5778
|
const nodes = [];
|
|
5482
5779
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
5483
|
-
const roots = paths?.srcRoots ?? [(0,
|
|
5780
|
+
const roots = paths?.srcRoots ?? [(0, import_node_path21.join)(rootDir, "src")];
|
|
5484
5781
|
const seenFile = /* @__PURE__ */ new Set();
|
|
5485
5782
|
const allFiles = [];
|
|
5486
5783
|
for (const root of roots) {
|
|
@@ -5493,8 +5790,8 @@ function extractConstants(rootDir) {
|
|
|
5493
5790
|
}
|
|
5494
5791
|
if (allFiles.length === 0) return { nodes };
|
|
5495
5792
|
for (const filePath of allFiles) {
|
|
5496
|
-
const content = (0,
|
|
5497
|
-
const relPath = (0,
|
|
5793
|
+
const content = (0, import_node_fs18.readFileSync)(filePath, "utf-8");
|
|
5794
|
+
const relPath = (0, import_node_path21.relative)(rootDir, filePath);
|
|
5498
5795
|
const constArrayRe = /export\s+const\s+([A-Z][A-Z_0-9]+)\s*(?::[^=]+)?\s*=\s*\[/g;
|
|
5499
5796
|
let cm;
|
|
5500
5797
|
while ((cm = constArrayRe.exec(content)) !== null) {
|
|
@@ -5528,13 +5825,13 @@ function extractConstants(rootDir) {
|
|
|
5528
5825
|
}
|
|
5529
5826
|
function detect4(rootDir) {
|
|
5530
5827
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
5531
|
-
if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath && (0,
|
|
5828
|
+
if (paths?.dbConfig.kind === "prisma" && paths.dbConfig.schemaPath && (0, import_node_fs18.existsSync)(paths.dbConfig.schemaPath)) {
|
|
5532
5829
|
return true;
|
|
5533
5830
|
}
|
|
5534
5831
|
if (paths?.dbDir) {
|
|
5535
|
-
if ((0,
|
|
5832
|
+
if ((0, import_node_fs18.existsSync)((0, import_node_path21.join)(paths.dbDir, "seed.ts")) || (0, import_node_fs18.existsSync)((0, import_node_path21.join)(paths.dbDir, "seed.js"))) return true;
|
|
5536
5833
|
}
|
|
5537
|
-
return (0,
|
|
5834
|
+
return (0, import_node_fs18.existsSync)((0, import_node_path21.join)(rootDir, "prisma", "schema.prisma")) || (0, import_node_fs18.existsSync)((0, import_node_path21.join)(rootDir, "prisma", "seed.ts"));
|
|
5538
5835
|
}
|
|
5539
5836
|
function generate4(rootDir) {
|
|
5540
5837
|
const enumResult = extractEnumValues(rootDir);
|
|
@@ -5609,8 +5906,8 @@ var staticValuesParser = {
|
|
|
5609
5906
|
};
|
|
5610
5907
|
|
|
5611
5908
|
// src/server/graph/parsers/crosslayer/static-ref-scanner.ts
|
|
5612
|
-
var
|
|
5613
|
-
var
|
|
5909
|
+
var import_node_fs19 = require("node:fs");
|
|
5910
|
+
var import_node_path22 = require("node:path");
|
|
5614
5911
|
init_config();
|
|
5615
5912
|
var MIN_VALUE_LENGTH = 4;
|
|
5616
5913
|
var SKIP_VALUES = /* @__PURE__ */ new Set([
|
|
@@ -5785,11 +6082,11 @@ var staticRefScannerParser = {
|
|
|
5785
6082
|
const seen = /* @__PURE__ */ new Set();
|
|
5786
6083
|
let filesScanned = 0;
|
|
5787
6084
|
for (const absPath of files) {
|
|
5788
|
-
const relFromSrc = (0,
|
|
5789
|
-
const sourceId = relFromSrc.startsWith("..") ? (0,
|
|
6085
|
+
const relFromSrc = (0, import_node_path22.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
6086
|
+
const sourceId = relFromSrc.startsWith("..") ? (0, import_node_path22.relative)(rootDir, absPath).replace(/\\/g, "/") : relFromSrc;
|
|
5790
6087
|
const sourceLayer = uiNodeIds.has(sourceId) ? "ui" : apiNodeIds.has(sourceId) ? "api" : null;
|
|
5791
6088
|
if (!sourceLayer) continue;
|
|
5792
|
-
const content = (0,
|
|
6089
|
+
const content = (0, import_node_fs19.readFileSync)(absPath, "utf-8");
|
|
5793
6090
|
filesScanned++;
|
|
5794
6091
|
let fileRefs;
|
|
5795
6092
|
if (parseCode2) {
|
|
@@ -5831,13 +6128,13 @@ var staticRefScannerParser = {
|
|
|
5831
6128
|
};
|
|
5832
6129
|
|
|
5833
6130
|
// src/server/graph/parsers/crosslayer/middleware-gates.ts
|
|
5834
|
-
var
|
|
6131
|
+
var import_node_path23 = require("node:path");
|
|
5835
6132
|
init_ts_extractor();
|
|
5836
6133
|
init_config();
|
|
5837
6134
|
function toNodeId4(srcDir, rootDir, absPath) {
|
|
5838
|
-
const relFromSrc = (0,
|
|
6135
|
+
const relFromSrc = (0, import_node_path23.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
5839
6136
|
if (relFromSrc.startsWith("..")) {
|
|
5840
|
-
return (0,
|
|
6137
|
+
return (0, import_node_path23.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
5841
6138
|
}
|
|
5842
6139
|
return relFromSrc;
|
|
5843
6140
|
}
|
|
@@ -6118,7 +6415,7 @@ var ParserRegistry = class {
|
|
|
6118
6415
|
return all;
|
|
6119
6416
|
}
|
|
6120
6417
|
};
|
|
6121
|
-
function
|
|
6418
|
+
function registerBuiltins3(registry, disabled) {
|
|
6122
6419
|
const builtins = [
|
|
6123
6420
|
typescriptProjectParser,
|
|
6124
6421
|
prismaSchemaParser,
|
|
@@ -6139,7 +6436,7 @@ function registerBuiltins2(registry, disabled) {
|
|
|
6139
6436
|
function loadCustomParsers(registry, config, rootDir, disabled) {
|
|
6140
6437
|
for (const entry of config.parsers?.custom ?? []) {
|
|
6141
6438
|
try {
|
|
6142
|
-
const absPath = (0,
|
|
6439
|
+
const absPath = (0, import_node_path24.resolve)(rootDir, entry.path);
|
|
6143
6440
|
const mod = require(absPath);
|
|
6144
6441
|
const parser = "default" in mod ? mod.default : mod;
|
|
6145
6442
|
if (disabled.has(parser.id)) continue;
|
|
@@ -6162,19 +6459,19 @@ function loadCustomParsers(registry, config, rootDir, disabled) {
|
|
|
6162
6459
|
function createRegistry(config, rootDir) {
|
|
6163
6460
|
const registry = new ParserRegistry();
|
|
6164
6461
|
const disabled = new Set(config.parsers?.disabled ?? []);
|
|
6165
|
-
|
|
6462
|
+
registerBuiltins3(registry, disabled);
|
|
6166
6463
|
loadCustomParsers(registry, config, rootDir, disabled);
|
|
6167
6464
|
return registry;
|
|
6168
6465
|
}
|
|
6169
6466
|
|
|
6170
6467
|
// src/server/graph/core/audit-core.ts
|
|
6171
|
-
var
|
|
6172
|
-
var
|
|
6468
|
+
var import_node_fs21 = require("node:fs");
|
|
6469
|
+
var import_node_path26 = require("node:path");
|
|
6173
6470
|
init_launch_kit_paths();
|
|
6174
6471
|
|
|
6175
6472
|
// src/server/graph/core/audit-security.ts
|
|
6176
|
-
var
|
|
6177
|
-
var
|
|
6473
|
+
var import_node_fs20 = require("node:fs");
|
|
6474
|
+
var import_node_path25 = require("node:path");
|
|
6178
6475
|
init_ts_extractor();
|
|
6179
6476
|
init_config();
|
|
6180
6477
|
function collectSourceFiles(rootDir) {
|
|
@@ -6199,9 +6496,9 @@ function collectSourceFiles(rootDir) {
|
|
|
6199
6496
|
return out;
|
|
6200
6497
|
}
|
|
6201
6498
|
function toNodeId5(rootDir, srcDir, absPath) {
|
|
6202
|
-
const relFromSrc = (0,
|
|
6499
|
+
const relFromSrc = (0, import_node_path25.relative)(srcDir, absPath).replace(/\\/g, "/");
|
|
6203
6500
|
if (relFromSrc.startsWith("..")) {
|
|
6204
|
-
return (0,
|
|
6501
|
+
return (0, import_node_path25.relative)(rootDir, absPath).replace(/\\/g, "/");
|
|
6205
6502
|
}
|
|
6206
6503
|
return relFromSrc;
|
|
6207
6504
|
}
|
|
@@ -6311,18 +6608,18 @@ function collectDeclaredEnvKeys(rootDir) {
|
|
|
6311
6608
|
const files = [];
|
|
6312
6609
|
let entries = [];
|
|
6313
6610
|
try {
|
|
6314
|
-
entries = (0,
|
|
6611
|
+
entries = (0, import_node_fs20.readdirSync)(rootDir);
|
|
6315
6612
|
} catch {
|
|
6316
6613
|
return { keys, files };
|
|
6317
6614
|
}
|
|
6318
6615
|
for (const name of entries) {
|
|
6319
6616
|
if (!name.startsWith(".env")) continue;
|
|
6320
|
-
const abs = (0,
|
|
6321
|
-
if (!(0,
|
|
6617
|
+
const abs = (0, import_node_path25.join)(rootDir, name);
|
|
6618
|
+
if (!(0, import_node_fs20.existsSync)(abs)) continue;
|
|
6322
6619
|
files.push(name);
|
|
6323
6620
|
let content = "";
|
|
6324
6621
|
try {
|
|
6325
|
-
content = (0,
|
|
6622
|
+
content = (0, import_node_fs20.readFileSync)(abs, "utf-8");
|
|
6326
6623
|
} catch {
|
|
6327
6624
|
continue;
|
|
6328
6625
|
}
|
|
@@ -6509,10 +6806,10 @@ function checkHardcodedUrlFallback(rootDir, core) {
|
|
|
6509
6806
|
|
|
6510
6807
|
// src/server/graph/core/audit-core.ts
|
|
6511
6808
|
function readGraphFile(rootDir, layer) {
|
|
6512
|
-
const filePath = (0,
|
|
6513
|
-
if (!(0,
|
|
6809
|
+
const filePath = (0, import_node_path26.join)(rootDir, LAUNCHSECURE_DIR, "graphs", `${layer}.json`);
|
|
6810
|
+
if (!(0, import_node_fs21.existsSync)(filePath)) return null;
|
|
6514
6811
|
try {
|
|
6515
|
-
return JSON.parse((0,
|
|
6812
|
+
return JSON.parse((0, import_node_fs21.readFileSync)(filePath, "utf-8"));
|
|
6516
6813
|
} catch {
|
|
6517
6814
|
return null;
|
|
6518
6815
|
}
|
|
@@ -6554,15 +6851,15 @@ function checkUnprotectedRoutes(rootDir) {
|
|
|
6554
6851
|
const findings = [];
|
|
6555
6852
|
const api = readGraphFile(rootDir, "api");
|
|
6556
6853
|
if (!api) return buildSkipped("api", "unprotected_routes", "no api graph");
|
|
6557
|
-
const routePermsPath = (0,
|
|
6558
|
-
if (!(0,
|
|
6854
|
+
const routePermsPath = (0, import_node_path26.join)(rootDir, "src", "config", "route-permissions.ts");
|
|
6855
|
+
if (!(0, import_node_fs21.existsSync)(routePermsPath)) {
|
|
6559
6856
|
return buildSkipped(
|
|
6560
6857
|
"api",
|
|
6561
6858
|
"unprotected_routes",
|
|
6562
6859
|
`no src/config/route-permissions.ts \u2014 this check needs a centralized ROUTE_PERMISSIONS inventory to compare endpoints against`
|
|
6563
6860
|
);
|
|
6564
6861
|
}
|
|
6565
|
-
const routePermsContent = (0,
|
|
6862
|
+
const routePermsContent = (0, import_node_fs21.readFileSync)(routePermsPath, "utf-8");
|
|
6566
6863
|
const registeredRoutes = /* @__PURE__ */ new Set();
|
|
6567
6864
|
const routeEntryRe = /path:\s*'([^']+)'/g;
|
|
6568
6865
|
let rm;
|
|
@@ -6647,15 +6944,15 @@ function checkUnenforcedPermissions(rootDir) {
|
|
|
6647
6944
|
`no seed_permission nodes \u2014 this project either has no seed permissions or hasn't tagged them in seed.ts`
|
|
6648
6945
|
);
|
|
6649
6946
|
}
|
|
6650
|
-
const routePermsPath = (0,
|
|
6651
|
-
if (!(0,
|
|
6947
|
+
const routePermsPath = (0, import_node_path26.join)(rootDir, "src", "config", "route-permissions.ts");
|
|
6948
|
+
if (!(0, import_node_fs21.existsSync)(routePermsPath)) {
|
|
6652
6949
|
return buildSkipped(
|
|
6653
6950
|
"static",
|
|
6654
6951
|
"unenforced_permissions",
|
|
6655
6952
|
`no src/config/route-permissions.ts to compare seed permissions against`
|
|
6656
6953
|
);
|
|
6657
6954
|
}
|
|
6658
|
-
const routePermsContent = (0,
|
|
6955
|
+
const routePermsContent = (0, import_node_fs21.readFileSync)(routePermsPath, "utf-8");
|
|
6659
6956
|
for (const perm of permissions) {
|
|
6660
6957
|
const regex = new RegExp(`permission:\\s*['"]${perm.key}['"]`);
|
|
6661
6958
|
if (!regex.test(routePermsContent)) {
|
|
@@ -6691,9 +6988,9 @@ function checkHardcodedValues(rootDir) {
|
|
|
6691
6988
|
const seen = /* @__PURE__ */ new Set();
|
|
6692
6989
|
for (const node of api.nodes) {
|
|
6693
6990
|
if (node.type !== "endpoint") continue;
|
|
6694
|
-
const filePath = (0,
|
|
6695
|
-
if (!(0,
|
|
6696
|
-
const content = (0,
|
|
6991
|
+
const filePath = (0, import_node_path26.join)(rootDir, "src", node.id);
|
|
6992
|
+
if (!(0, import_node_fs21.existsSync)(filePath)) continue;
|
|
6993
|
+
const content = (0, import_node_fs21.readFileSync)(filePath, "utf-8");
|
|
6697
6994
|
let m;
|
|
6698
6995
|
allCapsRe.lastIndex = 0;
|
|
6699
6996
|
while ((m = allCapsRe.exec(content)) !== null) {
|
|
@@ -6853,16 +7150,16 @@ var MIME_TYPES = {
|
|
|
6853
7150
|
function findProjectRoot(startDir) {
|
|
6854
7151
|
let dir = startDir;
|
|
6855
7152
|
for (let i = 0; i < 8; i++) {
|
|
6856
|
-
const graphsDir2 =
|
|
6857
|
-
if (
|
|
6858
|
-
const parent =
|
|
7153
|
+
const graphsDir2 = import_node_path27.default.join(dir, LAUNCHSECURE_DIR, "graphs");
|
|
7154
|
+
if (import_node_fs22.default.existsSync(import_node_path27.default.join(graphsDir2, "ui.json")) || import_node_fs22.default.existsSync(import_node_path27.default.join(graphsDir2, "api.json")) || import_node_fs22.default.existsSync(import_node_path27.default.join(graphsDir2, "db.json"))) return dir;
|
|
7155
|
+
const parent = import_node_path27.default.dirname(dir);
|
|
6859
7156
|
if (parent === dir) break;
|
|
6860
7157
|
dir = parent;
|
|
6861
7158
|
}
|
|
6862
7159
|
dir = startDir;
|
|
6863
7160
|
for (let i = 0; i < 8; i++) {
|
|
6864
|
-
if (
|
|
6865
|
-
const parent =
|
|
7161
|
+
if (import_node_fs22.default.existsSync(import_node_path27.default.join(dir, ".git"))) return dir;
|
|
7162
|
+
const parent = import_node_path27.default.dirname(dir);
|
|
6866
7163
|
if (parent === dir) break;
|
|
6867
7164
|
dir = parent;
|
|
6868
7165
|
}
|
|
@@ -6871,7 +7168,7 @@ function findProjectRoot(startDir) {
|
|
|
6871
7168
|
function resolveRequestRoot(url, monorepoRoot, projects) {
|
|
6872
7169
|
const projectParam = url.searchParams.get("project");
|
|
6873
7170
|
if (!projectParam || projects.length === 0) return monorepoRoot;
|
|
6874
|
-
const resolved =
|
|
7171
|
+
const resolved = import_node_path27.default.resolve(monorepoRoot, projectParam);
|
|
6875
7172
|
if (!resolved.startsWith(monorepoRoot)) {
|
|
6876
7173
|
throw new Error("Project path outside monorepo root");
|
|
6877
7174
|
}
|
|
@@ -6922,16 +7219,16 @@ async function buildMergedGraph(root) {
|
|
|
6922
7219
|
};
|
|
6923
7220
|
}
|
|
6924
7221
|
function serveStatic(res, filePath) {
|
|
6925
|
-
if (!
|
|
6926
|
-
const ext =
|
|
7222
|
+
if (!import_node_fs22.default.existsSync(filePath) || !import_node_fs22.default.statSync(filePath).isFile()) return false;
|
|
7223
|
+
const ext = import_node_path27.default.extname(filePath).toLowerCase();
|
|
6927
7224
|
const mime = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
6928
7225
|
res.writeHead(200, { "Content-Type": mime, "Cache-Control": "no-cache" });
|
|
6929
|
-
|
|
7226
|
+
import_node_fs22.default.createReadStream(filePath).pipe(res);
|
|
6930
7227
|
return true;
|
|
6931
7228
|
}
|
|
6932
7229
|
function serveIndex(res, clientDir) {
|
|
6933
|
-
const indexPath =
|
|
6934
|
-
if (!
|
|
7230
|
+
const indexPath = import_node_path27.default.join(clientDir, "index.html");
|
|
7231
|
+
if (!import_node_fs22.default.existsSync(indexPath)) {
|
|
6935
7232
|
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
6936
7233
|
res.end(`LaunchChart client bundle not found at ${clientDir}. Run 'npm run build:chart-client'.`);
|
|
6937
7234
|
return;
|
|
@@ -6939,14 +7236,14 @@ function serveIndex(res, clientDir) {
|
|
|
6939
7236
|
serveStatic(res, indexPath);
|
|
6940
7237
|
}
|
|
6941
7238
|
function tryListen(server, port) {
|
|
6942
|
-
return new Promise((
|
|
7239
|
+
return new Promise((resolve5, reject) => {
|
|
6943
7240
|
const onError = (err) => {
|
|
6944
7241
|
server.off("listening", onListening);
|
|
6945
7242
|
reject(err);
|
|
6946
7243
|
};
|
|
6947
7244
|
const onListening = () => {
|
|
6948
7245
|
server.off("error", onError);
|
|
6949
|
-
|
|
7246
|
+
resolve5(port);
|
|
6950
7247
|
};
|
|
6951
7248
|
server.once("error", onError);
|
|
6952
7249
|
server.once("listening", onListening);
|
|
@@ -6983,7 +7280,7 @@ async function startChartServer(opts = {}) {
|
|
|
6983
7280
|
}
|
|
6984
7281
|
return { port: existing.port, url: existing.url };
|
|
6985
7282
|
}
|
|
6986
|
-
const clientDir = opts.clientDir ??
|
|
7283
|
+
const clientDir = opts.clientDir ?? import_node_path27.default.join(__dirname, "..", "chart-client");
|
|
6987
7284
|
const rootConfig = loadConfig(projectRoot);
|
|
6988
7285
|
const projects = rootConfig.projects ?? [];
|
|
6989
7286
|
const server = import_node_http.default.createServer((req, res) => {
|
|
@@ -6999,11 +7296,11 @@ async function startChartServer(opts = {}) {
|
|
|
6999
7296
|
}
|
|
7000
7297
|
if (req.method === "GET" && url2.pathname === "/api/projects") {
|
|
7001
7298
|
const projectList = projects.length > 0 ? projects.map((p) => {
|
|
7002
|
-
const absRoot =
|
|
7003
|
-
const hasGraphs =
|
|
7004
|
-
const hasNextConfig =
|
|
7299
|
+
const absRoot = import_node_path27.default.resolve(projectRoot, p.root);
|
|
7300
|
+
const hasGraphs = import_node_fs22.default.existsSync(import_node_path27.default.join(absRoot, LAUNCHSECURE_DIR, "graphs"));
|
|
7301
|
+
const hasNextConfig = import_node_fs22.default.existsSync(import_node_path27.default.join(absRoot, "next.config.ts")) || import_node_fs22.default.existsSync(import_node_path27.default.join(absRoot, "next.config.js")) || import_node_fs22.default.existsSync(import_node_path27.default.join(absRoot, "next.config.mjs"));
|
|
7005
7302
|
return { name: p.name, root: p.root, hasGraphs, hasNextConfig };
|
|
7006
|
-
}) : [{ name:
|
|
7303
|
+
}) : [{ name: import_node_path27.default.basename(projectRoot), root: ".", hasGraphs: import_node_fs22.default.existsSync(import_node_path27.default.join(projectRoot, LAUNCHSECURE_DIR, "graphs")), hasNextConfig: true }];
|
|
7007
7304
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7008
7305
|
res.end(JSON.stringify({ projects: projectList, monorepoRoot: projectRoot }));
|
|
7009
7306
|
return;
|
|
@@ -7049,20 +7346,20 @@ async function startChartServer(opts = {}) {
|
|
|
7049
7346
|
}
|
|
7050
7347
|
if (req.method === "GET" && url2.pathname === "/api/file-content") {
|
|
7051
7348
|
const relPath = url2.searchParams.get("path");
|
|
7052
|
-
if (!relPath || relPath.includes("..") ||
|
|
7349
|
+
if (!relPath || relPath.includes("..") || import_node_path27.default.isAbsolute(relPath)) {
|
|
7053
7350
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
7054
7351
|
res.end(JSON.stringify({ error: "Invalid path" }));
|
|
7055
7352
|
return;
|
|
7056
7353
|
}
|
|
7057
|
-
const filePath =
|
|
7058
|
-
if (!filePath.startsWith(reqRoot) || !
|
|
7354
|
+
const filePath = import_node_path27.default.join(reqRoot, relPath);
|
|
7355
|
+
if (!filePath.startsWith(reqRoot) || !import_node_fs22.default.existsSync(filePath) || !import_node_fs22.default.statSync(filePath).isFile()) {
|
|
7059
7356
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
7060
7357
|
res.end(JSON.stringify({ error: "File not found" }));
|
|
7061
7358
|
return;
|
|
7062
7359
|
}
|
|
7063
|
-
const ext =
|
|
7360
|
+
const ext = import_node_path27.default.extname(filePath).toLowerCase();
|
|
7064
7361
|
const langMap = { ".ts": "typescript", ".tsx": "tsx", ".js": "javascript", ".jsx": "jsx", ".prisma": "prisma", ".json": "json", ".css": "css" };
|
|
7065
|
-
const content =
|
|
7362
|
+
const content = import_node_fs22.default.readFileSync(filePath, "utf-8");
|
|
7066
7363
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7067
7364
|
res.end(JSON.stringify({ content, language: langMap[ext] ?? "text", path: relPath }));
|
|
7068
7365
|
return;
|
|
@@ -7117,8 +7414,8 @@ async function startChartServer(opts = {}) {
|
|
|
7117
7414
|
const newConfig = JSON.parse(body);
|
|
7118
7415
|
const existingConfig = loadConfig(reqRoot);
|
|
7119
7416
|
const merged = { ...existingConfig, ...newConfig };
|
|
7120
|
-
const configPath =
|
|
7121
|
-
|
|
7417
|
+
const configPath = import_node_path27.default.join(reqRoot, LAUNCHCHART_CONFIG_FILE);
|
|
7418
|
+
import_node_fs22.default.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
7122
7419
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7123
7420
|
res.end(JSON.stringify({ ok: true }));
|
|
7124
7421
|
} catch (err) {
|
|
@@ -7151,8 +7448,8 @@ async function startChartServer(opts = {}) {
|
|
|
7151
7448
|
const taggerConfig = JSON.parse(body);
|
|
7152
7449
|
const config2 = loadConfig(reqRoot);
|
|
7153
7450
|
config2.taggers = taggerConfig;
|
|
7154
|
-
const configPath =
|
|
7155
|
-
|
|
7451
|
+
const configPath = import_node_path27.default.join(reqRoot, LAUNCHCHART_CONFIG_FILE);
|
|
7452
|
+
import_node_fs22.default.writeFileSync(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
7156
7453
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7157
7454
|
res.end(JSON.stringify({ ok: true }));
|
|
7158
7455
|
} catch (err) {
|
|
@@ -7222,7 +7519,7 @@ async function startChartServer(opts = {}) {
|
|
|
7222
7519
|
dbDir: !!config2.paths?.dbDir,
|
|
7223
7520
|
srcRoots: !!(config2.paths?.srcRoots && config2.paths.srcRoots.length > 0)
|
|
7224
7521
|
};
|
|
7225
|
-
const relFromRoot = (abs) =>
|
|
7522
|
+
const relFromRoot = (abs) => import_node_path27.default.relative(reqRoot, abs) || ".";
|
|
7226
7523
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7227
7524
|
res.end(JSON.stringify({
|
|
7228
7525
|
projectRoot: reqRoot,
|
|
@@ -7244,19 +7541,19 @@ async function startChartServer(opts = {}) {
|
|
|
7244
7541
|
}
|
|
7245
7542
|
if (req.method === "GET" && url2.pathname === "/api/browse-dir") {
|
|
7246
7543
|
const browsePath = url2.searchParams.get("path") || projectRoot;
|
|
7247
|
-
const abs =
|
|
7248
|
-
const twoUp =
|
|
7544
|
+
const abs = import_node_path27.default.resolve(browsePath);
|
|
7545
|
+
const twoUp = import_node_path27.default.resolve(projectRoot, "..", "..");
|
|
7249
7546
|
if (!abs.startsWith(twoUp)) {
|
|
7250
7547
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
7251
7548
|
res.end(JSON.stringify({ ok: false, error: "Path outside allowed range" }));
|
|
7252
7549
|
return;
|
|
7253
7550
|
}
|
|
7254
7551
|
try {
|
|
7255
|
-
const entries =
|
|
7552
|
+
const entries = import_node_fs22.default.readdirSync(abs, { withFileTypes: true });
|
|
7256
7553
|
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();
|
|
7257
|
-
const parent = abs !== twoUp ?
|
|
7554
|
+
const parent = abs !== twoUp ? import_node_path27.default.dirname(abs) : null;
|
|
7258
7555
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7259
|
-
res.end(JSON.stringify({ current: abs, parent, dirs, relative:
|
|
7556
|
+
res.end(JSON.stringify({ current: abs, parent, dirs, relative: import_node_path27.default.relative(projectRoot, abs) || "." }));
|
|
7260
7557
|
} catch (err) {
|
|
7261
7558
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
7262
7559
|
res.end(JSON.stringify({ ok: false, error: String(err) }));
|
|
@@ -7282,8 +7579,8 @@ async function startChartServer(opts = {}) {
|
|
|
7282
7579
|
const { projects: newProjects } = JSON.parse(body);
|
|
7283
7580
|
const config2 = loadConfig(projectRoot);
|
|
7284
7581
|
config2.projects = newProjects.length > 0 ? newProjects : void 0;
|
|
7285
|
-
const configPath =
|
|
7286
|
-
|
|
7582
|
+
const configPath = import_node_path27.default.join(projectRoot, LAUNCHCHART_CONFIG_FILE);
|
|
7583
|
+
import_node_fs22.default.writeFileSync(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
7287
7584
|
projects.length = 0;
|
|
7288
7585
|
if (config2.projects) projects.push(...config2.projects);
|
|
7289
7586
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -7296,7 +7593,7 @@ async function startChartServer(opts = {}) {
|
|
|
7296
7593
|
return;
|
|
7297
7594
|
}
|
|
7298
7595
|
if (url2.pathname !== "/") {
|
|
7299
|
-
const staticPath =
|
|
7596
|
+
const staticPath = import_node_path27.default.join(clientDir, url2.pathname);
|
|
7300
7597
|
if (serveStatic(res, staticPath)) return;
|
|
7301
7598
|
}
|
|
7302
7599
|
serveIndex(res, clientDir);
|