@launchsecure/launch-kit 0.0.29 → 0.0.31
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/beacon/beacon.mjs +2825 -1243
- package/dist/beacon/beacon.mjs.map +1 -1
- package/dist/beacon/beacon.umd.js +710 -95
- package/dist/beacon/beacon.umd.js.map +1 -1
- package/dist/beacon/types/core.d.ts +14 -0
- package/dist/beacon/types/core.d.ts.map +1 -0
- package/dist/beacon/types/ctx.d.ts +14 -0
- package/dist/beacon/types/ctx.d.ts.map +1 -0
- package/dist/beacon/types/element.d.ts +16 -48
- package/dist/beacon/types/element.d.ts.map +1 -1
- package/dist/beacon/types/index.d.ts +5 -4
- package/dist/beacon/types/index.d.ts.map +1 -1
- package/dist/beacon/types/internal/annotation-cache.d.ts +10 -0
- package/dist/beacon/types/internal/annotation-cache.d.ts.map +1 -0
- package/dist/beacon/types/internal/element-capture.d.ts +19 -0
- package/dist/beacon/types/internal/element-capture.d.ts.map +1 -0
- package/dist/beacon/types/internal/event-buffer.d.ts +16 -0
- package/dist/beacon/types/internal/event-buffer.d.ts.map +1 -0
- package/dist/beacon/types/internal/framework-detect.d.ts +6 -0
- package/dist/beacon/types/internal/framework-detect.d.ts.map +1 -0
- package/dist/beacon/types/internal/markers.d.ts +17 -0
- package/dist/beacon/types/internal/markers.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/capture-dom.d.ts +14 -0
- package/dist/beacon/types/internal/monitor/capture-dom.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/capture-network.d.ts +12 -0
- package/dist/beacon/types/internal/monitor/capture-network.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/overlay.d.ts +16 -0
- package/dist/beacon/types/internal/monitor/overlay.d.ts.map +1 -0
- package/dist/beacon/types/internal/monitor/session.d.ts +41 -0
- package/dist/beacon/types/internal/monitor/session.d.ts.map +1 -0
- package/dist/beacon/types/{monitor → internal/monitor}/transport.d.ts +3 -3
- package/dist/beacon/types/internal/monitor/transport.d.ts.map +1 -0
- package/dist/beacon/types/{monitor/types.d.ts → internal/monitor/wire.d.ts} +69 -27
- package/dist/beacon/types/internal/monitor/wire.d.ts.map +1 -0
- package/dist/beacon/types/{ui → internal}/pick-mode-overlay.d.ts +4 -5
- package/dist/beacon/types/internal/pick-mode-overlay.d.ts.map +1 -0
- package/dist/beacon/types/{capture → internal}/picker.d.ts +0 -1
- package/dist/beacon/types/internal/picker.d.ts.map +1 -0
- package/dist/beacon/types/{ui → internal}/pin-popover.d.ts +1 -1
- package/dist/beacon/types/internal/pin-popover.d.ts.map +1 -0
- package/dist/beacon/types/internal/screenshot.d.ts +26 -0
- package/dist/beacon/types/internal/screenshot.d.ts.map +1 -0
- package/dist/beacon/types/internal/selector.d.ts.map +1 -0
- package/dist/beacon/types/plugins/domEle.d.ts +14 -0
- package/dist/beacon/types/plugins/domEle.d.ts.map +1 -0
- package/dist/beacon/types/plugins/domSS.d.ts +8 -0
- package/dist/beacon/types/plugins/domSS.d.ts.map +1 -0
- package/dist/beacon/types/plugins/errors.d.ts +3 -0
- package/dist/beacon/types/plugins/errors.d.ts.map +1 -0
- package/dist/beacon/types/plugins/index.d.ts +8 -0
- package/dist/beacon/types/plugins/index.d.ts.map +1 -0
- package/dist/beacon/types/plugins/liveMonitor.d.ts +14 -0
- package/dist/beacon/types/plugins/liveMonitor.d.ts.map +1 -0
- package/dist/beacon/types/plugins/metadata.d.ts +3 -0
- package/dist/beacon/types/plugins/metadata.d.ts.map +1 -0
- package/dist/beacon/types/registry.d.ts +33 -0
- package/dist/beacon/types/registry.d.ts.map +1 -0
- package/dist/beacon/types/styles.d.ts +8 -0
- package/dist/beacon/types/styles.d.ts.map +1 -0
- package/dist/beacon/types/transport.d.ts +3 -0
- package/dist/beacon/types/transport.d.ts.map +1 -0
- package/dist/beacon/types/types.d.ts +152 -68
- package/dist/beacon/types/types.d.ts.map +1 -1
- package/dist/beacon/types/ui/dialog.d.ts +53 -0
- package/dist/beacon/types/ui/dialog.d.ts.map +1 -0
- package/dist/beacon/types/ui/form.d.ts +7 -0
- package/dist/beacon/types/ui/form.d.ts.map +1 -0
- package/dist/beacon/types/ui/overlay.d.ts +6 -0
- package/dist/beacon/types/ui/overlay.d.ts.map +1 -0
- package/dist/chart-client/assets/{index-CJ4mgRRF.css → index-CDIhdgWg.css} +1 -1
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/{index-DI5qSR_w.css → index-CfW4n40I.css} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/council-client/assets/{index-C_-vAM9L.css → index-CZim6x1u.css} +1 -1
- package/dist/council-client/index.html +2 -2
- package/dist/deck-client/assets/{_baseUniq-W2JQDmje.js → _baseUniq-DdHaBFYO.js} +1 -1
- package/dist/deck-client/assets/{arc-DIBWAId9.js → arc-D98e_18X.js} +1 -1
- package/dist/deck-client/assets/{architectureDiagram-Q4EWVU46-CAIRMvJK.js → architectureDiagram-Q4EWVU46-DNFZzh-4.js} +1 -1
- package/dist/deck-client/assets/{blockDiagram-DXYQGD6D-BeNaNiOi.js → blockDiagram-DXYQGD6D-DeQvGUdX.js} +1 -1
- package/dist/deck-client/assets/{c4Diagram-AHTNJAMY-B9Ozi62h.js → c4Diagram-AHTNJAMY-B6ekZf1n.js} +1 -1
- package/dist/deck-client/assets/channel-DmR7Tyyt.js +1 -0
- package/dist/deck-client/assets/{chunk-4BX2VUAB-D7AZ47dt.js → chunk-4BX2VUAB-9aDWymq2.js} +1 -1
- package/dist/deck-client/assets/{chunk-4TB4RGXK-DnVnNPcI.js → chunk-4TB4RGXK-DtKQqaI7.js} +1 -1
- package/dist/deck-client/assets/{chunk-55IACEB6-UKYs-YNd.js → chunk-55IACEB6-COy9hEae.js} +1 -1
- package/dist/deck-client/assets/{chunk-EDXVE4YY-D43b-SKn.js → chunk-EDXVE4YY-D_f861An.js} +1 -1
- package/dist/deck-client/assets/{chunk-FMBD7UC4-QzBAoyyW.js → chunk-FMBD7UC4-CmuA5UKn.js} +1 -1
- package/dist/deck-client/assets/{chunk-OYMX7WX6-Cjif4r6W.js → chunk-OYMX7WX6-vT8z8D-0.js} +1 -1
- package/dist/deck-client/assets/{chunk-QZHKN3VN-CqLDirEI.js → chunk-QZHKN3VN-CTlwwg-R.js} +1 -1
- package/dist/deck-client/assets/{chunk-YZCP3GAM-_FQvmMs4.js → chunk-YZCP3GAM-C44yr620.js} +1 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-Bl4ozQWs.js +1 -0
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-Bl4ozQWs.js +1 -0
- package/dist/deck-client/assets/clone-BAy58j24.js +1 -0
- package/dist/deck-client/assets/{cose-bilkent-S5V4N54A-rfrocesE.js → cose-bilkent-S5V4N54A-DBB2J2nL.js} +1 -1
- package/dist/deck-client/assets/{dagre-KV5264BT-Bv_7DJat.js → dagre-KV5264BT-DxDTYbKl.js} +1 -1
- package/dist/deck-client/assets/{diagram-5BDNPKRD-4F1414G5.js → diagram-5BDNPKRD-DByWrWd1.js} +1 -1
- package/dist/deck-client/assets/{diagram-G4DWMVQ6-C4-Pszqm.js → diagram-G4DWMVQ6-B8B6ddMq.js} +1 -1
- package/dist/deck-client/assets/{diagram-MMDJMWI5-B647TIx9.js → diagram-MMDJMWI5-BMUZ2PWK.js} +1 -1
- package/dist/deck-client/assets/{diagram-TYMM5635-BFAqpezd.js → diagram-TYMM5635-Bk9e8BB-.js} +1 -1
- package/dist/deck-client/assets/{erDiagram-SMLLAGMA-BfBfrJOC.js → erDiagram-SMLLAGMA-DcOSwSol.js} +1 -1
- package/dist/deck-client/assets/{flowDiagram-DWJPFMVM-DX9YAYes.js → flowDiagram-DWJPFMVM-DI-4BR0F.js} +1 -1
- package/dist/deck-client/assets/{ganttDiagram-T4ZO3ILL-DCuiy7wF.js → ganttDiagram-T4ZO3ILL-BeZuXBoU.js} +1 -1
- package/dist/deck-client/assets/{gitGraphDiagram-UUTBAWPF-CGp1IXUh.js → gitGraphDiagram-UUTBAWPF-Bcki__f-.js} +1 -1
- package/dist/deck-client/assets/{graph-B7g8aoxv.js → graph-CifKx6G1.js} +1 -1
- package/dist/deck-client/assets/index-6sdqbm2o.js +2 -0
- package/dist/deck-client/assets/{index-DsIZ3LqL.css → index-BlTlhxFW.css} +1 -1
- package/dist/deck-client/assets/index-CB-qlwRT.js +1195 -0
- package/dist/deck-client/assets/{infoDiagram-42DDH7IO-L3fahMkF.js → infoDiagram-42DDH7IO-CReN1nFN.js} +1 -1
- package/dist/deck-client/assets/{ishikawaDiagram-UXIWVN3A-aS_EjWBZ.js → ishikawaDiagram-UXIWVN3A-CDF_VLN_.js} +1 -1
- package/dist/deck-client/assets/{journeyDiagram-VCZTEJTY-djTSQZF9.js → journeyDiagram-VCZTEJTY-DwgGrNVB.js} +1 -1
- package/dist/deck-client/assets/{kanban-definition-6JOO6SKY-CcTHo4CM.js → kanban-definition-6JOO6SKY-DB_zohh5.js} +1 -1
- package/dist/deck-client/assets/{layout-mEJiadb7.js → layout-DFfX1O3z.js} +1 -1
- package/dist/deck-client/assets/{linear-XgTKqyRu.js → linear-CtKb4EXj.js} +1 -1
- package/dist/deck-client/assets/{min-Ct9jZdpd.js → min-DCRRwUZv.js} +1 -1
- package/dist/deck-client/assets/{mindmap-definition-QFDTVHPH-BaFxCGNU.js → mindmap-definition-QFDTVHPH-D0QBOiFe.js} +1 -1
- package/dist/deck-client/assets/{pieDiagram-DEJITSTG-CIbYYjtw.js → pieDiagram-DEJITSTG-CD-EV5WB.js} +1 -1
- package/dist/deck-client/assets/{quadrantDiagram-34T5L4WZ-D9EtCOvh.js → quadrantDiagram-34T5L4WZ-B-JXZ8xI.js} +1 -1
- package/dist/deck-client/assets/{requirementDiagram-MS252O5E-xeni9eVG.js → requirementDiagram-MS252O5E-D2_OK5Dp.js} +1 -1
- package/dist/deck-client/assets/{sankeyDiagram-XADWPNL6-LYeknz9h.js → sankeyDiagram-XADWPNL6-BbBJqVSC.js} +1 -1
- package/dist/deck-client/assets/{sequenceDiagram-FGHM5R23-RDbsKFZf.js → sequenceDiagram-FGHM5R23-Db8A-Rkk.js} +1 -1
- package/dist/deck-client/assets/{stateDiagram-FHFEXIEX-BH1Zjglk.js → stateDiagram-FHFEXIEX-DGJnanjS.js} +1 -1
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-CR7riiab.js +1 -0
- package/dist/deck-client/assets/{timeline-definition-GMOUNBTQ-IFXxKptt.js → timeline-definition-GMOUNBTQ-BRkr6T4w.js} +1 -1
- package/dist/deck-client/assets/{vennDiagram-DHZGUBPP-D-sLkQs9.js → vennDiagram-DHZGUBPP-d0rsTqFo.js} +1 -1
- package/dist/deck-client/assets/{wardley-RL74JXVD-C010F8l4.js → wardley-RL74JXVD-2t7cMqdS.js} +1 -1
- package/dist/deck-client/assets/{wardleyDiagram-NUSXRM2D-BTjjuDU3.js → wardleyDiagram-NUSXRM2D-DzboAsHh.js} +1 -1
- package/dist/deck-client/assets/{xychartDiagram-5P7HB3ND-AYbv92n-.js → xychartDiagram-5P7HB3ND-CgTP9u2V.js} +1 -1
- package/dist/deck-client/index.html +2 -2
- package/dist/server/beacon-monitor-entry.js +548 -6
- package/dist/server/chart-serve.js +917 -248
- package/dist/server/cli.js +2033 -385
- package/dist/server/deck-mcp-entry.js +141 -21
- package/dist/server/deck-serve.js +141 -21
- package/dist/server/graph-mcp-entry.js +1991 -333
- package/dist/server/init-entry.js +24 -13
- package/dist/server/orbit-entry.js +135 -7
- package/dist/server/parse-worker-entry.js +918 -247
- package/package.json +4 -2
- package/scaffolds/ls-marketplace/plugins/kit/skills/analyse/SKILL.md +180 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-array/SKILL.md +107 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-clear/SKILL.md +94 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-pulse/SKILL.md +82 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/beacon-scan/SKILL.md +66 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/blast-radius/SKILL.md +117 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/brief/SKILL.md +112 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/course/SKILL.md +84 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/debug/SKILL.md +85 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check/SKILL.md +160 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/diagram/SKILL.md +152 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/orbit/SKILL.md +87 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/prototype/SKILL.md +110 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/recovery/SKILL.md +95 -0
- package/scaffolds/ls-marketplace/plugins/kit/{commands/show-mcp-status.md → skills/show-mcp-status/SKILL.md} +4 -4
- package/scaffolds/ls-marketplace/plugins/kit/skills/wireframe/SKILL.md +90 -0
- package/scaffolds/statusline/statusline-mcp.sh +21 -9
- package/dist/beacon/types/capture/element.d.ts +0 -3
- package/dist/beacon/types/capture/element.d.ts.map +0 -1
- package/dist/beacon/types/capture/events.d.ts +0 -20
- package/dist/beacon/types/capture/events.d.ts.map +0 -1
- package/dist/beacon/types/capture/framework.d.ts +0 -3
- package/dist/beacon/types/capture/framework.d.ts.map +0 -1
- package/dist/beacon/types/capture/metadata.d.ts +0 -3
- package/dist/beacon/types/capture/metadata.d.ts.map +0 -1
- package/dist/beacon/types/capture/overlay.d.ts +0 -7
- package/dist/beacon/types/capture/overlay.d.ts.map +0 -1
- package/dist/beacon/types/capture/picker.d.ts.map +0 -1
- package/dist/beacon/types/capture/screenshot.d.ts +0 -7
- package/dist/beacon/types/capture/screenshot.d.ts.map +0 -1
- package/dist/beacon/types/capture/selector.d.ts.map +0 -1
- package/dist/beacon/types/monitor/dom.d.ts +0 -13
- package/dist/beacon/types/monitor/dom.d.ts.map +0 -1
- package/dist/beacon/types/monitor/index.d.ts +0 -19
- package/dist/beacon/types/monitor/index.d.ts.map +0 -1
- package/dist/beacon/types/monitor/network.d.ts +0 -12
- package/dist/beacon/types/monitor/network.d.ts.map +0 -1
- package/dist/beacon/types/monitor/transport.d.ts.map +0 -1
- package/dist/beacon/types/monitor/types.d.ts.map +0 -1
- package/dist/beacon/types/transport/submit.d.ts +0 -3
- package/dist/beacon/types/transport/submit.d.ts.map +0 -1
- package/dist/beacon/types/ui/button.d.ts +0 -2
- package/dist/beacon/types/ui/button.d.ts.map +0 -1
- package/dist/beacon/types/ui/drawer.d.ts +0 -33
- package/dist/beacon/types/ui/drawer.d.ts.map +0 -1
- package/dist/beacon/types/ui/icons.d.ts +0 -9
- package/dist/beacon/types/ui/icons.d.ts.map +0 -1
- package/dist/beacon/types/ui/monitor-panel.d.ts +0 -19
- package/dist/beacon/types/ui/monitor-panel.d.ts.map +0 -1
- package/dist/beacon/types/ui/pick-mode-overlay.d.ts.map +0 -1
- package/dist/beacon/types/ui/pin-popover.d.ts.map +0 -1
- package/dist/deck-client/assets/channel-CRdozqbp.js +0 -1
- package/dist/deck-client/assets/classDiagram-6PBFFD2Q-lIZMp57W.js +0 -1
- package/dist/deck-client/assets/classDiagram-v2-HSJHXN6E-lIZMp57W.js +0 -1
- package/dist/deck-client/assets/clone-BtWeSTyJ.js +0 -1
- package/dist/deck-client/assets/index-Dg1r-WSN.js +0 -476
- package/dist/deck-client/assets/stateDiagram-v2-QKLJ7IA2-BrV78NDR.js +0 -1
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-array.md +0 -92
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-clear.md +0 -68
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-pulse.md +0 -80
- package/scaffolds/ls-marketplace/plugins/kit/commands/beacon-scan.md +0 -62
- /package/dist/beacon/types/{capture → internal}/selector.d.ts +0 -0
- /package/dist/chart-client/assets/{index-Ccy-DpI-.js → index-B__ARB8k.js} +0 -0
- /package/dist/client/assets/{index-Dp0_okva.js → index-h8kMzVtG.js} +0 -0
- /package/dist/council-client/assets/{index-Dt4zWKSj.js → index-CWaDcsFR.js} +0 -0
|
@@ -1084,6 +1084,8 @@ function extractDeep(absPath) {
|
|
|
1084
1084
|
false
|
|
1085
1085
|
);
|
|
1086
1086
|
const hasEffects = Object.keys(fileEffects).length > 0;
|
|
1087
|
+
const uiLabels = collectUiLabels(root);
|
|
1088
|
+
const notes = collectNotes(root);
|
|
1087
1089
|
return {
|
|
1088
1090
|
elements,
|
|
1089
1091
|
stateVars,
|
|
@@ -1091,10 +1093,77 @@ function extractDeep(absPath) {
|
|
|
1091
1093
|
variables,
|
|
1092
1094
|
responses,
|
|
1093
1095
|
params,
|
|
1094
|
-
...hasEffects ? { effects: fileEffects } : {}
|
|
1096
|
+
...hasEffects ? { effects: fileEffects } : {},
|
|
1097
|
+
...uiLabels.length > 0 ? { ui_labels: uiLabels } : {},
|
|
1098
|
+
...notes.length > 0 ? { notes } : {}
|
|
1095
1099
|
};
|
|
1096
1100
|
}
|
|
1097
|
-
|
|
1101
|
+
function collectNotes(root) {
|
|
1102
|
+
const out = [];
|
|
1103
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1104
|
+
function visit(node) {
|
|
1105
|
+
if (out.length >= NOTES_MAX) return;
|
|
1106
|
+
if (node.type === "comment") {
|
|
1107
|
+
const text = node.text;
|
|
1108
|
+
const startRow = node.startPosition.row;
|
|
1109
|
+
NOTE_REGEX.lastIndex = 0;
|
|
1110
|
+
let m;
|
|
1111
|
+
while ((m = NOTE_REGEX.exec(text)) !== null) {
|
|
1112
|
+
const kind = m[1];
|
|
1113
|
+
const author = m[2];
|
|
1114
|
+
const body = m[3];
|
|
1115
|
+
if (!kind || !body) continue;
|
|
1116
|
+
const newlinesBefore = (text.slice(0, m.index).match(/\n/g) ?? []).length;
|
|
1117
|
+
const line = startRow + 1 + newlinesBefore;
|
|
1118
|
+
const key = `${line}:${kind}`;
|
|
1119
|
+
if (seen.has(key)) continue;
|
|
1120
|
+
seen.add(key);
|
|
1121
|
+
const note = {
|
|
1122
|
+
kind,
|
|
1123
|
+
text: body.length <= 200 ? body : body.slice(0, 200) + "...",
|
|
1124
|
+
line
|
|
1125
|
+
};
|
|
1126
|
+
if (author) note.author = author;
|
|
1127
|
+
out.push(note);
|
|
1128
|
+
if (out.length >= NOTES_MAX) return;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
for (const child of node.namedChildren) {
|
|
1132
|
+
visit(child);
|
|
1133
|
+
if (out.length >= NOTES_MAX) return;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
visit(root);
|
|
1137
|
+
return out;
|
|
1138
|
+
}
|
|
1139
|
+
function collectUiLabels(root) {
|
|
1140
|
+
const out = [];
|
|
1141
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1142
|
+
function visit(node) {
|
|
1143
|
+
if (out.length >= UI_LABELS_MAX) return;
|
|
1144
|
+
if (node.type === "pair") {
|
|
1145
|
+
const key = node.childForFieldName("key");
|
|
1146
|
+
const val = node.childForFieldName("value");
|
|
1147
|
+
if (key && val) {
|
|
1148
|
+
const keyText = key.type === "property_identifier" ? key.text : stringLiteralValue(key) ?? key.text;
|
|
1149
|
+
if (UI_LABEL_KEYS.has(keyText)) {
|
|
1150
|
+
const strVal = stringLiteralValue(val);
|
|
1151
|
+
if (strVal && strVal.length > 0 && strVal.length <= 200 && !seen.has(strVal)) {
|
|
1152
|
+
seen.add(strVal);
|
|
1153
|
+
out.push(strVal);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
for (const child of node.namedChildren) {
|
|
1159
|
+
visit(child);
|
|
1160
|
+
if (out.length >= UI_LABELS_MAX) return;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
visit(root);
|
|
1164
|
+
return out;
|
|
1165
|
+
}
|
|
1166
|
+
var import_node_fs11, import_node_path13, 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;
|
|
1098
1167
|
var init_ts_extractor = __esm({
|
|
1099
1168
|
"src/server/graph/core/ts-extractor.ts"() {
|
|
1100
1169
|
"use strict";
|
|
@@ -1213,6 +1282,27 @@ var init_ts_extractor = __esm({
|
|
|
1213
1282
|
"selected",
|
|
1214
1283
|
"disabled"
|
|
1215
1284
|
]);
|
|
1285
|
+
UI_LABEL_KEYS = /* @__PURE__ */ new Set([
|
|
1286
|
+
"label",
|
|
1287
|
+
"title",
|
|
1288
|
+
"name",
|
|
1289
|
+
"text",
|
|
1290
|
+
"description",
|
|
1291
|
+
"placeholder",
|
|
1292
|
+
"tooltip",
|
|
1293
|
+
"heading",
|
|
1294
|
+
"subheading",
|
|
1295
|
+
"sheetTitle",
|
|
1296
|
+
"sheetDescription",
|
|
1297
|
+
"caption",
|
|
1298
|
+
"cta",
|
|
1299
|
+
"buttonText",
|
|
1300
|
+
"emptyText",
|
|
1301
|
+
"subtitle"
|
|
1302
|
+
]);
|
|
1303
|
+
UI_LABELS_MAX = 200;
|
|
1304
|
+
NOTE_REGEX = /^\s*(?:\/\/|\/\*+|\*)\s*([A-Z][A-Z0-9_]{1,15})(?:\(([^)]+)\))?:\s*(\S.*?)\s*(?:\*\/)?$/gm;
|
|
1305
|
+
NOTES_MAX = 100;
|
|
1216
1306
|
}
|
|
1217
1307
|
});
|
|
1218
1308
|
|
|
@@ -1936,7 +2026,7 @@ var NON_LAYER_GRAPH_FILES = /* @__PURE__ */ new Set(["tags.json", "effects-index
|
|
|
1936
2026
|
function getAvailableLayers(rootDir) {
|
|
1937
2027
|
const dir = (0, import_node_path9.join)(rootDir, GRAPHS_DIR2);
|
|
1938
2028
|
if (!(0, import_node_fs7.existsSync)(dir)) return [];
|
|
1939
|
-
return (0, import_node_fs7.readdirSync)(dir).filter((f) => f.endsWith(".json") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
|
|
2029
|
+
return (0, import_node_fs7.readdirSync)(dir).filter((f) => f.endsWith(".json") && !f.startsWith(".") && !NON_LAYER_GRAPH_FILES.has(f)).map((f) => f.replace(".json", ""));
|
|
1940
2030
|
}
|
|
1941
2031
|
var graphCache = /* @__PURE__ */ new Map();
|
|
1942
2032
|
var taggedCache = /* @__PURE__ */ new Map();
|
|
@@ -2832,6 +2922,7 @@ function generate(rootDir) {
|
|
|
2832
2922
|
responses: deep.responses,
|
|
2833
2923
|
params: deep.params,
|
|
2834
2924
|
...deep.effects ? { effects: deep.effects } : {},
|
|
2925
|
+
...deep.notes ? { notes: deep.notes } : {},
|
|
2835
2926
|
_dbCalls: dbCalls
|
|
2836
2927
|
// temp: used for cross-ref building below
|
|
2837
2928
|
});
|
|
@@ -2852,6 +2943,8 @@ function generate(rootDir) {
|
|
|
2852
2943
|
conditions: deep.conditions,
|
|
2853
2944
|
variables: deep.variables,
|
|
2854
2945
|
...deep.effects ? { effects: deep.effects } : {},
|
|
2946
|
+
...deep.ui_labels ? { ui_labels: deep.ui_labels } : {},
|
|
2947
|
+
...deep.notes ? { notes: deep.notes } : {},
|
|
2855
2948
|
...authWrappers.length > 0 ? { auth: authWrappers } : {},
|
|
2856
2949
|
...dbCalls.length > 0 ? { _dbCalls: dbCalls } : {}
|
|
2857
2950
|
});
|
|
@@ -3453,6 +3546,7 @@ var prismaSchemaParser = {
|
|
|
3453
3546
|
// src/server/graph/parsers/db/sql-migrations.ts
|
|
3454
3547
|
var import_node_fs14 = require("node:fs");
|
|
3455
3548
|
var import_node_path15 = require("node:path");
|
|
3549
|
+
var import_pgsql_parser = require("pgsql-parser");
|
|
3456
3550
|
init_config();
|
|
3457
3551
|
var PG_TO_PRISMA = {
|
|
3458
3552
|
"TEXT": "String",
|
|
@@ -3484,243 +3578,6 @@ function pgTypeToPrisma(pgType) {
|
|
|
3484
3578
|
const upper = pgType.toUpperCase().trim();
|
|
3485
3579
|
return PG_TO_PRISMA[upper] ?? upper;
|
|
3486
3580
|
}
|
|
3487
|
-
var ID = `(?:"[\\w$]+"|[\\w$]+)`;
|
|
3488
|
-
var QID = `(?:${ID}\\.)?${ID}`;
|
|
3489
|
-
function bareName(captured) {
|
|
3490
|
-
const parts = captured.split(".");
|
|
3491
|
-
const last = parts[parts.length - 1];
|
|
3492
|
-
return last.replace(/^"(.*)"$/, "$1").trim();
|
|
3493
|
-
}
|
|
3494
|
-
function parseCreateTable(sql, state) {
|
|
3495
|
-
const re = new RegExp(
|
|
3496
|
-
`CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${QID})\\s*\\(([\\s\\S]*?)\\);`,
|
|
3497
|
-
"gi"
|
|
3498
|
-
);
|
|
3499
|
-
let m;
|
|
3500
|
-
while ((m = re.exec(sql)) !== null) {
|
|
3501
|
-
const tableName = bareName(m[1]);
|
|
3502
|
-
const body = m[2];
|
|
3503
|
-
const columns = /* @__PURE__ */ new Map();
|
|
3504
|
-
let primaryCol = null;
|
|
3505
|
-
const inlineFks = [];
|
|
3506
|
-
const lines = splitTopLevelCommas(body);
|
|
3507
|
-
for (const raw of lines) {
|
|
3508
|
-
const trimmed = raw.trim().replace(/,\s*$/, "");
|
|
3509
|
-
if (!trimmed || trimmed.startsWith("--")) continue;
|
|
3510
|
-
const namedPk = trimmed.match(new RegExp(`^CONSTRAINT\\s+${ID}\\s+PRIMARY\\s+KEY\\s*\\(\\s*(${QID})`, "i"));
|
|
3511
|
-
if (namedPk) {
|
|
3512
|
-
primaryCol = bareName(namedPk[1]);
|
|
3513
|
-
continue;
|
|
3514
|
-
}
|
|
3515
|
-
const tablePk = trimmed.match(new RegExp(`^PRIMARY\\s+KEY\\s*\\(\\s*(${QID})`, "i"));
|
|
3516
|
-
if (tablePk) {
|
|
3517
|
-
primaryCol = bareName(tablePk[1]);
|
|
3518
|
-
continue;
|
|
3519
|
-
}
|
|
3520
|
-
if (/^UNIQUE\s*\(/i.test(trimmed)) continue;
|
|
3521
|
-
const namedFk = trimmed.match(new RegExp(
|
|
3522
|
-
`^CONSTRAINT\\s+(${ID})\\s+FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
|
|
3523
|
-
"i"
|
|
3524
|
-
));
|
|
3525
|
-
if (namedFk) {
|
|
3526
|
-
inlineFks.push({
|
|
3527
|
-
constraintName: bareName(namedFk[1]),
|
|
3528
|
-
sourceTable: tableName,
|
|
3529
|
-
sourceColumn: bareName(namedFk[2]),
|
|
3530
|
-
targetTable: bareName(namedFk[3]),
|
|
3531
|
-
targetColumn: bareName(namedFk[4]),
|
|
3532
|
-
onDelete: namedFk[5] ?? null
|
|
3533
|
-
});
|
|
3534
|
-
continue;
|
|
3535
|
-
}
|
|
3536
|
-
const bareFk = trimmed.match(new RegExp(
|
|
3537
|
-
`^FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
|
|
3538
|
-
"i"
|
|
3539
|
-
));
|
|
3540
|
-
if (bareFk) {
|
|
3541
|
-
inlineFks.push({
|
|
3542
|
-
constraintName: `${tableName}_${bareName(bareFk[1])}_fkey`,
|
|
3543
|
-
sourceTable: tableName,
|
|
3544
|
-
sourceColumn: bareName(bareFk[1]),
|
|
3545
|
-
targetTable: bareName(bareFk[2]),
|
|
3546
|
-
targetColumn: bareName(bareFk[3]),
|
|
3547
|
-
onDelete: bareFk[4] ?? null
|
|
3548
|
-
});
|
|
3549
|
-
continue;
|
|
3550
|
-
}
|
|
3551
|
-
if (/^CONSTRAINT\s/i.test(trimmed)) continue;
|
|
3552
|
-
const colMatch = trimmed.match(new RegExp(`^(${ID})\\s+(.+)`, "i"));
|
|
3553
|
-
if (!colMatch) continue;
|
|
3554
|
-
const colName = bareName(colMatch[1]);
|
|
3555
|
-
let rest = colMatch[2];
|
|
3556
|
-
const inlineRefMatch = rest.match(new RegExp(
|
|
3557
|
-
`\\bREFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
|
|
3558
|
-
"i"
|
|
3559
|
-
));
|
|
3560
|
-
if (inlineRefMatch) {
|
|
3561
|
-
inlineFks.push({
|
|
3562
|
-
constraintName: `${tableName}_${colName}_fkey`,
|
|
3563
|
-
sourceTable: tableName,
|
|
3564
|
-
sourceColumn: colName,
|
|
3565
|
-
targetTable: bareName(inlineRefMatch[1]),
|
|
3566
|
-
targetColumn: bareName(inlineRefMatch[2]),
|
|
3567
|
-
onDelete: inlineRefMatch[3] ?? null
|
|
3568
|
-
});
|
|
3569
|
-
rest = rest.replace(inlineRefMatch[0], "").trim();
|
|
3570
|
-
}
|
|
3571
|
-
const isNotNull = /\bNOT\s+NULL\b/i.test(rest);
|
|
3572
|
-
const isPrimaryKey = /\bPRIMARY\s+KEY\b/i.test(rest);
|
|
3573
|
-
const isUnique = /\bUNIQUE\b/i.test(rest);
|
|
3574
|
-
const defaultMatch = rest.match(/\bDEFAULT\s+(.+?)(?:\s*,?\s*$)/i);
|
|
3575
|
-
const defaultVal = defaultMatch ? defaultMatch[1].trim() : null;
|
|
3576
|
-
let colType = rest.replace(/\bNOT\s+NULL\b/gi, "").replace(/\bPRIMARY\s+KEY\b/gi, "").replace(/\bUNIQUE\b/gi, "").replace(/\bDEFAULT\s+.*/gi, "").trim().replace(/,\s*$/, "").trim();
|
|
3577
|
-
columns.set(colName, {
|
|
3578
|
-
name: colName,
|
|
3579
|
-
type: colType,
|
|
3580
|
-
nullable: !isNotNull && !isPrimaryKey,
|
|
3581
|
-
primary: isPrimaryKey,
|
|
3582
|
-
unique: isUnique,
|
|
3583
|
-
default: defaultVal
|
|
3584
|
-
});
|
|
3585
|
-
if (isPrimaryKey) primaryCol = colName;
|
|
3586
|
-
}
|
|
3587
|
-
if (primaryCol && columns.has(primaryCol)) {
|
|
3588
|
-
columns.get(primaryCol).primary = true;
|
|
3589
|
-
}
|
|
3590
|
-
state.tables.set(tableName, { name: tableName, columns });
|
|
3591
|
-
state.fks.push(...inlineFks);
|
|
3592
|
-
}
|
|
3593
|
-
}
|
|
3594
|
-
function splitTopLevelCommas(body) {
|
|
3595
|
-
const out = [];
|
|
3596
|
-
let depth = 0;
|
|
3597
|
-
let buf = "";
|
|
3598
|
-
let inString = null;
|
|
3599
|
-
for (const ch of body) {
|
|
3600
|
-
if (inString) {
|
|
3601
|
-
buf += ch;
|
|
3602
|
-
if (ch === inString) inString = null;
|
|
3603
|
-
continue;
|
|
3604
|
-
}
|
|
3605
|
-
if (ch === "'" || ch === '"') {
|
|
3606
|
-
inString = ch;
|
|
3607
|
-
buf += ch;
|
|
3608
|
-
continue;
|
|
3609
|
-
}
|
|
3610
|
-
if (ch === "(") depth++;
|
|
3611
|
-
else if (ch === ")") depth--;
|
|
3612
|
-
if (ch === "," && depth === 0) {
|
|
3613
|
-
out.push(buf);
|
|
3614
|
-
buf = "";
|
|
3615
|
-
continue;
|
|
3616
|
-
}
|
|
3617
|
-
buf += ch;
|
|
3618
|
-
}
|
|
3619
|
-
if (buf.trim()) out.push(buf);
|
|
3620
|
-
return out;
|
|
3621
|
-
}
|
|
3622
|
-
function parseCreateEnum(sql, state) {
|
|
3623
|
-
const re = new RegExp(
|
|
3624
|
-
`CREATE\\s+TYPE\\s+(${QID})\\s+AS\\s+ENUM\\s*\\(([^)]+)\\)`,
|
|
3625
|
-
"gi"
|
|
3626
|
-
);
|
|
3627
|
-
let m;
|
|
3628
|
-
while ((m = re.exec(sql)) !== null) {
|
|
3629
|
-
const enumName = bareName(m[1]);
|
|
3630
|
-
const valuesStr = m[2];
|
|
3631
|
-
const values = new Set(
|
|
3632
|
-
valuesStr.split(",").map((v) => v.trim().replace(/^'(.*)'$/, "$1")).filter(Boolean)
|
|
3633
|
-
);
|
|
3634
|
-
state.enums.set(enumName, { name: enumName, values });
|
|
3635
|
-
}
|
|
3636
|
-
}
|
|
3637
|
-
function parseAlterTable(sql, state) {
|
|
3638
|
-
const addColRe = new RegExp(
|
|
3639
|
-
`ALTER\\s+TABLE\\s+(${QID})\\s+ADD\\s+COLUMN\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${QID})\\s+(.+?);`,
|
|
3640
|
-
"gi"
|
|
3641
|
-
);
|
|
3642
|
-
let m;
|
|
3643
|
-
while ((m = addColRe.exec(sql)) !== null) {
|
|
3644
|
-
const tableName = bareName(m[1]);
|
|
3645
|
-
const colName = bareName(m[2]);
|
|
3646
|
-
let rest = m[3];
|
|
3647
|
-
const table = state.tables.get(tableName);
|
|
3648
|
-
if (!table) continue;
|
|
3649
|
-
const isNotNull = /\bNOT\s+NULL\b/i.test(rest);
|
|
3650
|
-
const defaultMatch = rest.match(/\bDEFAULT\s+(.+?)$/i);
|
|
3651
|
-
const defaultVal = defaultMatch ? defaultMatch[1].trim() : null;
|
|
3652
|
-
let colType = rest.replace(/\bNOT\s+NULL\b/gi, "").replace(/\bDEFAULT\s+.*/gi, "").trim();
|
|
3653
|
-
table.columns.set(colName, {
|
|
3654
|
-
name: colName,
|
|
3655
|
-
type: colType,
|
|
3656
|
-
nullable: !isNotNull,
|
|
3657
|
-
primary: false,
|
|
3658
|
-
unique: false,
|
|
3659
|
-
default: defaultVal
|
|
3660
|
-
});
|
|
3661
|
-
}
|
|
3662
|
-
const dropColRe = new RegExp(
|
|
3663
|
-
`ALTER\\s+TABLE\\s+(${QID})\\s+DROP\\s+COLUMN\\s+(?:IF\\s+EXISTS\\s+)?(${QID})`,
|
|
3664
|
-
"gi"
|
|
3665
|
-
);
|
|
3666
|
-
while ((m = dropColRe.exec(sql)) !== null) {
|
|
3667
|
-
const table = state.tables.get(bareName(m[1]));
|
|
3668
|
-
if (table) table.columns.delete(bareName(m[2]));
|
|
3669
|
-
}
|
|
3670
|
-
const fkRe = new RegExp(
|
|
3671
|
-
`ALTER\\s+TABLE\\s+(${QID})\\s+ADD\\s+CONSTRAINT\\s+(${ID})\\s+FOREIGN\\s+KEY\\s*\\(\\s*(${QID})\\s*\\)\\s+REFERENCES\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)(?:\\s+ON\\s+DELETE\\s+(\\w+(?:\\s+\\w+)?))?`,
|
|
3672
|
-
"gi"
|
|
3673
|
-
);
|
|
3674
|
-
while ((m = fkRe.exec(sql)) !== null) {
|
|
3675
|
-
state.fks.push({
|
|
3676
|
-
constraintName: bareName(m[2]),
|
|
3677
|
-
sourceTable: bareName(m[1]),
|
|
3678
|
-
sourceColumn: bareName(m[3]),
|
|
3679
|
-
targetTable: bareName(m[4]),
|
|
3680
|
-
targetColumn: bareName(m[5]),
|
|
3681
|
-
onDelete: m[6] ?? null
|
|
3682
|
-
});
|
|
3683
|
-
}
|
|
3684
|
-
}
|
|
3685
|
-
function parseAlterEnum(sql, state) {
|
|
3686
|
-
const re = new RegExp(
|
|
3687
|
-
`ALTER\\s+TYPE\\s+(${QID})\\s+ADD\\s+VALUE\\s+'([^']+)'`,
|
|
3688
|
-
"gi"
|
|
3689
|
-
);
|
|
3690
|
-
let m;
|
|
3691
|
-
while ((m = re.exec(sql)) !== null) {
|
|
3692
|
-
const en = state.enums.get(bareName(m[1]));
|
|
3693
|
-
if (en) en.values.add(m[2]);
|
|
3694
|
-
}
|
|
3695
|
-
}
|
|
3696
|
-
function parseDropTable(sql, state) {
|
|
3697
|
-
const re = new RegExp(
|
|
3698
|
-
`DROP\\s+TABLE\\s+(?:IF\\s+EXISTS\\s+)?(${QID})`,
|
|
3699
|
-
"gi"
|
|
3700
|
-
);
|
|
3701
|
-
let m;
|
|
3702
|
-
while ((m = re.exec(sql)) !== null) {
|
|
3703
|
-
const dropped = bareName(m[1]);
|
|
3704
|
-
state.tables.delete(dropped);
|
|
3705
|
-
state.fks = state.fks.filter((fk) => fk.sourceTable !== dropped && fk.targetTable !== dropped);
|
|
3706
|
-
}
|
|
3707
|
-
}
|
|
3708
|
-
function parseUniqueIndex(sql, state) {
|
|
3709
|
-
const re = new RegExp(
|
|
3710
|
-
`CREATE\\s+UNIQUE\\s+INDEX\\s+(?:(?:IF\\s+NOT\\s+EXISTS\\s+)?(?:${ID}\\s+)?)?ON\\s+(${QID})\\s*\\(\\s*(${QID})\\s*\\)`,
|
|
3711
|
-
"gi"
|
|
3712
|
-
);
|
|
3713
|
-
let m;
|
|
3714
|
-
while ((m = re.exec(sql)) !== null) {
|
|
3715
|
-
const tableName = bareName(m[1]);
|
|
3716
|
-
const colName = bareName(m[2]);
|
|
3717
|
-
const table = state.tables.get(tableName);
|
|
3718
|
-
const col = table?.columns.get(colName);
|
|
3719
|
-
if (col) col.unique = true;
|
|
3720
|
-
if (!state.uniqueIndexes.has(tableName)) state.uniqueIndexes.set(tableName, /* @__PURE__ */ new Set());
|
|
3721
|
-
state.uniqueIndexes.get(tableName).add(colName);
|
|
3722
|
-
}
|
|
3723
|
-
}
|
|
3724
3581
|
function discoverMigrationFiles(migrationsDir) {
|
|
3725
3582
|
if (!(0, import_node_fs14.existsSync)(migrationsDir)) return [];
|
|
3726
3583
|
const out = [];
|
|
@@ -3735,25 +3592,614 @@ function discoverMigrationFiles(migrationsDir) {
|
|
|
3735
3592
|
}
|
|
3736
3593
|
return out;
|
|
3737
3594
|
}
|
|
3738
|
-
|
|
3595
|
+
var postgresDialect = {
|
|
3596
|
+
parse(sql) {
|
|
3597
|
+
return (0, import_pgsql_parser.parseSync)(sql);
|
|
3598
|
+
},
|
|
3599
|
+
applyAll(ast, state, filepath) {
|
|
3600
|
+
const stmts = ast.stmts ?? [];
|
|
3601
|
+
extractTablesFromStmts(stmts, state);
|
|
3602
|
+
extractEnumsFromStmts(stmts, state);
|
|
3603
|
+
extractIndexesFromStmts(stmts, state, filepath);
|
|
3604
|
+
extractPoliciesFromStmts(stmts, state, filepath);
|
|
3605
|
+
extractExtensionsFromStmts(stmts, state, filepath);
|
|
3606
|
+
extractTriggersFromStmts(stmts, state, filepath);
|
|
3607
|
+
extractFunctionsFromStmts(stmts, state, filepath);
|
|
3608
|
+
extractViewsFromStmts(stmts, state, filepath);
|
|
3609
|
+
applyDropIndexes(stmts, state);
|
|
3610
|
+
applyDropPolicies(stmts, state);
|
|
3611
|
+
applyDropsForSchemaObjects(stmts, state);
|
|
3612
|
+
applyAstAlterEnums(stmts, state);
|
|
3613
|
+
applyAstAlterations(stmts, state);
|
|
3614
|
+
},
|
|
3615
|
+
extractMigrationInfo(ast, name, filepath) {
|
|
3616
|
+
const stmts = ast.stmts ?? [];
|
|
3617
|
+
return extractMigrationInfoFromStmts(stmts, name, filepath);
|
|
3618
|
+
}
|
|
3619
|
+
};
|
|
3620
|
+
function parseMigrations(migrationsDir, dialect = postgresDialect) {
|
|
3739
3621
|
const state = {
|
|
3740
3622
|
tables: /* @__PURE__ */ new Map(),
|
|
3741
3623
|
enums: /* @__PURE__ */ new Map(),
|
|
3742
3624
|
fks: [],
|
|
3743
|
-
uniqueIndexes: /* @__PURE__ */ new Map()
|
|
3625
|
+
uniqueIndexes: /* @__PURE__ */ new Map(),
|
|
3626
|
+
indexes: [],
|
|
3627
|
+
policies: [],
|
|
3628
|
+
extensions: [],
|
|
3629
|
+
triggers: [],
|
|
3630
|
+
functions: [],
|
|
3631
|
+
views: []
|
|
3744
3632
|
};
|
|
3745
3633
|
if (!migrationsDir) return state;
|
|
3746
3634
|
for (const sqlPath of discoverMigrationFiles(migrationsDir)) {
|
|
3747
3635
|
const sql = (0, import_node_fs14.readFileSync)(sqlPath, "utf-8");
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3636
|
+
let ast;
|
|
3637
|
+
try {
|
|
3638
|
+
ast = dialect.parse(sql);
|
|
3639
|
+
} catch {
|
|
3640
|
+
continue;
|
|
3641
|
+
}
|
|
3642
|
+
dialect.applyAll(ast, state, sqlPath);
|
|
3754
3643
|
}
|
|
3755
3644
|
return state;
|
|
3756
3645
|
}
|
|
3646
|
+
function extractIndexesFromStmts(stmts, state, filepath) {
|
|
3647
|
+
for (const wrap of stmts) {
|
|
3648
|
+
const stmt = wrap.stmt ?? {};
|
|
3649
|
+
const ix = stmt.IndexStmt;
|
|
3650
|
+
if (!ix) continue;
|
|
3651
|
+
const name = ix.idxname ?? "";
|
|
3652
|
+
if (!name) continue;
|
|
3653
|
+
const table = ix.relation?.relname ?? "";
|
|
3654
|
+
const unique = !!ix.unique;
|
|
3655
|
+
const method = String(ix.accessMethod ?? "btree").toLowerCase();
|
|
3656
|
+
const params = ix.indexParams ?? [];
|
|
3657
|
+
const columns = [];
|
|
3658
|
+
let hasExpressions = false;
|
|
3659
|
+
for (const p of params) {
|
|
3660
|
+
const elem = p.IndexElem;
|
|
3661
|
+
if (!elem) continue;
|
|
3662
|
+
if (elem.name) columns.push(elem.name);
|
|
3663
|
+
else if (elem.expr) hasExpressions = true;
|
|
3664
|
+
}
|
|
3665
|
+
const hasPredicate = !!ix.whereClause;
|
|
3666
|
+
const existing = state.indexes.findIndex((i) => i.name === name);
|
|
3667
|
+
const next = { name, table, unique, method, columns, hasExpressions, hasPredicate, filepath };
|
|
3668
|
+
if (existing >= 0) state.indexes[existing] = next;
|
|
3669
|
+
else state.indexes.push(next);
|
|
3670
|
+
if (unique && columns.length === 1 && !hasPredicate && !hasExpressions) {
|
|
3671
|
+
const t = state.tables.get(table);
|
|
3672
|
+
const col = t?.columns.get(columns[0]);
|
|
3673
|
+
if (col) col.unique = true;
|
|
3674
|
+
if (!state.uniqueIndexes.has(table)) state.uniqueIndexes.set(table, /* @__PURE__ */ new Set());
|
|
3675
|
+
state.uniqueIndexes.get(table).add(columns[0]);
|
|
3676
|
+
}
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
function applyDropIndexes(stmts, state) {
|
|
3680
|
+
for (const wrap of stmts) {
|
|
3681
|
+
const drop = wrap.stmt?.DropStmt;
|
|
3682
|
+
if (!drop || drop.removeType !== "OBJECT_INDEX") continue;
|
|
3683
|
+
const objects = drop.objects ?? [];
|
|
3684
|
+
const droppedNames = /* @__PURE__ */ new Set();
|
|
3685
|
+
for (const obj of objects) {
|
|
3686
|
+
const items = obj.List?.items ?? [];
|
|
3687
|
+
const last = items[items.length - 1]?.String?.sval;
|
|
3688
|
+
if (last) droppedNames.add(last);
|
|
3689
|
+
}
|
|
3690
|
+
if (droppedNames.size > 0) {
|
|
3691
|
+
state.indexes = state.indexes.filter((i) => !droppedNames.has(i.name));
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
function formatPgTypeName(typeName) {
|
|
3696
|
+
const names = (typeName?.names ?? []).map((n) => n.String?.sval ?? "").filter(Boolean);
|
|
3697
|
+
const base = (names[names.length - 1] ?? "").toLowerCase();
|
|
3698
|
+
const PG_INTERNAL_MAP = {
|
|
3699
|
+
int4: "INTEGER",
|
|
3700
|
+
int8: "BIGINT",
|
|
3701
|
+
int2: "SMALLINT",
|
|
3702
|
+
float8: "DOUBLE PRECISION",
|
|
3703
|
+
float4: "REAL",
|
|
3704
|
+
bool: "BOOLEAN",
|
|
3705
|
+
bpchar: "CHAR",
|
|
3706
|
+
timestamptz: "TIMESTAMPTZ",
|
|
3707
|
+
timestamp: "TIMESTAMP",
|
|
3708
|
+
numeric: "NUMERIC",
|
|
3709
|
+
text: "TEXT",
|
|
3710
|
+
varchar: "VARCHAR",
|
|
3711
|
+
jsonb: "JSONB",
|
|
3712
|
+
json: "JSON",
|
|
3713
|
+
uuid: "UUID",
|
|
3714
|
+
date: "DATE",
|
|
3715
|
+
bytea: "BYTEA"
|
|
3716
|
+
};
|
|
3717
|
+
return PG_INTERNAL_MAP[base] ?? base.toUpperCase();
|
|
3718
|
+
}
|
|
3719
|
+
function applyAstAlterations(stmts, state) {
|
|
3720
|
+
for (const wrap of stmts) {
|
|
3721
|
+
const stmt = wrap.stmt ?? {};
|
|
3722
|
+
const kind = Object.keys(stmt)[0];
|
|
3723
|
+
if (!kind) continue;
|
|
3724
|
+
if (kind === "AlterTableStmt") {
|
|
3725
|
+
const body = stmt.AlterTableStmt;
|
|
3726
|
+
const tableName = body.relation?.relname ?? "";
|
|
3727
|
+
const table = state.tables.get(tableName);
|
|
3728
|
+
if (!table) continue;
|
|
3729
|
+
const cmds = body.cmds ?? [];
|
|
3730
|
+
for (const c of cmds) {
|
|
3731
|
+
const cmd = c.AlterTableCmd;
|
|
3732
|
+
if (!cmd) continue;
|
|
3733
|
+
const subtype = cmd.subtype ?? "";
|
|
3734
|
+
const colName = cmd.name ?? "";
|
|
3735
|
+
const col = colName ? table.columns.get(colName) : void 0;
|
|
3736
|
+
switch (subtype) {
|
|
3737
|
+
case "AT_AlterColumnType": {
|
|
3738
|
+
if (!col) break;
|
|
3739
|
+
const typeName = cmd.def?.ColumnDef?.typeName ?? cmd.def?.typeName;
|
|
3740
|
+
if (typeName) col.type = formatPgTypeNameWithMods(typeName);
|
|
3741
|
+
break;
|
|
3742
|
+
}
|
|
3743
|
+
case "AT_SetNotNull":
|
|
3744
|
+
if (col) col.nullable = false;
|
|
3745
|
+
break;
|
|
3746
|
+
case "AT_DropNotNull":
|
|
3747
|
+
if (col) col.nullable = true;
|
|
3748
|
+
break;
|
|
3749
|
+
case "AT_AddColumn": {
|
|
3750
|
+
const cd = cmd.def?.ColumnDef;
|
|
3751
|
+
if (!cd) break;
|
|
3752
|
+
const newColName = cd.colname ?? "";
|
|
3753
|
+
if (!newColName) break;
|
|
3754
|
+
if (table.columns.has(newColName)) break;
|
|
3755
|
+
let nullable = true;
|
|
3756
|
+
let primary = false;
|
|
3757
|
+
let unique = false;
|
|
3758
|
+
let defaultVal = null;
|
|
3759
|
+
for (const c2 of cd.constraints ?? []) {
|
|
3760
|
+
const ct = c2.Constraint;
|
|
3761
|
+
if (!ct) continue;
|
|
3762
|
+
if (ct.contype === "CONSTR_NOTNULL") nullable = false;
|
|
3763
|
+
else if (ct.contype === "CONSTR_PRIMARY") {
|
|
3764
|
+
primary = true;
|
|
3765
|
+
nullable = false;
|
|
3766
|
+
} else if (ct.contype === "CONSTR_UNIQUE") unique = true;
|
|
3767
|
+
else if (ct.contype === "CONSTR_DEFAULT") defaultVal = "<expr>";
|
|
3768
|
+
}
|
|
3769
|
+
table.columns.set(newColName, {
|
|
3770
|
+
name: newColName,
|
|
3771
|
+
type: formatPgTypeNameWithMods(cd.typeName),
|
|
3772
|
+
nullable,
|
|
3773
|
+
primary,
|
|
3774
|
+
unique,
|
|
3775
|
+
default: defaultVal
|
|
3776
|
+
});
|
|
3777
|
+
break;
|
|
3778
|
+
}
|
|
3779
|
+
case "AT_DropColumn":
|
|
3780
|
+
if (colName) table.columns.delete(colName);
|
|
3781
|
+
break;
|
|
3782
|
+
case "AT_AddConstraint": {
|
|
3783
|
+
const ct = cmd.def?.Constraint;
|
|
3784
|
+
if (!ct) break;
|
|
3785
|
+
if (ct.contype !== "CONSTR_FOREIGN") break;
|
|
3786
|
+
const fkCols = (ct.fk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
3787
|
+
const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
3788
|
+
const pkTable = ct.pktable?.relname ?? "";
|
|
3789
|
+
if (fkCols.length && pkCols.length && pkTable) {
|
|
3790
|
+
state.fks.push({
|
|
3791
|
+
constraintName: ct.conname || `${tableName}_${fkCols[0]}_fkey`,
|
|
3792
|
+
sourceTable: tableName,
|
|
3793
|
+
sourceColumn: fkCols[0],
|
|
3794
|
+
targetTable: pkTable,
|
|
3795
|
+
targetColumn: pkCols[0],
|
|
3796
|
+
onDelete: mapFkAction(ct.fk_del_action)
|
|
3797
|
+
});
|
|
3798
|
+
}
|
|
3799
|
+
break;
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
} else if (kind === "RenameStmt") {
|
|
3804
|
+
const body = stmt.RenameStmt;
|
|
3805
|
+
const renameType = body.renameType ?? "";
|
|
3806
|
+
const newName = body.newname ?? "";
|
|
3807
|
+
if (renameType === "OBJECT_COLUMN") {
|
|
3808
|
+
const tableName = body.relation?.relname ?? "";
|
|
3809
|
+
const oldName = body.subname ?? "";
|
|
3810
|
+
const table = state.tables.get(tableName);
|
|
3811
|
+
if (!table || !oldName || !newName) continue;
|
|
3812
|
+
const col = table.columns.get(oldName);
|
|
3813
|
+
if (col) {
|
|
3814
|
+
col.name = newName;
|
|
3815
|
+
table.columns.delete(oldName);
|
|
3816
|
+
table.columns.set(newName, col);
|
|
3817
|
+
}
|
|
3818
|
+
} else if (renameType === "OBJECT_TABLE") {
|
|
3819
|
+
const oldName = body.relation?.relname ?? "";
|
|
3820
|
+
if (!oldName || !newName) continue;
|
|
3821
|
+
const t = state.tables.get(oldName);
|
|
3822
|
+
if (!t) continue;
|
|
3823
|
+
state.tables.delete(oldName);
|
|
3824
|
+
t.name = newName;
|
|
3825
|
+
state.tables.set(newName, t);
|
|
3826
|
+
for (const fk of state.fks) {
|
|
3827
|
+
if (fk.sourceTable === oldName) fk.sourceTable = newName;
|
|
3828
|
+
if (fk.targetTable === oldName) fk.targetTable = newName;
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3834
|
+
function extractPoliciesFromStmts(stmts, state, filepath) {
|
|
3835
|
+
for (const wrap of stmts) {
|
|
3836
|
+
const body = wrap.stmt?.CreatePolicyStmt;
|
|
3837
|
+
if (!body) continue;
|
|
3838
|
+
const name = body.policy_name ?? "";
|
|
3839
|
+
if (!name) continue;
|
|
3840
|
+
const table = body.table?.relname ?? "";
|
|
3841
|
+
const cmdRaw = String(body.cmd_name ?? "all").toUpperCase();
|
|
3842
|
+
const command = ["SELECT", "INSERT", "UPDATE", "DELETE", "ALL"].includes(cmdRaw) ? cmdRaw : "ALL";
|
|
3843
|
+
const permissive = body.permissive === true;
|
|
3844
|
+
const roles = (body.roles ?? []).map((r) => {
|
|
3845
|
+
const rs = r.RoleSpec;
|
|
3846
|
+
if (!rs) return "";
|
|
3847
|
+
if (rs.roletype === "ROLESPEC_PUBLIC") return "public";
|
|
3848
|
+
if (rs.roletype === "ROLESPEC_CURRENT_USER") return "current_user";
|
|
3849
|
+
if (rs.roletype === "ROLESPEC_CSTRING" && rs.rolename) return rs.rolename;
|
|
3850
|
+
return "";
|
|
3851
|
+
}).filter(Boolean);
|
|
3852
|
+
const hasUsing = !!body.qual;
|
|
3853
|
+
const hasWithCheck = !!body.with_check;
|
|
3854
|
+
const existing = state.policies.findIndex((p) => p.table === table && p.name === name);
|
|
3855
|
+
const next = { name, table, command, permissive, roles, hasUsing, hasWithCheck, filepath };
|
|
3856
|
+
if (existing >= 0) state.policies[existing] = next;
|
|
3857
|
+
else state.policies.push(next);
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
function applyDropPolicies(stmts, state) {
|
|
3861
|
+
for (const wrap of stmts) {
|
|
3862
|
+
const drop = wrap.stmt?.DropStmt;
|
|
3863
|
+
if (!drop || drop.removeType !== "OBJECT_POLICY") continue;
|
|
3864
|
+
const objects = drop.objects ?? [];
|
|
3865
|
+
for (const obj of objects) {
|
|
3866
|
+
const items = obj.List?.items ?? [];
|
|
3867
|
+
if (items.length < 2) continue;
|
|
3868
|
+
const table = items[0]?.String?.sval ?? "";
|
|
3869
|
+
const policyName = items[items.length - 1]?.String?.sval ?? "";
|
|
3870
|
+
if (!table || !policyName) continue;
|
|
3871
|
+
state.policies = state.policies.filter((p) => !(p.table === table && p.name === policyName));
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
function mapFkAction(action) {
|
|
3876
|
+
if (!action) return null;
|
|
3877
|
+
const m = {
|
|
3878
|
+
r: "RESTRICT",
|
|
3879
|
+
c: "CASCADE",
|
|
3880
|
+
s: "SET NULL",
|
|
3881
|
+
d: "SET DEFAULT",
|
|
3882
|
+
a: "NO ACTION",
|
|
3883
|
+
// pgsql-parser may also emit FKCONSTR_ACTION_* enum strings:
|
|
3884
|
+
FKCONSTR_ACTION_RESTRICT: "RESTRICT",
|
|
3885
|
+
FKCONSTR_ACTION_CASCADE: "CASCADE",
|
|
3886
|
+
FKCONSTR_ACTION_SETNULL: "SET NULL",
|
|
3887
|
+
FKCONSTR_ACTION_SETDEFAULT: "SET DEFAULT",
|
|
3888
|
+
FKCONSTR_ACTION_NOACTION: "NO ACTION"
|
|
3889
|
+
};
|
|
3890
|
+
return m[action] ?? null;
|
|
3891
|
+
}
|
|
3892
|
+
function formatPgTypeNameWithMods(typeName) {
|
|
3893
|
+
const base = formatPgTypeName(typeName);
|
|
3894
|
+
if (base === "String" || base === "unknown") return base;
|
|
3895
|
+
const typmods = [];
|
|
3896
|
+
for (const m of typeName?.typmods ?? []) {
|
|
3897
|
+
const v = m.A_Const?.ival?.ival;
|
|
3898
|
+
if (typeof v === "number") typmods.push(v);
|
|
3899
|
+
}
|
|
3900
|
+
return typmods.length ? `${base}(${typmods.join(",")})` : base;
|
|
3901
|
+
}
|
|
3902
|
+
function extractTablesFromStmts(stmts, state) {
|
|
3903
|
+
for (const wrap of stmts) {
|
|
3904
|
+
const body = wrap.stmt?.CreateStmt;
|
|
3905
|
+
if (!body) continue;
|
|
3906
|
+
const tableName = body.relation?.relname ?? "";
|
|
3907
|
+
if (!tableName) continue;
|
|
3908
|
+
const columns = /* @__PURE__ */ new Map();
|
|
3909
|
+
const fks = [];
|
|
3910
|
+
let primaryCol = null;
|
|
3911
|
+
for (const elt of body.tableElts ?? []) {
|
|
3912
|
+
if (elt.ColumnDef) {
|
|
3913
|
+
const cd = elt.ColumnDef;
|
|
3914
|
+
const colName = cd.colname ?? "";
|
|
3915
|
+
if (!colName) continue;
|
|
3916
|
+
const colType = formatPgTypeNameWithMods(cd.typeName);
|
|
3917
|
+
let nullable = true;
|
|
3918
|
+
let primary = false;
|
|
3919
|
+
let unique = false;
|
|
3920
|
+
let defaultVal = null;
|
|
3921
|
+
for (const c of cd.constraints ?? []) {
|
|
3922
|
+
const ct = c.Constraint;
|
|
3923
|
+
if (!ct) continue;
|
|
3924
|
+
switch (ct.contype) {
|
|
3925
|
+
case "CONSTR_NOTNULL":
|
|
3926
|
+
nullable = false;
|
|
3927
|
+
break;
|
|
3928
|
+
case "CONSTR_PRIMARY":
|
|
3929
|
+
primary = true;
|
|
3930
|
+
nullable = false;
|
|
3931
|
+
primaryCol = colName;
|
|
3932
|
+
break;
|
|
3933
|
+
case "CONSTR_UNIQUE":
|
|
3934
|
+
unique = true;
|
|
3935
|
+
break;
|
|
3936
|
+
case "CONSTR_DEFAULT":
|
|
3937
|
+
defaultVal = "<expr>";
|
|
3938
|
+
break;
|
|
3939
|
+
case "CONSTR_FOREIGN": {
|
|
3940
|
+
const pkTable = ct.pktable?.relname ?? "";
|
|
3941
|
+
const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
3942
|
+
if (pkTable && pkCols.length) {
|
|
3943
|
+
fks.push({
|
|
3944
|
+
constraintName: ct.conname || `${tableName}_${colName}_fkey`,
|
|
3945
|
+
sourceTable: tableName,
|
|
3946
|
+
sourceColumn: colName,
|
|
3947
|
+
targetTable: pkTable,
|
|
3948
|
+
targetColumn: pkCols[0],
|
|
3949
|
+
onDelete: mapFkAction(ct.fk_del_action)
|
|
3950
|
+
});
|
|
3951
|
+
}
|
|
3952
|
+
break;
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
columns.set(colName, {
|
|
3957
|
+
name: colName,
|
|
3958
|
+
type: colType,
|
|
3959
|
+
nullable,
|
|
3960
|
+
primary,
|
|
3961
|
+
unique,
|
|
3962
|
+
default: defaultVal
|
|
3963
|
+
});
|
|
3964
|
+
} else if (elt.Constraint) {
|
|
3965
|
+
const ct = elt.Constraint;
|
|
3966
|
+
switch (ct.contype) {
|
|
3967
|
+
case "CONSTR_PRIMARY": {
|
|
3968
|
+
const keys = (ct.keys ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
3969
|
+
if (keys.length) primaryCol = keys[0];
|
|
3970
|
+
break;
|
|
3971
|
+
}
|
|
3972
|
+
case "CONSTR_FOREIGN": {
|
|
3973
|
+
const fkCols = (ct.fk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
3974
|
+
const pkCols = (ct.pk_attrs ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
3975
|
+
const pkTable = ct.pktable?.relname ?? "";
|
|
3976
|
+
if (fkCols.length && pkCols.length && pkTable) {
|
|
3977
|
+
fks.push({
|
|
3978
|
+
constraintName: ct.conname || `${tableName}_${fkCols[0]}_fkey`,
|
|
3979
|
+
sourceTable: tableName,
|
|
3980
|
+
sourceColumn: fkCols[0],
|
|
3981
|
+
targetTable: pkTable,
|
|
3982
|
+
targetColumn: pkCols[0],
|
|
3983
|
+
onDelete: mapFkAction(ct.fk_del_action)
|
|
3984
|
+
});
|
|
3985
|
+
}
|
|
3986
|
+
break;
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
if (primaryCol && columns.has(primaryCol)) {
|
|
3992
|
+
columns.get(primaryCol).primary = true;
|
|
3993
|
+
columns.get(primaryCol).nullable = false;
|
|
3994
|
+
}
|
|
3995
|
+
state.tables.set(tableName, { name: tableName, columns });
|
|
3996
|
+
state.fks.push(...fks);
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
function extractEnumsFromStmts(stmts, state) {
|
|
4000
|
+
for (const wrap of stmts) {
|
|
4001
|
+
const body = wrap.stmt?.CreateEnumStmt;
|
|
4002
|
+
if (!body) continue;
|
|
4003
|
+
const names = (body.typeName ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
4004
|
+
const enumName = names[names.length - 1] ?? "";
|
|
4005
|
+
if (!enumName) continue;
|
|
4006
|
+
const vals = new Set(
|
|
4007
|
+
(body.vals ?? []).map((s) => s.String?.sval ?? "").filter(Boolean)
|
|
4008
|
+
);
|
|
4009
|
+
state.enums.set(enumName, { name: enumName, values: vals });
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
function applyAstAlterEnums(stmts, state) {
|
|
4013
|
+
for (const wrap of stmts) {
|
|
4014
|
+
const body = wrap.stmt?.AlterEnumStmt;
|
|
4015
|
+
if (!body) continue;
|
|
4016
|
+
const names = (body.typeName ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
4017
|
+
const enumName = names[names.length - 1] ?? "";
|
|
4018
|
+
const en = state.enums.get(enumName);
|
|
4019
|
+
if (!en) continue;
|
|
4020
|
+
if (body.newVal) en.values.add(String(body.newVal));
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
function extractExtensionsFromStmts(stmts, state, filepath) {
|
|
4024
|
+
for (const wrap of stmts) {
|
|
4025
|
+
const body = wrap.stmt?.CreateExtensionStmt;
|
|
4026
|
+
if (!body) continue;
|
|
4027
|
+
const name = body.extname ?? "";
|
|
4028
|
+
if (!name) continue;
|
|
4029
|
+
let schema = null;
|
|
4030
|
+
let version = null;
|
|
4031
|
+
for (const opt of body.options ?? []) {
|
|
4032
|
+
const de = opt.DefElem;
|
|
4033
|
+
if (!de) continue;
|
|
4034
|
+
if (de.defname === "schema" && de.arg?.String?.sval) schema = de.arg.String.sval;
|
|
4035
|
+
else if (de.defname === "new_version" && de.arg?.String?.sval) version = de.arg.String.sval;
|
|
4036
|
+
}
|
|
4037
|
+
const next = { name, schema, version, filepath };
|
|
4038
|
+
const existing = state.extensions.findIndex((e) => e.name === name);
|
|
4039
|
+
if (existing >= 0) state.extensions[existing] = next;
|
|
4040
|
+
else state.extensions.push(next);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
function extractTriggersFromStmts(stmts, state, filepath) {
|
|
4044
|
+
for (const wrap of stmts) {
|
|
4045
|
+
const body = wrap.stmt?.CreateTrigStmt;
|
|
4046
|
+
if (!body) continue;
|
|
4047
|
+
const name = body.trigname ?? "";
|
|
4048
|
+
if (!name) continue;
|
|
4049
|
+
const table = body.relation?.relname ?? "";
|
|
4050
|
+
const timingVal = body.timing ?? 0;
|
|
4051
|
+
const eventsVal = body.events ?? 0;
|
|
4052
|
+
const timing = timingVal & 2 ? "BEFORE" : timingVal & 64 ? "INSTEAD OF" : "AFTER";
|
|
4053
|
+
const events = [];
|
|
4054
|
+
if (eventsVal & 4) events.push("INSERT");
|
|
4055
|
+
if (eventsVal & 8) events.push("DELETE");
|
|
4056
|
+
if (eventsVal & 16) events.push("UPDATE");
|
|
4057
|
+
if (eventsVal & 32) events.push("TRUNCATE");
|
|
4058
|
+
const funcname = body.funcname ?? [];
|
|
4059
|
+
const funcCall = funcname[funcname.length - 1]?.String?.sval ?? "";
|
|
4060
|
+
const forEach = body.row ? "ROW" : "STATEMENT";
|
|
4061
|
+
const hasWhen = !!body.whenClause;
|
|
4062
|
+
const next = { name, table, timing, events, function: funcCall, hasWhen, forEach, filepath };
|
|
4063
|
+
const existing = state.triggers.findIndex((t) => t.table === table && t.name === name);
|
|
4064
|
+
if (existing >= 0) state.triggers[existing] = next;
|
|
4065
|
+
else state.triggers.push(next);
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
4068
|
+
function functionIdFor(name, schema) {
|
|
4069
|
+
return schema ? `${schema}.${name}` : name;
|
|
4070
|
+
}
|
|
4071
|
+
function extractFunctionsFromStmts(stmts, state, filepath) {
|
|
4072
|
+
for (const wrap of stmts) {
|
|
4073
|
+
const body = wrap.stmt?.CreateFunctionStmt;
|
|
4074
|
+
if (!body) continue;
|
|
4075
|
+
const fn = body.funcname ?? [];
|
|
4076
|
+
if (fn.length === 0) continue;
|
|
4077
|
+
const name = fn[fn.length - 1]?.String?.sval ?? "";
|
|
4078
|
+
if (!name) continue;
|
|
4079
|
+
const schema = fn.length > 1 ? fn[fn.length - 2]?.String?.sval ?? null : null;
|
|
4080
|
+
let language = "sql";
|
|
4081
|
+
for (const opt of body.options ?? []) {
|
|
4082
|
+
const de = opt.DefElem;
|
|
4083
|
+
if (de?.defname === "language" && de.arg?.String?.sval) language = de.arg.String.sval;
|
|
4084
|
+
}
|
|
4085
|
+
const returnType = body.returnType ? formatPgTypeName(body.returnType) : "";
|
|
4086
|
+
const isProcedure = !!body.is_procedure;
|
|
4087
|
+
const next = { name, schema, language, returnType, isProcedure, filepath };
|
|
4088
|
+
const id = functionIdFor(name, schema);
|
|
4089
|
+
const existing = state.functions.findIndex((f) => functionIdFor(f.name, f.schema) === id);
|
|
4090
|
+
if (existing >= 0) state.functions[existing] = next;
|
|
4091
|
+
else state.functions.push(next);
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
function extractViewsFromStmts(stmts, state, filepath) {
|
|
4095
|
+
for (const wrap of stmts) {
|
|
4096
|
+
const stmt = wrap.stmt ?? {};
|
|
4097
|
+
const view = stmt.ViewStmt;
|
|
4098
|
+
if (view) {
|
|
4099
|
+
const name = view.view?.relname ?? "";
|
|
4100
|
+
if (!name) continue;
|
|
4101
|
+
const schema = view.view?.schemaname ?? null;
|
|
4102
|
+
const next = {
|
|
4103
|
+
name,
|
|
4104
|
+
schema,
|
|
4105
|
+
isMaterialized: false,
|
|
4106
|
+
withCheckOption: String(view.withCheckOption ?? "NO_CHECK_OPTION"),
|
|
4107
|
+
filepath
|
|
4108
|
+
};
|
|
4109
|
+
const id = functionIdFor(name, schema);
|
|
4110
|
+
const existing = state.views.findIndex((v) => functionIdFor(v.name, v.schema) === id);
|
|
4111
|
+
if (existing >= 0) state.views[existing] = next;
|
|
4112
|
+
else state.views.push(next);
|
|
4113
|
+
}
|
|
4114
|
+
const ctas = stmt.CreateTableAsStmt;
|
|
4115
|
+
if (ctas && ctas.objtype === "OBJECT_MATVIEW") {
|
|
4116
|
+
const name = ctas.into?.rel?.relname ?? "";
|
|
4117
|
+
if (!name) continue;
|
|
4118
|
+
const schema = ctas.into?.rel?.schemaname ?? null;
|
|
4119
|
+
const next = {
|
|
4120
|
+
name,
|
|
4121
|
+
schema,
|
|
4122
|
+
isMaterialized: true,
|
|
4123
|
+
withCheckOption: "N/A",
|
|
4124
|
+
filepath
|
|
4125
|
+
};
|
|
4126
|
+
const id = functionIdFor(name, schema);
|
|
4127
|
+
const existing = state.views.findIndex((v) => functionIdFor(v.name, v.schema) === id);
|
|
4128
|
+
if (existing >= 0) state.views[existing] = next;
|
|
4129
|
+
else state.views.push(next);
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
function applyDropsForSchemaObjects(stmts, state) {
|
|
4134
|
+
for (const wrap of stmts) {
|
|
4135
|
+
const drop = wrap.stmt?.DropStmt;
|
|
4136
|
+
if (!drop) continue;
|
|
4137
|
+
const removeType = drop.removeType ?? "";
|
|
4138
|
+
const objects = drop.objects ?? [];
|
|
4139
|
+
if (removeType === "OBJECT_TABLE") {
|
|
4140
|
+
const droppedTables = /* @__PURE__ */ new Set();
|
|
4141
|
+
for (const obj of objects) {
|
|
4142
|
+
const items = obj.List?.items ?? [];
|
|
4143
|
+
const last = items[items.length - 1]?.String?.sval;
|
|
4144
|
+
if (last) droppedTables.add(last);
|
|
4145
|
+
}
|
|
4146
|
+
if (droppedTables.size > 0) {
|
|
4147
|
+
for (const t of droppedTables) state.tables.delete(t);
|
|
4148
|
+
state.fks = state.fks.filter((fk) => !droppedTables.has(fk.sourceTable) && !droppedTables.has(fk.targetTable));
|
|
4149
|
+
}
|
|
4150
|
+
} else if (removeType === "OBJECT_TYPE") {
|
|
4151
|
+
const droppedEnums = /* @__PURE__ */ new Set();
|
|
4152
|
+
for (const obj of objects) {
|
|
4153
|
+
const tn = obj.TypeName;
|
|
4154
|
+
if (!tn) continue;
|
|
4155
|
+
const names = (tn.names ?? []).map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
4156
|
+
const last = names[names.length - 1];
|
|
4157
|
+
if (last) droppedEnums.add(last);
|
|
4158
|
+
}
|
|
4159
|
+
for (const e of droppedEnums) state.enums.delete(e);
|
|
4160
|
+
} else if (removeType === "OBJECT_EXTENSION") {
|
|
4161
|
+
const names = /* @__PURE__ */ new Set();
|
|
4162
|
+
for (const obj of objects) {
|
|
4163
|
+
const sval = obj.String?.sval;
|
|
4164
|
+
if (sval) names.add(sval);
|
|
4165
|
+
}
|
|
4166
|
+
if (names.size > 0) state.extensions = state.extensions.filter((e) => !names.has(e.name));
|
|
4167
|
+
} else if (removeType === "OBJECT_TRIGGER") {
|
|
4168
|
+
for (const obj of objects) {
|
|
4169
|
+
const items = obj.List?.items ?? [];
|
|
4170
|
+
if (items.length < 2) continue;
|
|
4171
|
+
const table = items[0]?.String?.sval ?? "";
|
|
4172
|
+
const trigName = items[items.length - 1]?.String?.sval ?? "";
|
|
4173
|
+
if (!table || !trigName) continue;
|
|
4174
|
+
state.triggers = state.triggers.filter((t) => !(t.table === table && t.name === trigName));
|
|
4175
|
+
}
|
|
4176
|
+
} else if (removeType === "OBJECT_FUNCTION" || removeType === "OBJECT_PROCEDURE") {
|
|
4177
|
+
for (const obj of objects) {
|
|
4178
|
+
const items = obj.ObjectWithArgs?.objname?.items ?? obj.ObjectWithArgs?.objname ?? obj.List?.items ?? [];
|
|
4179
|
+
if (!items.length) continue;
|
|
4180
|
+
const segs = items.map((s) => s.String?.sval ?? "").filter(Boolean);
|
|
4181
|
+
if (!segs.length) continue;
|
|
4182
|
+
const name = segs[segs.length - 1];
|
|
4183
|
+
const schema = segs.length > 1 ? segs[segs.length - 2] : null;
|
|
4184
|
+
const id = functionIdFor(name, schema);
|
|
4185
|
+
state.functions = state.functions.filter((f) => functionIdFor(f.name, f.schema) !== id);
|
|
4186
|
+
}
|
|
4187
|
+
} else if (removeType === "OBJECT_VIEW" || removeType === "OBJECT_MATVIEW") {
|
|
4188
|
+
for (const obj of objects) {
|
|
4189
|
+
const items = obj.List?.items ?? [];
|
|
4190
|
+
if (!items.length) continue;
|
|
4191
|
+
const name = items[items.length - 1]?.String?.sval ?? "";
|
|
4192
|
+
const schema = items.length > 1 ? items[items.length - 2]?.String?.sval ?? null : null;
|
|
4193
|
+
if (!name) continue;
|
|
4194
|
+
const id = functionIdFor(name, schema);
|
|
4195
|
+
state.views = state.views.filter((v) => functionIdFor(v.name, v.schema) !== id);
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
function indexIsPrismaUncoverable(idx) {
|
|
4201
|
+
return idx.hasPredicate || idx.hasExpressions || idx.method !== "btree";
|
|
4202
|
+
}
|
|
3757
4203
|
function loadPrismaState(schemaPath) {
|
|
3758
4204
|
if (!schemaPath || !(0, import_node_fs14.existsSync)(schemaPath)) return null;
|
|
3759
4205
|
const content = (0, import_node_fs14.readFileSync)(schemaPath, "utf-8");
|
|
@@ -3920,6 +4366,96 @@ function verify(sqlState, prisma) {
|
|
|
3920
4366
|
}
|
|
3921
4367
|
return { contradictions, flaggedEdges };
|
|
3922
4368
|
}
|
|
4369
|
+
function deriveMigrationName(sqlPath) {
|
|
4370
|
+
const segments = sqlPath.split(/[\\/]/);
|
|
4371
|
+
const last = segments[segments.length - 1];
|
|
4372
|
+
if (last === "migration.sql" && segments.length >= 2) {
|
|
4373
|
+
return segments[segments.length - 2];
|
|
4374
|
+
}
|
|
4375
|
+
return last.replace(/\.sql$/, "");
|
|
4376
|
+
}
|
|
4377
|
+
function extractMigrationInfoFromStmts(stmts, name, filepath) {
|
|
4378
|
+
let isDestructive = false;
|
|
4379
|
+
let hasOrphanCheck = false;
|
|
4380
|
+
let hasSidecarBackup = false;
|
|
4381
|
+
let hasPreFlightNotice = false;
|
|
4382
|
+
let containsBackfill = false;
|
|
4383
|
+
let containsDropColumn = false;
|
|
4384
|
+
let containsDropTable = false;
|
|
4385
|
+
for (const wrap of stmts) {
|
|
4386
|
+
const stmt = wrap.stmt ?? {};
|
|
4387
|
+
const kind = Object.keys(stmt)[0];
|
|
4388
|
+
if (!kind) continue;
|
|
4389
|
+
const body = stmt[kind] ?? {};
|
|
4390
|
+
switch (kind) {
|
|
4391
|
+
case "AlterTableStmt": {
|
|
4392
|
+
const cmds = body.cmds ?? [];
|
|
4393
|
+
for (const c of cmds) {
|
|
4394
|
+
const subtype = c.AlterTableCmd?.subtype;
|
|
4395
|
+
if (subtype === "AT_DropColumn") {
|
|
4396
|
+
containsDropColumn = true;
|
|
4397
|
+
isDestructive = true;
|
|
4398
|
+
} else if (subtype === "AT_AlterColumnType" || subtype === "AT_DropNotNull" || subtype === "AT_DropConstraint") {
|
|
4399
|
+
isDestructive = true;
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
break;
|
|
4403
|
+
}
|
|
4404
|
+
case "DropStmt": {
|
|
4405
|
+
const removeType = body.removeType ?? "";
|
|
4406
|
+
if (removeType === "OBJECT_TABLE") {
|
|
4407
|
+
containsDropTable = true;
|
|
4408
|
+
isDestructive = true;
|
|
4409
|
+
} else if (removeType === "OBJECT_TYPE" || removeType === "OBJECT_COLUMN" || removeType === "OBJECT_INDEX" || removeType === "OBJECT_POLICY") {
|
|
4410
|
+
isDestructive = true;
|
|
4411
|
+
}
|
|
4412
|
+
break;
|
|
4413
|
+
}
|
|
4414
|
+
case "CreateStmt": {
|
|
4415
|
+
const relname = body.relation?.relname ?? "";
|
|
4416
|
+
if (relname.startsWith("_backup_")) hasSidecarBackup = true;
|
|
4417
|
+
break;
|
|
4418
|
+
}
|
|
4419
|
+
case "CreateTableAsStmt": {
|
|
4420
|
+
const relname = body.into?.rel?.relname ?? "";
|
|
4421
|
+
if (relname.startsWith("_backup_")) hasSidecarBackup = true;
|
|
4422
|
+
break;
|
|
4423
|
+
}
|
|
4424
|
+
case "UpdateStmt":
|
|
4425
|
+
case "InsertStmt":
|
|
4426
|
+
case "DeleteStmt": {
|
|
4427
|
+
containsBackfill = true;
|
|
4428
|
+
break;
|
|
4429
|
+
}
|
|
4430
|
+
case "DoStmt": {
|
|
4431
|
+
const args = body.args ?? [];
|
|
4432
|
+
for (const arg of args) {
|
|
4433
|
+
const def = arg.DefElem;
|
|
4434
|
+
if (!def || def.defname !== "as") continue;
|
|
4435
|
+
const code = def.arg?.String?.sval ?? "";
|
|
4436
|
+
if (/\bRAISE\s+EXCEPTION\b/i.test(code)) hasOrphanCheck = true;
|
|
4437
|
+
if (/\bRAISE\s+NOTICE\b/i.test(code)) hasPreFlightNotice = true;
|
|
4438
|
+
}
|
|
4439
|
+
break;
|
|
4440
|
+
}
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4443
|
+
const tsMatch = name.match(/^(\d{8,14})/);
|
|
4444
|
+
const timestamp = tsMatch ? tsMatch[1] : null;
|
|
4445
|
+
return {
|
|
4446
|
+
name,
|
|
4447
|
+
filepath,
|
|
4448
|
+
timestamp,
|
|
4449
|
+
isDestructive,
|
|
4450
|
+
hasOrphanCheck,
|
|
4451
|
+
hasSidecarBackup,
|
|
4452
|
+
hasPreFlightNotice,
|
|
4453
|
+
containsBackfill,
|
|
4454
|
+
containsDropColumn,
|
|
4455
|
+
containsDropTable,
|
|
4456
|
+
statementCount: stmts.length
|
|
4457
|
+
};
|
|
4458
|
+
}
|
|
3923
4459
|
function migrationsDirFor(rootDir) {
|
|
3924
4460
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
3925
4461
|
if (!paths) return null;
|
|
@@ -3974,6 +4510,132 @@ function generate3(rootDir) {
|
|
|
3974
4510
|
values: [...sqlEnum.values]
|
|
3975
4511
|
});
|
|
3976
4512
|
}
|
|
4513
|
+
let indexNodeCount = 0;
|
|
4514
|
+
for (const idx of sqlState.indexes) {
|
|
4515
|
+
if (!indexIsPrismaUncoverable(idx)) continue;
|
|
4516
|
+
nodes.push({
|
|
4517
|
+
id: `index:${idx.name}`,
|
|
4518
|
+
type: "index",
|
|
4519
|
+
name: idx.name,
|
|
4520
|
+
source: "sql",
|
|
4521
|
+
table: idx.table,
|
|
4522
|
+
unique: idx.unique,
|
|
4523
|
+
method: idx.method,
|
|
4524
|
+
columns: idx.columns,
|
|
4525
|
+
has_expressions: idx.hasExpressions,
|
|
4526
|
+
has_predicate: idx.hasPredicate,
|
|
4527
|
+
filepath: idx.filepath
|
|
4528
|
+
});
|
|
4529
|
+
indexNodeCount++;
|
|
4530
|
+
}
|
|
4531
|
+
let extensionNodeCount = 0;
|
|
4532
|
+
for (const ext of sqlState.extensions) {
|
|
4533
|
+
nodes.push({
|
|
4534
|
+
id: `extension:${ext.name}`,
|
|
4535
|
+
type: "extension",
|
|
4536
|
+
name: ext.name,
|
|
4537
|
+
source: "sql",
|
|
4538
|
+
schema: ext.schema,
|
|
4539
|
+
version: ext.version,
|
|
4540
|
+
filepath: ext.filepath
|
|
4541
|
+
});
|
|
4542
|
+
extensionNodeCount++;
|
|
4543
|
+
}
|
|
4544
|
+
let triggerNodeCount = 0;
|
|
4545
|
+
for (const trg of sqlState.triggers) {
|
|
4546
|
+
nodes.push({
|
|
4547
|
+
id: `trigger:${trg.table}:${trg.name}`,
|
|
4548
|
+
type: "trigger",
|
|
4549
|
+
name: trg.name,
|
|
4550
|
+
source: "sql",
|
|
4551
|
+
table: trg.table,
|
|
4552
|
+
timing: trg.timing,
|
|
4553
|
+
events: trg.events,
|
|
4554
|
+
function: trg.function,
|
|
4555
|
+
has_when: trg.hasWhen,
|
|
4556
|
+
for_each: trg.forEach,
|
|
4557
|
+
filepath: trg.filepath
|
|
4558
|
+
});
|
|
4559
|
+
triggerNodeCount++;
|
|
4560
|
+
}
|
|
4561
|
+
let functionNodeCount = 0;
|
|
4562
|
+
for (const fn of sqlState.functions) {
|
|
4563
|
+
const qualified = fn.schema ? `${fn.schema}.${fn.name}` : fn.name;
|
|
4564
|
+
nodes.push({
|
|
4565
|
+
id: `function:${qualified}`,
|
|
4566
|
+
type: "function",
|
|
4567
|
+
name: fn.name,
|
|
4568
|
+
source: "sql",
|
|
4569
|
+
schema: fn.schema,
|
|
4570
|
+
language: fn.language,
|
|
4571
|
+
return_type: fn.returnType,
|
|
4572
|
+
is_procedure: fn.isProcedure,
|
|
4573
|
+
filepath: fn.filepath
|
|
4574
|
+
});
|
|
4575
|
+
functionNodeCount++;
|
|
4576
|
+
}
|
|
4577
|
+
let viewNodeCount = 0;
|
|
4578
|
+
for (const vw of sqlState.views) {
|
|
4579
|
+
const qualified = vw.schema ? `${vw.schema}.${vw.name}` : vw.name;
|
|
4580
|
+
nodes.push({
|
|
4581
|
+
id: `${vw.isMaterialized ? "matview" : "view"}:${qualified}`,
|
|
4582
|
+
type: vw.isMaterialized ? "materialized_view" : "view",
|
|
4583
|
+
name: vw.name,
|
|
4584
|
+
source: "sql",
|
|
4585
|
+
schema: vw.schema,
|
|
4586
|
+
is_materialized: vw.isMaterialized,
|
|
4587
|
+
with_check_option: vw.withCheckOption,
|
|
4588
|
+
filepath: vw.filepath
|
|
4589
|
+
});
|
|
4590
|
+
viewNodeCount++;
|
|
4591
|
+
}
|
|
4592
|
+
let policyNodeCount = 0;
|
|
4593
|
+
for (const pol of sqlState.policies) {
|
|
4594
|
+
nodes.push({
|
|
4595
|
+
id: `policy:${pol.table}:${pol.name}`,
|
|
4596
|
+
type: "policy",
|
|
4597
|
+
name: pol.name,
|
|
4598
|
+
source: "sql",
|
|
4599
|
+
table: pol.table,
|
|
4600
|
+
command: pol.command,
|
|
4601
|
+
permissive: pol.permissive,
|
|
4602
|
+
roles: pol.roles,
|
|
4603
|
+
has_using: pol.hasUsing,
|
|
4604
|
+
has_with_check: pol.hasWithCheck,
|
|
4605
|
+
filepath: pol.filepath
|
|
4606
|
+
});
|
|
4607
|
+
policyNodeCount++;
|
|
4608
|
+
}
|
|
4609
|
+
const migrationFiles = migrationsDir ? discoverMigrationFiles(migrationsDir) : [];
|
|
4610
|
+
let migrationNodeCount = 0;
|
|
4611
|
+
for (const sqlPath of migrationFiles) {
|
|
4612
|
+
const sql = (0, import_node_fs14.readFileSync)(sqlPath, "utf-8");
|
|
4613
|
+
const name = deriveMigrationName(sqlPath);
|
|
4614
|
+
let ast;
|
|
4615
|
+
try {
|
|
4616
|
+
ast = postgresDialect.parse(sql);
|
|
4617
|
+
} catch {
|
|
4618
|
+
ast = { stmts: [] };
|
|
4619
|
+
}
|
|
4620
|
+
const info = postgresDialect.extractMigrationInfo(ast, name, sqlPath);
|
|
4621
|
+
nodes.push({
|
|
4622
|
+
id: `migration:${name}`,
|
|
4623
|
+
type: "migration",
|
|
4624
|
+
name,
|
|
4625
|
+
source: "sql",
|
|
4626
|
+
filepath: info.filepath,
|
|
4627
|
+
timestamp: info.timestamp,
|
|
4628
|
+
is_destructive: info.isDestructive,
|
|
4629
|
+
has_orphan_check: info.hasOrphanCheck,
|
|
4630
|
+
has_sidecar_backup: info.hasSidecarBackup,
|
|
4631
|
+
has_pre_flight_notice: info.hasPreFlightNotice,
|
|
4632
|
+
contains_backfill: info.containsBackfill,
|
|
4633
|
+
contains_drop_column: info.containsDropColumn,
|
|
4634
|
+
contains_drop_table: info.containsDropTable,
|
|
4635
|
+
statement_count: info.statementCount
|
|
4636
|
+
});
|
|
4637
|
+
migrationNodeCount++;
|
|
4638
|
+
}
|
|
3977
4639
|
const sqlOnlyTables = new Set(nodes.filter((n) => n.type === "table").map((n) => n.id));
|
|
3978
4640
|
const edges = sqlState.fks.filter((fk) => sqlOnlyTables.has(fk.sourceTable)).map((fk) => ({
|
|
3979
4641
|
source: fk.sourceTable,
|
|
@@ -3992,6 +4654,13 @@ function generate3(rootDir) {
|
|
|
3992
4654
|
sql_tables: sqlState.tables.size,
|
|
3993
4655
|
sql_enums: sqlState.enums.size,
|
|
3994
4656
|
sql_fks: sqlState.fks.length,
|
|
4657
|
+
sql_index_nodes: indexNodeCount,
|
|
4658
|
+
sql_policy_nodes: policyNodeCount,
|
|
4659
|
+
sql_extension_nodes: extensionNodeCount,
|
|
4660
|
+
sql_trigger_nodes: triggerNodeCount,
|
|
4661
|
+
sql_function_nodes: functionNodeCount,
|
|
4662
|
+
sql_view_nodes: viewNodeCount,
|
|
4663
|
+
sql_migration_nodes: migrationNodeCount,
|
|
3995
4664
|
additive_nodes: nodes.length,
|
|
3996
4665
|
contradictions_found: contradictions.length,
|
|
3997
4666
|
flagged_edges_found: flaggedEdges.length
|