@diagrammo/dgmo 0.47.0 → 0.48.0
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/auto.js +1 -1
- package/dist/auto.mjs +1 -1
- package/dist/element.js +1 -1
- package/dist/element.mjs +1 -1
- package/package.json +19 -70
- package/dist/advanced.cjs +0 -71648
- package/dist/advanced.d.cts +0 -5719
- package/dist/auto.cjs +0 -70648
- package/dist/auto.d.cts +0 -54
- package/dist/block.cjs +0 -70208
- package/dist/block.d.cts +0 -115
- package/dist/editor.cjs +0 -526
- package/dist/editor.d.cts +0 -26
- package/dist/element.cjs +0 -70530
- package/dist/element.d.cts +0 -62
- package/dist/highlight.cjs +0 -852
- package/dist/highlight.d.cts +0 -49
- package/dist/index.cjs +0 -70491
- package/dist/index.d.cts +0 -160
- package/dist/pert.cjs +0 -325
- package/dist/pert.d.cts +0 -559
- package/dist/themes-1-CuKpeH.d.cts +0 -908
- package/src/advanced.ts +0 -873
- package/src/arc/parser.ts +0 -15
- package/src/arc/renderer.ts +0 -633
- package/src/auto/index.ts +0 -621
- package/src/auto/shared.ts +0 -370
- package/src/auto/styles.ts +0 -73
- package/src/block/layout.ts +0 -198
- package/src/block/parser.ts +0 -427
- package/src/block/renderer.ts +0 -484
- package/src/block/types.ts +0 -67
- package/src/boxes-and-lines/collapse.ts +0 -96
- package/src/boxes-and-lines/focus.ts +0 -257
- package/src/boxes-and-lines/label-placement.ts +0 -339
- package/src/boxes-and-lines/layout-grouped.ts +0 -912
- package/src/boxes-and-lines/layout-layered.ts +0 -722
- package/src/boxes-and-lines/layout-search.ts +0 -1678
- package/src/boxes-and-lines/layout.ts +0 -398
- package/src/boxes-and-lines/parser.ts +0 -1181
- package/src/boxes-and-lines/renderer.ts +0 -1465
- package/src/boxes-and-lines/types.ts +0 -66
- package/src/c4/layout.ts +0 -2441
- package/src/c4/parser.ts +0 -1158
- package/src/c4/renderer.ts +0 -2008
- package/src/c4/types.ts +0 -89
- package/src/chart-type-registry.ts +0 -529
- package/src/chart-types.ts +0 -225
- package/src/chart.ts +0 -685
- package/src/charts-d3/bar.ts +0 -338
- package/src/charts-d3/chord.ts +0 -140
- package/src/charts-d3/function.ts +0 -147
- package/src/charts-d3/funnel.ts +0 -104
- package/src/charts-d3/heatmap.ts +0 -145
- package/src/charts-d3/index.ts +0 -337
- package/src/charts-d3/interactions.ts +0 -477
- package/src/charts-d3/line.ts +0 -344
- package/src/charts-d3/mount.ts +0 -151
- package/src/charts-d3/pie.ts +0 -117
- package/src/charts-d3/polar.ts +0 -89
- package/src/charts-d3/radar.ts +0 -0
- package/src/charts-d3/sankey.ts +0 -0
- package/src/charts-d3/scatter.ts +0 -185
- package/src/charts-d3/shared.ts +0 -208
- package/src/class/layout.ts +0 -326
- package/src/class/parser.ts +0 -635
- package/src/class/renderer.ts +0 -793
- package/src/class/types.ts +0 -58
- package/src/cli-banner.ts +0 -106
- package/src/cli.ts +0 -1080
- package/src/colors-diagnostics.ts +0 -35
- package/src/colors.ts +0 -379
- package/src/completion-types.ts +0 -27
- package/src/completion.ts +0 -2668
- package/src/cycle/layout.ts +0 -1026
- package/src/cycle/parser.ts +0 -387
- package/src/cycle/renderer.ts +0 -653
- package/src/cycle/types.ts +0 -101
- package/src/d3.ts +0 -1434
- package/src/data-chart-parser.ts +0 -1007
- package/src/dgmo-router.ts +0 -296
- package/src/diagnostics-registry.ts +0 -108
- package/src/diagnostics.ts +0 -0
- package/src/dimensions.ts +0 -20
- package/src/directives-registry.ts +0 -396
- package/src/editor/dgmo.grammar +0 -76
- package/src/editor/dgmo.grammar.d.ts +0 -2
- package/src/editor/dgmo.grammar.js +0 -18
- package/src/editor/dgmo.grammar.terms.d.ts +0 -5
- package/src/editor/dgmo.grammar.terms.js +0 -35
- package/src/editor/highlight-api.ts +0 -596
- package/src/editor/highlight.ts +0 -36
- package/src/editor/index.ts +0 -27
- package/src/editor/keywords.ts +0 -128
- package/src/editor/tokens.ts +0 -30
- package/src/element/index.ts +0 -432
- package/src/embed/css.ts +0 -312
- package/src/embed/escape.ts +0 -15
- package/src/embed/index.ts +0 -280
- package/src/er/classify.ts +0 -228
- package/src/er/layout.ts +0 -530
- package/src/er/parser.ts +0 -750
- package/src/er/renderer.ts +0 -725
- package/src/er/types.ts +0 -52
- package/src/error-card.ts +0 -269
- package/src/event-line/diagnostics.ts +0 -117
- package/src/event-line/parser.ts +0 -643
- package/src/event-line/renderer.ts +0 -1742
- package/src/event-line/types.ts +0 -74
- package/src/fonts.ts +0 -3
- package/src/gantt/calculator.ts +0 -979
- package/src/gantt/parser.ts +0 -1641
- package/src/gantt/renderer.ts +0 -3787
- package/src/gantt/resolver.ts +0 -172
- package/src/gantt/types.ts +0 -206
- package/src/graph/diagnostics.ts +0 -64
- package/src/graph/edge-spline.ts +0 -29
- package/src/graph/flowchart-parser.ts +0 -759
- package/src/graph/flowchart-renderer.ts +0 -817
- package/src/graph/layout.ts +0 -472
- package/src/graph/notes.ts +0 -21
- package/src/graph/state-collapse.ts +0 -78
- package/src/graph/state-parser.ts +0 -574
- package/src/graph/state-renderer.ts +0 -653
- package/src/graph/types.ts +0 -65
- package/src/index.ts +0 -261
- package/src/infra/compute.ts +0 -1385
- package/src/infra/layout.ts +0 -888
- package/src/infra/parser.ts +0 -1234
- package/src/infra/renderer.ts +0 -2534
- package/src/infra/roles.ts +0 -75
- package/src/infra/types.ts +0 -216
- package/src/infra/validation.ts +0 -201
- package/src/journey-map/layout.ts +0 -490
- package/src/journey-map/parser.ts +0 -557
- package/src/journey-map/renderer.ts +0 -1580
- package/src/journey-map/types.ts +0 -47
- package/src/kanban/mutations.ts +0 -175
- package/src/kanban/parser.ts +0 -509
- package/src/kanban/renderer.ts +0 -1449
- package/src/kanban/types.ts +0 -39
- package/src/label-layout.ts +0 -368
- package/src/map/colorize.ts +0 -54
- package/src/map/completion.ts +0 -316
- package/src/map/context-labels.ts +0 -609
- package/src/map/data/PROVENANCE.json +0 -1
- package/src/map/data/README.md +0 -40
- package/src/map/data/airport-collisions.json +0 -1
- package/src/map/data/airports.json +0 -1
- package/src/map/data/gazetteer.json +0 -1
- package/src/map/data/lakes.json +0 -1
- package/src/map/data/mountain-ranges.json +0 -1
- package/src/map/data/na-lakes.json +0 -1
- package/src/map/data/na-land.json +0 -1
- package/src/map/data/region-names.json +0 -1
- package/src/map/data/rivers.json +0 -1
- package/src/map/data/types.ts +0 -121
- package/src/map/data/us-states.json +0 -1
- package/src/map/data/water-bodies.json +0 -1
- package/src/map/data/world-coarse.json +0 -1
- package/src/map/data/world-detail.json +0 -1
- package/src/map/diagnostics.ts +0 -134
- package/src/map/dimensions.ts +0 -150
- package/src/map/geo-query.ts +0 -295
- package/src/map/geo.ts +0 -438
- package/src/map/invert.ts +0 -111
- package/src/map/layout.ts +0 -5069
- package/src/map/legend-band.ts +0 -127
- package/src/map/load-data.ts +0 -186
- package/src/map/parser.ts +0 -783
- package/src/map/renderer.ts +0 -1445
- package/src/map/resolved-types.ts +0 -160
- package/src/map/resolver.ts +0 -1146
- package/src/map/types.ts +0 -194
- package/src/mindmap/collapse.ts +0 -67
- package/src/mindmap/layout.ts +0 -649
- package/src/mindmap/parser.ts +0 -430
- package/src/mindmap/renderer.ts +0 -637
- package/src/mindmap/text-wrap.ts +0 -218
- package/src/mindmap/types.ts +0 -56
- package/src/org/collapse.ts +0 -151
- package/src/org/layout.ts +0 -1262
- package/src/org/parser.ts +0 -519
- package/src/org/renderer.ts +0 -866
- package/src/org/resolver.ts +0 -636
- package/src/palettes/atlas.ts +0 -77
- package/src/palettes/blueprint.ts +0 -73
- package/src/palettes/catppuccin.ts +0 -84
- package/src/palettes/color-utils.ts +0 -443
- package/src/palettes/index.ts +0 -67
- package/src/palettes/nord.ts +0 -67
- package/src/palettes/registry.ts +0 -114
- package/src/palettes/slate.ts +0 -73
- package/src/palettes/tidewater.ts +0 -73
- package/src/palettes/tokyo-night.ts +0 -86
- package/src/palettes/types.ts +0 -88
- package/src/pert/analyzer.ts +0 -1183
- package/src/pert/diagnostics.ts +0 -110
- package/src/pert/index.ts +0 -43
- package/src/pert/internal.ts +0 -252
- package/src/pert/layout.ts +0 -971
- package/src/pert/monte-carlo.ts +0 -446
- package/src/pert/parser.ts +0 -1606
- package/src/pert/renderer.ts +0 -4009
- package/src/pert/share-normalize.ts +0 -62
- package/src/pert/types.ts +0 -604
- package/src/pyramid/parser.ts +0 -185
- package/src/pyramid/renderer.ts +0 -768
- package/src/pyramid/types.ts +0 -28
- package/src/quadrant/parser.ts +0 -18
- package/src/quadrant/renderer.ts +0 -638
- package/src/raci/diagnostics.ts +0 -213
- package/src/raci/index.ts +0 -23
- package/src/raci/mutations.ts +0 -321
- package/src/raci/parser.ts +0 -699
- package/src/raci/renderer.ts +0 -1627
- package/src/raci/types.ts +0 -82
- package/src/raci/variants.ts +0 -320
- package/src/render.ts +0 -268
- package/src/ring/parser.ts +0 -212
- package/src/ring/renderer.ts +0 -490
- package/src/ring/types.ts +0 -27
- package/src/sequence/collapse.ts +0 -174
- package/src/sequence/parser.ts +0 -1596
- package/src/sequence/participant-inference.ts +0 -152
- package/src/sequence/renderer.ts +0 -3168
- package/src/sequence/tag-resolution.ts +0 -164
- package/src/sharing.ts +0 -211
- package/src/sitemap/collapse.ts +0 -100
- package/src/sitemap/layout.ts +0 -925
- package/src/sitemap/parser.ts +0 -755
- package/src/sitemap/renderer.ts +0 -828
- package/src/sitemap/types.ts +0 -42
- package/src/slope/parser.ts +0 -18
- package/src/slope/renderer.ts +0 -378
- package/src/swimlane/diagnostics.ts +0 -94
- package/src/swimlane/layout.ts +0 -597
- package/src/swimlane/parser.ts +0 -613
- package/src/swimlane/renderer.ts +0 -681
- package/src/swimlane/types.ts +0 -151
- package/src/tech-radar/interactive.ts +0 -1129
- package/src/tech-radar/layout.ts +0 -197
- package/src/tech-radar/parser.ts +0 -436
- package/src/tech-radar/renderer.ts +0 -1239
- package/src/tech-radar/shared.ts +0 -151
- package/src/tech-radar/types.ts +0 -86
- package/src/themes.ts +0 -22
- package/src/timeline/parser.ts +0 -472
- package/src/timeline/renderer.ts +0 -3024
- package/src/timeline/types.ts +0 -33
- package/src/timeline/viz-parser.ts +0 -21
- package/src/treemap/diagnostics.ts +0 -62
- package/src/treemap/layout-radial.ts +0 -233
- package/src/treemap/layout.ts +0 -189
- package/src/treemap/parser.ts +0 -463
- package/src/treemap/renderer-radial.ts +0 -438
- package/src/treemap/renderer.ts +0 -572
- package/src/treemap/treemap-shared.ts +0 -309
- package/src/treemap/types.ts +0 -60
- package/src/utils/arrow-markers.ts +0 -51
- package/src/utils/arrows-diagnostics.ts +0 -62
- package/src/utils/arrows.ts +0 -227
- package/src/utils/brand.ts +0 -61
- package/src/utils/card.ts +0 -183
- package/src/utils/collapse-engine/tree-edges.ts +0 -115
- package/src/utils/collapse-engine/tree.ts +0 -117
- package/src/utils/d3-helpers.ts +0 -219
- package/src/utils/d3-types.ts +0 -9
- package/src/utils/description-helpers.ts +0 -38
- package/src/utils/duration.ts +0 -312
- package/src/utils/export-container.ts +0 -41
- package/src/utils/expr-eval.ts +0 -27
- package/src/utils/fit-canvas.ts +0 -64
- package/src/utils/hover-styles.ts +0 -673
- package/src/utils/inline-markdown.ts +0 -96
- package/src/utils/legend-constants.ts +0 -48
- package/src/utils/legend-d3.ts +0 -618
- package/src/utils/legend-integration.ts +0 -107
- package/src/utils/legend-layout.ts +0 -776
- package/src/utils/legend-svg.ts +0 -214
- package/src/utils/legend-types.ts +0 -272
- package/src/utils/name-normalize.ts +0 -163
- package/src/utils/note-box/constants.ts +0 -25
- package/src/utils/note-box/index.ts +0 -11
- package/src/utils/note-box/metrics.ts +0 -90
- package/src/utils/note-box/svg.ts +0 -331
- package/src/utils/notes/bounds.ts +0 -30
- package/src/utils/notes/build.ts +0 -131
- package/src/utils/notes/index.ts +0 -18
- package/src/utils/notes/model.ts +0 -19
- package/src/utils/notes/parse.ts +0 -131
- package/src/utils/notes/place.ts +0 -177
- package/src/utils/notes/resolve.ts +0 -88
- package/src/utils/number-format.ts +0 -36
- package/src/utils/parsing.ts +0 -953
- package/src/utils/reserved-key-registry.ts +0 -239
- package/src/utils/safe-href.ts +0 -38
- package/src/utils/scaling.ts +0 -97
- package/src/utils/svg-embed.ts +0 -251
- package/src/utils/tag-groups.ts +0 -607
- package/src/utils/text-measure.ts +0 -122
- package/src/utils/time-ticks.ts +0 -253
- package/src/utils/title-constants.ts +0 -24
- package/src/utils/visual-conventions.ts +0 -61
- package/src/utils/wrapped-desc.ts +0 -87
- package/src/venn/parser.ts +0 -18
- package/src/venn/renderer.ts +0 -1047
- package/src/version-control/diagnostics.ts +0 -67
- package/src/version-control/parser.ts +0 -544
- package/src/version-control/renderer.ts +0 -724
- package/src/version-control/types.ts +0 -100
- package/src/visualizations/parse.ts +0 -1560
- package/src/visualizations/types.ts +0 -262
- package/src/wireframe/layout.ts +0 -479
- package/src/wireframe/parser.ts +0 -1114
- package/src/wireframe/renderer.ts +0 -1318
- package/src/wireframe/types.ts +0 -110
- package/src/wordcloud/parser.ts +0 -18
- package/src/wordcloud/renderer.ts +0 -357
package/src/er/classify.ts
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// ER Diagram Entity Classification
|
|
3
|
-
// ============================================================
|
|
4
|
-
//
|
|
5
|
-
// Classifies each ER entity into a structural role using heuristics
|
|
6
|
-
// derived from column constraints, FK patterns, relationship in-degree,
|
|
7
|
-
// and naming conventions.
|
|
8
|
-
//
|
|
9
|
-
// Only used when no explicit colors or tag groups are defined.
|
|
10
|
-
|
|
11
|
-
import type { ERTable, ERRelationship } from './types';
|
|
12
|
-
import type { PaletteColors } from '../palettes/types';
|
|
13
|
-
|
|
14
|
-
export type EntityRole =
|
|
15
|
-
| 'core'
|
|
16
|
-
| 'dependent'
|
|
17
|
-
| 'junction'
|
|
18
|
-
| 'ambiguous'
|
|
19
|
-
| 'lookup'
|
|
20
|
-
| 'hub'
|
|
21
|
-
| 'self-referential'
|
|
22
|
-
| 'unclassified';
|
|
23
|
-
|
|
24
|
-
/** Maps each role to a key in PaletteColors['colors'] */
|
|
25
|
-
export const ROLE_COLORS: Record<EntityRole, keyof PaletteColors['colors']> = {
|
|
26
|
-
core: 'green',
|
|
27
|
-
dependent: 'blue',
|
|
28
|
-
junction: 'red',
|
|
29
|
-
ambiguous: 'purple',
|
|
30
|
-
lookup: 'yellow',
|
|
31
|
-
hub: 'orange',
|
|
32
|
-
'self-referential': 'teal',
|
|
33
|
-
unclassified: 'gray',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/** Human-readable legend labels per role */
|
|
37
|
-
export const ROLE_LABELS: Record<EntityRole, string> = {
|
|
38
|
-
core: 'Core entity',
|
|
39
|
-
dependent: 'Dependent',
|
|
40
|
-
junction: 'Junction / M:M',
|
|
41
|
-
ambiguous: 'Bridge',
|
|
42
|
-
lookup: 'Lookup / Reference',
|
|
43
|
-
hub: 'Hub',
|
|
44
|
-
'self-referential': 'Self-referential',
|
|
45
|
-
unclassified: 'Unclassified',
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/** Stable display order for the semantic legend */
|
|
49
|
-
export const ROLE_ORDER: EntityRole[] = [
|
|
50
|
-
'core',
|
|
51
|
-
'dependent',
|
|
52
|
-
'junction',
|
|
53
|
-
'ambiguous',
|
|
54
|
-
'lookup',
|
|
55
|
-
'hub',
|
|
56
|
-
'self-referential',
|
|
57
|
-
'unclassified',
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
const LOOKUP_NAME_SUFFIXES = ['_type', '_status', '_code', '_category'];
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Classify each ER entity into a structural role.
|
|
64
|
-
*
|
|
65
|
-
* Returns a Map of tableId → EntityRole.
|
|
66
|
-
* Pure logic — no palette or DOM dependencies.
|
|
67
|
-
*/
|
|
68
|
-
export function classifyEREntities(
|
|
69
|
-
tables: ERTable[],
|
|
70
|
-
relationships: ERRelationship[]
|
|
71
|
-
): Map<string, EntityRole> {
|
|
72
|
-
const result = new Map<string, EntityRole>();
|
|
73
|
-
if (tables.length === 0) return result;
|
|
74
|
-
|
|
75
|
-
// ── Pre-compute graph metrics ─────────────────────────────────────────────
|
|
76
|
-
|
|
77
|
-
// indegreeMap: how many other tables have FK references pointing to this table.
|
|
78
|
-
// A table's indegree increments when it is on the exclusive '1' side of a 1:* or 1:?
|
|
79
|
-
// relationship. 1:1 relationships are skipped on both sides to avoid double-counting.
|
|
80
|
-
const indegreeMap: Record<string, number> = {};
|
|
81
|
-
for (const t of tables) indegreeMap[t.id] = 0;
|
|
82
|
-
for (const rel of relationships) {
|
|
83
|
-
if (rel.source === rel.target) continue; // skip self-loops
|
|
84
|
-
if (rel.cardinality.from === '1' && rel.cardinality.to !== '1') {
|
|
85
|
-
indegreeMap[rel.source] = (indegreeMap[rel.source] ?? 0) + 1;
|
|
86
|
-
}
|
|
87
|
-
if (rel.cardinality.to === '1' && rel.cardinality.from !== '1') {
|
|
88
|
-
indegreeMap[rel.target] = (indegreeMap[rel.target] ?? 0) + 1;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// mmParticipants: tables with '*' cardinality connecting to 2+ distinct other tables.
|
|
93
|
-
// Catches wide junction tables (e.g. with surrogate PKs) that the FK-ratio alone misses.
|
|
94
|
-
const tableStarNeighbors = new Map<string, Set<string>>();
|
|
95
|
-
for (const rel of relationships) {
|
|
96
|
-
if (rel.source === rel.target) continue;
|
|
97
|
-
if (rel.cardinality.from === '*') {
|
|
98
|
-
if (!tableStarNeighbors.has(rel.source))
|
|
99
|
-
tableStarNeighbors.set(rel.source, new Set());
|
|
100
|
-
tableStarNeighbors.get(rel.source)!.add(rel.target);
|
|
101
|
-
}
|
|
102
|
-
if (rel.cardinality.to === '*') {
|
|
103
|
-
if (!tableStarNeighbors.has(rel.target))
|
|
104
|
-
tableStarNeighbors.set(rel.target, new Set());
|
|
105
|
-
tableStarNeighbors.get(rel.target)!.add(rel.source);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
const mmParticipants = new Set<string>();
|
|
109
|
-
for (const [id, neighbors] of tableStarNeighbors) {
|
|
110
|
-
if (neighbors.size >= 2) mmParticipants.add(id);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Hub outlier statistics
|
|
114
|
-
const indegreeValues = Object.values(indegreeMap);
|
|
115
|
-
const mean =
|
|
116
|
-
indegreeValues.reduce((a, b) => a + b, 0) / indegreeValues.length;
|
|
117
|
-
const variance =
|
|
118
|
-
indegreeValues.reduce((a, b) => a + (b - mean) ** 2, 0) /
|
|
119
|
-
indegreeValues.length;
|
|
120
|
-
const stddev = Math.sqrt(variance);
|
|
121
|
-
|
|
122
|
-
// Median indegree (for lookup detection: table must be referenced above-median)
|
|
123
|
-
const sorted = [...indegreeValues].sort((a, b) => a - b);
|
|
124
|
-
// In-bounds: sorted.length === tables.length and tables.length > 0 is guaranteed above.
|
|
125
|
-
const median =
|
|
126
|
-
sorted.length % 2 === 0
|
|
127
|
-
? (sorted[sorted.length / 2 - 1]! + sorted[sorted.length / 2]!) / 2
|
|
128
|
-
: sorted[Math.floor(sorted.length / 2)]!;
|
|
129
|
-
|
|
130
|
-
// ── Per-table classification ──────────────────────────────────────────────
|
|
131
|
-
|
|
132
|
-
for (const table of tables) {
|
|
133
|
-
const id = table.id;
|
|
134
|
-
const cols = table.columns;
|
|
135
|
-
const fkCols = cols.filter((c) => c.constraints.includes('fk'));
|
|
136
|
-
const pkFkCols = cols.filter(
|
|
137
|
-
(c) => c.constraints.includes('pk') && c.constraints.includes('fk')
|
|
138
|
-
);
|
|
139
|
-
const fkCount = fkCols.length;
|
|
140
|
-
const fkRatio = cols.length === 0 ? 0 : fkCount / cols.length;
|
|
141
|
-
const indegree = indegreeMap[id] ?? 0;
|
|
142
|
-
const nameLower = table.name.toLowerCase();
|
|
143
|
-
|
|
144
|
-
// External relationships (exclude self-loops)
|
|
145
|
-
const externalRels = relationships.filter(
|
|
146
|
-
(r) => (r.source === id || r.target === id) && r.source !== r.target
|
|
147
|
-
);
|
|
148
|
-
const hasSelfRef = relationships.some(
|
|
149
|
-
(r) => r.source === id && r.target === id
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
// Distinct external tables this table relates to
|
|
153
|
-
const externalTargets = new Set<string>();
|
|
154
|
-
for (const rel of externalRels) {
|
|
155
|
-
externalTargets.add(rel.source === id ? rel.target : rel.source);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// ── Decision tree (priority order) ─────────────────────────────────────
|
|
159
|
-
|
|
160
|
-
// 1. Self-referential: has a self-loop relationship AND no external relationships
|
|
161
|
-
if (hasSelfRef && externalRels.length === 0) {
|
|
162
|
-
result.set(id, 'self-referential');
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// 2. Junction: any one of three signals qualifies.
|
|
167
|
-
// Inheritance exception: composite PK FKs all pointing to a single parent → skip ratio signal.
|
|
168
|
-
const isInheritancePattern =
|
|
169
|
-
pkFkCols.length >= 2 && externalTargets.size === 1;
|
|
170
|
-
const junctionByRatio = fkRatio >= 0.6 && !isInheritancePattern;
|
|
171
|
-
const junctionByCompositePk =
|
|
172
|
-
pkFkCols.length >= 2 && externalTargets.size >= 2;
|
|
173
|
-
const junctionByMm = mmParticipants.has(id);
|
|
174
|
-
if (junctionByRatio || junctionByCompositePk || junctionByMm) {
|
|
175
|
-
result.set(id, 'junction');
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// 3. Ambiguous: FK ratio 0.4–0.59, no composite PK FKs, not M:M participant
|
|
180
|
-
if (
|
|
181
|
-
fkRatio >= 0.4 &&
|
|
182
|
-
fkRatio < 0.6 &&
|
|
183
|
-
pkFkCols.length < 2 &&
|
|
184
|
-
!mmParticipants.has(id)
|
|
185
|
-
) {
|
|
186
|
-
result.set(id, 'ambiguous');
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// 4. Lookup: naming convention match + structural guards
|
|
191
|
-
// Naming only applies when cols ≤ 6 AND fkCount ≤ 1; structure overrides for larger tables.
|
|
192
|
-
const nameMatchesLookup = LOOKUP_NAME_SUFFIXES.some((s) =>
|
|
193
|
-
nameLower.endsWith(s)
|
|
194
|
-
);
|
|
195
|
-
if (
|
|
196
|
-
nameMatchesLookup &&
|
|
197
|
-
cols.length <= 6 &&
|
|
198
|
-
fkCount <= 1 &&
|
|
199
|
-
indegree > median
|
|
200
|
-
) {
|
|
201
|
-
result.set(id, 'lookup');
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// 5. Hub: in-degree outlier in a schema of ≥ 6 tables.
|
|
206
|
-
// Dual condition: > mean + 1.5σ AND ≥ 2× mean (guards against near-zero mean edge cases).
|
|
207
|
-
if (
|
|
208
|
-
tables.length >= 6 &&
|
|
209
|
-
indegree > 0 &&
|
|
210
|
-
indegree > mean + 1.5 * stddev &&
|
|
211
|
-
indegree >= 2 * mean
|
|
212
|
-
) {
|
|
213
|
-
result.set(id, 'hub');
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// 6. Dependent: has FK columns
|
|
218
|
-
if (fkCount > 0) {
|
|
219
|
-
result.set(id, 'dependent');
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// 7. Core: no FK columns (always true at this point)
|
|
224
|
-
result.set(id, 'core');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return result;
|
|
228
|
-
}
|