@g1cloud/entity-modeler-next 5.0.0-alpha.1
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/LICENSE +6 -0
- package/README.md +42 -0
- package/dist/adapter/diagramAdapter.d.ts +44 -0
- package/dist/adapter/persisted.d.ts +245 -0
- package/dist/agent/buildAgentBatch.d.ts +16 -0
- package/dist/agent/resolver.d.ts +54 -0
- package/dist/agent/schema.d.ts +9 -0
- package/dist/agent/symbolicOp.d.ts +109 -0
- package/dist/command/commands.d.ts +108 -0
- package/dist/command/op.d.ts +80 -0
- package/dist/command/opSync.d.ts +89 -0
- package/dist/command/stack.d.ts +48 -0
- package/dist/command/types.d.ts +29 -0
- package/dist/core/autolayout.d.ts +12 -0
- package/dist/core/dbTypes.d.ts +45 -0
- package/dist/core/id.d.ts +2 -0
- package/dist/core/javaTypes.d.ts +52 -0
- package/dist/core/propagation.d.ts +49 -0
- package/dist/core/relationMarker.d.ts +44 -0
- package/dist/core/resolve.d.ts +63 -0
- package/dist/core/routing.d.ts +58 -0
- package/dist/core/sharedColumn.d.ts +19 -0
- package/dist/core/sqlReservedWords.d.ts +25 -0
- package/dist/core/svg.d.ts +98 -0
- package/dist/core/text.d.ts +8 -0
- package/dist/core/types.d.ts +400 -0
- package/dist/core/validation.d.ts +53 -0
- package/dist/editor/controller.d.ts +371 -0
- package/dist/entity-modeler-next.css +1 -0
- package/dist/entity-modeler.js +19943 -0
- package/dist/entity-modeler.umd.cjs +41 -0
- package/dist/index.d.ts +32 -0
- package/dist/view/AssociationEdge.vue.d.ts +16 -0
- package/dist/view/DiagramCanvas.vue.d.ts +9 -0
- package/dist/view/DiagramExplorer.vue.d.ts +11 -0
- package/dist/view/EditModeToggle.vue.d.ts +10 -0
- package/dist/view/EditorToolbar.vue.d.ts +10 -0
- package/dist/view/EmContextMenu.vue.d.ts +26 -0
- package/dist/view/EmIcon.vue.d.ts +12 -0
- package/dist/view/EntityAttributesWide.vue.d.ts +7 -0
- package/dist/view/EntityBasicsSection.vue.d.ts +7 -0
- package/dist/view/EntityColumnsSection.vue.d.ts +7 -0
- package/dist/view/EntityDetailModal.vue.d.ts +7 -0
- package/dist/view/EntityIndexSection.vue.d.ts +7 -0
- package/dist/view/EntityIndexesWide.vue.d.ts +7 -0
- package/dist/view/EntityModeler.vue.d.ts +6 -0
- package/dist/view/EntityNode.vue.d.ts +20 -0
- package/dist/view/EntityOperationsSection.vue.d.ts +7 -0
- package/dist/view/EntityOperationsWide.vue.d.ts +7 -0
- package/dist/view/EntityTextPreview.vue.d.ts +5 -0
- package/dist/view/GroupCodeCombobox.vue.d.ts +11 -0
- package/dist/view/GroupNode.vue.d.ts +11 -0
- package/dist/view/InlineIssueBadge.vue.d.ts +8 -0
- package/dist/view/MultiLangTextField.vue.d.ts +24 -0
- package/dist/view/NoteConnectionEdge.vue.d.ts +12 -0
- package/dist/view/NoteNode.vue.d.ts +11 -0
- package/dist/view/OperationSourceEditor.vue.d.ts +7 -0
- package/dist/view/PropertyPanel.vue.d.ts +6 -0
- package/dist/view/ValidationPanel.vue.d.ts +6 -0
- package/dist/view/diagramGeometry.d.ts +9 -0
- package/dist/view/exportSvg.d.ts +7 -0
- package/dist/view/groupCodeFilter.d.ts +8 -0
- package/dist/view/groupHover.d.ts +10 -0
- package/dist/view/openEntityDetail.d.ts +5 -0
- package/dist/view/relationHighlight.d.ts +38 -0
- package/dist/view/swatches.d.ts +37 -0
- package/dist/view/useFloatingRoute.d.ts +28 -0
- package/dist/view/validationDisplay.d.ts +10 -0
- package/dist/view/waypointController.d.ts +14 -0
- package/package.json +61 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ModelId } from '../core/types';
|
|
2
|
+
/** rev CAS 대상 축 — logical(컨테이너 rev) / layout(layout.version, LWW). M2 §4.2 */
|
|
3
|
+
export type CasUnit = 'logical' | 'layout';
|
|
4
|
+
/**
|
|
5
|
+
* command가 산출하는 단일 op의 어휘 형태. `{target}.{verb}` kind + 로케이터 + 페이로드.
|
|
6
|
+
* CAS 메타는 여기 없다 — emit 어댑터 책임(계약 3).
|
|
7
|
+
*/
|
|
8
|
+
export interface OpShape {
|
|
9
|
+
/** `{target}.{verb}` — 'attribute.add' 등. M2 §3 어휘 인벤토리. */
|
|
10
|
+
kind: string;
|
|
11
|
+
casUnit: CasUnit;
|
|
12
|
+
/** rev CAS를 거는 대상 컨테이너(entity/association/group). layout op·top-level add/remove는 없음. */
|
|
13
|
+
containerRef?: ModelId;
|
|
14
|
+
entityRef?: ModelId;
|
|
15
|
+
attributeRef?: ModelId;
|
|
16
|
+
associationRef?: ModelId;
|
|
17
|
+
groupRef?: ModelId;
|
|
18
|
+
noteRef?: ModelId;
|
|
19
|
+
indexRef?: ModelId;
|
|
20
|
+
operationRef?: ModelId;
|
|
21
|
+
targetRef?: ModelId;
|
|
22
|
+
end?: 'end1' | 'end2';
|
|
23
|
+
/** add: 직렬화 전 core 모델 (호스트가 lib 직렬화기로 doc element 변환, A2). */
|
|
24
|
+
value?: unknown;
|
|
25
|
+
/** update: 부분 patch. */
|
|
26
|
+
patch?: Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* 부수(incidental) 레이아웃 op 마커(M2 §3.3·§4.2) — 구조 op(entity/group/association
|
|
29
|
+
* add·remove)가 동반하는 layout 엔트리 생성/삭제. `layout.version` 검사·증가 비대상.
|
|
30
|
+
* 어댑터가 `cas.layout`에서 제외하는 분기 신호.
|
|
31
|
+
*/
|
|
32
|
+
incidental?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* apply 이후 호출 계약(계약 1)의 산출 — memento가 채워진 상태에서 do/undo 양방향 op.
|
|
36
|
+
* invert는 *역방향 forward op*(계약 2) — 같은 op의 역값이 아니라 역연산 op.
|
|
37
|
+
*/
|
|
38
|
+
export interface OpEmission {
|
|
39
|
+
/** do/redo 시 호스트로 보낼 op 배치 (apply 순서). */
|
|
40
|
+
forward: OpShape[];
|
|
41
|
+
/** undo 시 호스트로 보낼 역연산 forward op 배치 (invert 순서). */
|
|
42
|
+
invert: OpShape[];
|
|
43
|
+
}
|
|
44
|
+
/** op 출처 — 레거시 updateId 관례 계승(감사·aggregation 트리거 분기용). */
|
|
45
|
+
export type OpOrigin = 'gui' | 'agent' | 'rest';
|
|
46
|
+
/**
|
|
47
|
+
* 배치 CAS 단언 — 건드리는 logical 컨테이너의 base rev + (포함 시) base layout.version.
|
|
48
|
+
* 호스트가 updateOne filter로 접어 충돌(matchedCount:0)을 감지한다(M2 §4.3).
|
|
49
|
+
*/
|
|
50
|
+
export interface OpCas {
|
|
51
|
+
/** 건드리는 logical 컨테이너의 base rev (update/내부변경). top-level add/remove는 비대상. */
|
|
52
|
+
revs?: Record<ModelId, number>;
|
|
53
|
+
/** 의도적(non-incidental) layout op 포함 시 base layout.version. */
|
|
54
|
+
layout?: number;
|
|
55
|
+
}
|
|
56
|
+
/** 한 제스처 = 한 원자 배치 = 한 updateOne(M2 §4.1). */
|
|
57
|
+
export interface PersistedOpBatch {
|
|
58
|
+
diagramId: string;
|
|
59
|
+
ops: OpShape[];
|
|
60
|
+
cas: OpCas;
|
|
61
|
+
origin: OpOrigin;
|
|
62
|
+
/** 멱등 키 — 재시도 중복 적용 차단(호스트가 직전 결과 반환). */
|
|
63
|
+
clientOpId: string;
|
|
64
|
+
}
|
|
65
|
+
/** 충돌 종류 — rev 불일치 / layout.version 불일치 / 대상 소실. */
|
|
66
|
+
export interface OpConflict {
|
|
67
|
+
kind: 'rev' | 'layout' | 'missing';
|
|
68
|
+
ref?: ModelId;
|
|
69
|
+
current?: number;
|
|
70
|
+
}
|
|
71
|
+
/** 호스트 op 집행 응답 — ok면 갱신 rev/version, 충돌이면 하드 프리즈 트리거. */
|
|
72
|
+
export type OpResult = {
|
|
73
|
+
ok: true;
|
|
74
|
+
revs: Record<ModelId, number>;
|
|
75
|
+
layoutVersion: number;
|
|
76
|
+
logicalVersion: number;
|
|
77
|
+
} | {
|
|
78
|
+
ok: false;
|
|
79
|
+
conflict: OpConflict;
|
|
80
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ModelId } from '../core/types';
|
|
2
|
+
import { OpConflict, OpOrigin, OpResult, PersistedOpBatch } from './op';
|
|
3
|
+
import { CommandStack } from './stack';
|
|
4
|
+
import { EditorState } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* 컨테이너 rev + layout/logical version의 라이브 캐시 — 모든 forward op의 base rev 단일 출처.
|
|
7
|
+
* `fromPersisted`(세션 #2)가 마커 doc을 파싱해 `seed`로 주입하고, 호스트 응답이 drain된 시점에 확정.
|
|
8
|
+
*/
|
|
9
|
+
export declare class RevCache {
|
|
10
|
+
private revs;
|
|
11
|
+
layoutVersion: number;
|
|
12
|
+
logicalVersion: number;
|
|
13
|
+
/** 마커 doc 적재/재적재 시 캐시 초기화(세션 #2 fromPersisted 분기 파서가 호출). */
|
|
14
|
+
seed(snapshot: {
|
|
15
|
+
revs?: Record<ModelId, number>;
|
|
16
|
+
layoutVersion?: number;
|
|
17
|
+
logicalVersion?: number;
|
|
18
|
+
}): void;
|
|
19
|
+
rev(id: ModelId): number;
|
|
20
|
+
setRev(id: ModelId, v: number): void;
|
|
21
|
+
deleteRev(id: ModelId): void;
|
|
22
|
+
/** 진단·테스트용 읽기 스냅샷(내부 Map 노출 안 함). */
|
|
23
|
+
snapshot(): {
|
|
24
|
+
revs: Record<ModelId, number>;
|
|
25
|
+
layoutVersion: number;
|
|
26
|
+
logicalVersion: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** 호스트로 배치를 전송하는 함수(세션 #3 applyEntityDiagramOps 라우트에 연결, 테스트는 mock). */
|
|
30
|
+
export type OpSyncTransport = (batch: PersistedOpBatch) => Promise<OpResult>;
|
|
31
|
+
export interface OpSyncOptions {
|
|
32
|
+
diagramId: string;
|
|
33
|
+
/** emitOps(state) 호출 대상 — controller의 reactive EditorState. */
|
|
34
|
+
state: EditorState;
|
|
35
|
+
transport: OpSyncTransport;
|
|
36
|
+
origin?: OpOrigin;
|
|
37
|
+
/** coalesce 그룹 idle 디바운스(ms). 기본 300. */
|
|
38
|
+
debounceMs?: number;
|
|
39
|
+
/** 멱등 키 생성기(주입 가능 — 테스트 결정성). 기본 newId. */
|
|
40
|
+
newClientOpId?: () => string;
|
|
41
|
+
/** 충돌(또는 전송 실패)로 하드 프리즈 진입 시 — controller가 editable=false + reload UX 연동. */
|
|
42
|
+
onFreeze?: (conflict: OpConflict) => void;
|
|
43
|
+
/** 전송 거부(네트워크 등) 통지 — 진단용(프리즈는 별도 onFreeze로). */
|
|
44
|
+
onError?: (err: unknown) => void;
|
|
45
|
+
}
|
|
46
|
+
export declare class OpSyncAdapter {
|
|
47
|
+
private readonly opts;
|
|
48
|
+
private readonly cache;
|
|
49
|
+
private readonly newClientOpId;
|
|
50
|
+
private readonly debounceMs;
|
|
51
|
+
private readonly emissions;
|
|
52
|
+
private open;
|
|
53
|
+
private debounceHandle;
|
|
54
|
+
private readonly queue;
|
|
55
|
+
private sending;
|
|
56
|
+
private _frozen;
|
|
57
|
+
private stack;
|
|
58
|
+
private settledWaiters;
|
|
59
|
+
constructor(opts: OpSyncOptions);
|
|
60
|
+
/** RevCache 시드(세션 #2 fromPersisted가 마커 파싱 후 호출). */
|
|
61
|
+
seed(snapshot: Parameters<RevCache['seed']>[0]): void;
|
|
62
|
+
/** stack에 구독 — onCommand 알림을 받고, flush 경계에서 sealCoalesce를 호출하기 위해 참조 보관. 해제 함수 반환. */
|
|
63
|
+
attach(stack: CommandStack): () => void;
|
|
64
|
+
get frozen(): boolean;
|
|
65
|
+
/** 미전송 pending 그룹 존재 여부(controller dirty 보조 신호). */
|
|
66
|
+
get hasPending(): boolean;
|
|
67
|
+
/** 진단·테스트용 캐시 스냅샷. */
|
|
68
|
+
cacheSnapshot(): ReturnType<RevCache['snapshot']>;
|
|
69
|
+
/** 강제 flush(save·blur·beforeunload) — 열린 그룹을 즉시 영속에 내보내고 coalesce 경계 봉인. */
|
|
70
|
+
flush(): void;
|
|
71
|
+
/** 큐가 비고 전송 중이 아니며 열린 그룹도 없을 때 resolve — 테스트 동기화용. */
|
|
72
|
+
whenSettled(): Promise<void>;
|
|
73
|
+
private handle;
|
|
74
|
+
private flushOpen;
|
|
75
|
+
private startDebounce;
|
|
76
|
+
private resetDebounce;
|
|
77
|
+
private cancelDebounce;
|
|
78
|
+
private buildBatch;
|
|
79
|
+
private enqueue;
|
|
80
|
+
private pump;
|
|
81
|
+
/**
|
|
82
|
+
* ok 응답 확정 — 낙관 체인 유지가 핵심. 후속 pending 배치가 이 예측 위에 base를 쌓았으므로
|
|
83
|
+
* 큐가 완전히 빈 시점에만 서버 권위값으로 덮어쓴다(중간에 덮으면 후속 배치 base가 stale → 거짓 충돌).
|
|
84
|
+
* ok ⟹ CAS 통과 ⟹ 서버 신 rev = 낙관 예측이므로, 미배수 시 캐시는 이미 정확(덮을 필요 없음).
|
|
85
|
+
*/
|
|
86
|
+
private reconcile;
|
|
87
|
+
private freeze;
|
|
88
|
+
private notifySettled;
|
|
89
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Command, EditorState } from './types';
|
|
2
|
+
export type StackListener = () => void;
|
|
3
|
+
/** 명령 적용 방향 — op emit 어댑터가 forward(do/redo) vs invert(undo) op를 고르는 축. */
|
|
4
|
+
export type CommandDirection = 'do' | 'undo' | 'redo';
|
|
5
|
+
/**
|
|
6
|
+
* 명령 적용 알림 구독자(트랙 B). `onChange`(상태 변경 무인자 알림)와 직교 —
|
|
7
|
+
* 이쪽은 *어떤 명령이 어느 방향으로* 적용됐는지(+coalesce 병합 여부)를 전달해
|
|
8
|
+
* op emit 어댑터가 emitOps로 op 배치를 파생하게 한다.
|
|
9
|
+
*/
|
|
10
|
+
export type CommandListener = (cmd: Command, dir: CommandDirection, coalesced: boolean) => void;
|
|
11
|
+
/**
|
|
12
|
+
* 명령 스택 — 레거시 ActionManager 대응.
|
|
13
|
+
* execute/undo/redo와 savePoint 기반 dirty 추적을 제공한다.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CommandStack {
|
|
16
|
+
private readonly state;
|
|
17
|
+
private undoStack;
|
|
18
|
+
private redoStack;
|
|
19
|
+
private savePoint;
|
|
20
|
+
private listeners;
|
|
21
|
+
private commandListeners;
|
|
22
|
+
private coalesceSealed;
|
|
23
|
+
constructor(state: EditorState);
|
|
24
|
+
execute(cmd: Command): void;
|
|
25
|
+
undo(): void;
|
|
26
|
+
redo(): void;
|
|
27
|
+
/**
|
|
28
|
+
* 다음 execute의 coalesce 병합을 1회 차단한다(op 어댑터의 idle flush·강제 flush 시 호출).
|
|
29
|
+
* 어댑터가 coalesce 그룹을 영속에 내보낸 경계 이후의 동일 키 명령이 같은 undo 단위로
|
|
30
|
+
* 빨려 들어가면 undo 시 로컬·서버 상태가 어긋나므로, 봉인으로 새 단위를 강제한다.
|
|
31
|
+
*/
|
|
32
|
+
sealCoalesce(): void;
|
|
33
|
+
get canUndo(): boolean;
|
|
34
|
+
get canRedo(): boolean;
|
|
35
|
+
/** 저장 시점 표시 — 이후 dirty 판정 기준 */
|
|
36
|
+
markSavePoint(): void;
|
|
37
|
+
/** 마지막 저장 이후 변경 여부 (undo로 저장 지점에 정확히 돌아오면 clean) */
|
|
38
|
+
get isDirty(): boolean;
|
|
39
|
+
/** 변경 알림 구독 — 반환 함수로 해제 */
|
|
40
|
+
onChange(listener: StackListener): () => void;
|
|
41
|
+
/**
|
|
42
|
+
* 명령 적용 알림 구독(트랙 B op emit). apply/invert 적용 *직후* 발화하므로
|
|
43
|
+
* 구독자가 emitOps()를 호출하면 memento가 채워진 상태를 본다(계약 1). 반환 함수로 해제.
|
|
44
|
+
*/
|
|
45
|
+
onCommand(listener: CommandListener): () => void;
|
|
46
|
+
private emit;
|
|
47
|
+
private emitCommand;
|
|
48
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DiagramLayout, LogicalModel } from '../core/types';
|
|
2
|
+
import { OpEmission } from './op';
|
|
3
|
+
/** 편집 대상 상태 — 분리된 논리 모델 + 다이어그램 레이아웃 */
|
|
4
|
+
export interface EditorState {
|
|
5
|
+
logical: LogicalModel;
|
|
6
|
+
layout: DiagramLayout;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 명령(Command) — 레거시 EMAction 대응.
|
|
10
|
+
* apply로 상태를 변경하고 invert로 정확히 되돌린다(do/undo 대칭).
|
|
11
|
+
*/
|
|
12
|
+
export interface Command {
|
|
13
|
+
readonly label: string;
|
|
14
|
+
/**
|
|
15
|
+
* 연속 동종 변경(키보드 미세 이동 등)을 하나의 undo 단위로 병합하기 위한 키.
|
|
16
|
+
* 직전 명령의 키와 같으면 스택에서 합쳐진다(시작 상태 복원을 승계). undefined면 병합하지 않음.
|
|
17
|
+
*/
|
|
18
|
+
readonly coalesceKey?: string;
|
|
19
|
+
apply(state: EditorState): void;
|
|
20
|
+
invert(state: EditorState): void;
|
|
21
|
+
/**
|
|
22
|
+
* 자신을 forward/invert op로 파생한다(트랙 B (가)). **apply() 이후 호출 계약**(계약 1) —
|
|
23
|
+
* invert op이 apply가 캡처한 memento에 의존하므로(move=이전 좌표, removeEntity=cascade 대상).
|
|
24
|
+
*
|
|
25
|
+
* 옵셔널 — 점진 마이그레이션 중 미구현 command는 op를 산출하지 않는다. 호스트 영속 경로(stack
|
|
26
|
+
* emit 훅, B-2)는 이 메서드 부재를 런타임 가드로 감지해야 op 누락이 조용히 새지 않는다.
|
|
27
|
+
*/
|
|
28
|
+
emitOps?(state: EditorState): OpEmission;
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DiagramLayout, LogicalModel, ModelId, Point } from './types';
|
|
2
|
+
export interface AutoLayoutGrid {
|
|
3
|
+
cellWidth: number;
|
|
4
|
+
cellHeight: number;
|
|
5
|
+
pad: number;
|
|
6
|
+
headerHeight: number;
|
|
7
|
+
ungroupedCols: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function computeAutoLayout(logical: LogicalModel, layout: DiagramLayout, grid?: Partial<AutoLayoutGrid>): {
|
|
10
|
+
id: ModelId;
|
|
11
|
+
location: Point;
|
|
12
|
+
}[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 물리 DB 타입(DbColumn.dataType) 카탈로그 — 속성의 DB 컬럼 타입 셀렉트 단일 출처.
|
|
3
|
+
*
|
|
4
|
+
* 권위 정의: bluework-entitymodeler-core `net.g1project.bluework.entitymodeler.core.shared.DataType`
|
|
5
|
+
* (JDBC `java.sql.JDBCType` 기반 enum + PostgreSQL 확장 SERIAL·BIG_SERIAL·JSONB). javaTypes.ts가
|
|
6
|
+
* 레거시 JavaType enum을 이식한 것과 대칭 — 저장값(dataType) = enum 상수명이고, 실제 DDL 타입으로의
|
|
7
|
+
* 변환은 호스트 플랫폼(BlueworkPostgreSqlPlatform 등)이 담당한다(예: TIMESTAMP_WITH_TIMEZONE →
|
|
8
|
+
* "TIMESTAMP WITH TIME ZONE", JAVA_OBJECT → "JSONB"). 따라서 카탈로그는 DDL 리터럴이 아니라 enum명을
|
|
9
|
+
* 그대로 담는다 — round-trip 무손실.
|
|
10
|
+
*
|
|
11
|
+
* 두 계층을 분리한다: ALL_DATA_TYPES(저장·round-trip·폴백의 권위)는 enum 전체로 플랫폼 중립을 유지하고,
|
|
12
|
+
* SELECTABLE_DATA_TYPES(셀렉트 후보)는 PG 타겟 기준으로 좁힌다 — ddlutils 1.0 PG 매핑(바이트코드 실측)
|
|
13
|
+
* 대비 DDL 생성이 불확실하거나 의미가 변형되는 타입은 신규 선택에서 뺀다. 기존 데이터는 폴백 합성으로 보존.
|
|
14
|
+
*
|
|
15
|
+
* 표시값은 enum명 원본(value==label). javaType과 달리 표시 변환 매핑이 없다 — attrTypeCell의 PHYSICAL
|
|
16
|
+
* 뷰가 dataType을 그대로 출력하므로 셀렉트도 enum명이어야 뷰가 일관된다. 단순 문자열 목록 + idn(value=
|
|
17
|
+
* label) 패턴(personalInfoItems·updatableItems와 동형).
|
|
18
|
+
*/
|
|
19
|
+
/** DataType enum 전체 이식(정의 순서 보존). round-trip·폴백 합성의 권위 목록 — 셀렉트 후보는 아래서 필터. */
|
|
20
|
+
export declare const ALL_DATA_TYPES: readonly string[];
|
|
21
|
+
/** DB 타입 셀렉트 후보(단일 출처) — enum 전체에서 비컬럼 추상타입을 뺀 실 컬럼 타입. */
|
|
22
|
+
export declare const SELECTABLE_DATA_TYPES: readonly string[];
|
|
23
|
+
/** 저장값(enum명) → 표시 라벨. 미등록 값은 그대로 반환(폴백). 셀렉트 label-provider·attrTypeCell 공용. */
|
|
24
|
+
export declare function dbTypeLabel(value: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* 길이(length)를 지정해야 의미가 완결되는 가변/고정 길이 타입 — 누락 시 DB 기본/암묵 길이로 떨어져
|
|
27
|
+
* 의도와 어긋날 수 있다(예: VARCHAR 무길이). 검증 CHK-TYPE-2의 단일 출처(타입 메타데이터는 이 카탈로그 소유).
|
|
28
|
+
*
|
|
29
|
+
* NUMERIC·DECIMAL은 precision을 length로 표현 — 누락 시 정밀도 미정의이므로 동일하게 포함한다.
|
|
30
|
+
* scale은 누락 시 0으로 떨어지는 게 정수형 의미로 정당해 **필수로 보지 않는다**(length만 검사).
|
|
31
|
+
* TEXT류(LONGVARCHAR·CLOB·BLOB)·고정 폭 타입(INTEGER·DATE·BOOLEAN 등)은 길이 무의미라 제외.
|
|
32
|
+
*/
|
|
33
|
+
export declare const LENGTH_REQUIRED_DATA_TYPES: ReadonlySet<string>;
|
|
34
|
+
/**
|
|
35
|
+
* dataType 셀렉트 items — 실 컬럼 후보 + 현재값 폴백 합성.
|
|
36
|
+
*
|
|
37
|
+
* open-bluesea BSSelect는 model-value가 items에 없으면 placeholder로 떨어뜨려 값이 빈칸으로 보인다(표시
|
|
38
|
+
* 손상). 현재값이 후보 밖(비후보 추상타입·미지 레거시값)이면 맨 앞에 합성해 현 상태를 보존 표시한다 —
|
|
39
|
+
* 자유 선택지가 아니라 "현재 보유 값" 표시용. 빈값(미설정)은 합성하지 않고 placeholder에 맡긴다.
|
|
40
|
+
*
|
|
41
|
+
* selectable은 어포던스(드롭다운 후보)와 검증(CHK-TYPE-1 `ctx.selectableDataTypes`)의 단일 출처 정렬용 —
|
|
42
|
+
* 호스트가 타겟 다이얼렉트 셋을 주입하면 controller가 그 값을 넘겨 둘이 어긋나지 않게 한다. 미주입(undefined)
|
|
43
|
+
* 이면 코어 상수 SELECTABLE_DATA_TYPES(PG 기준)로 폴백 = dev·미통합 환경 무회귀. Set 주입 시 순서는 삽입 순서.
|
|
44
|
+
*/
|
|
45
|
+
export declare function dbTypeSelectItems(currentDataType: string, selectable?: ReadonlySet<string> | readonly string[]): string[];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Association, Attribute, DisplayMode, PredefinedCustomTypeCatalog } from './types';
|
|
2
|
+
export interface JavaTypeDef {
|
|
3
|
+
/** 저장값 = 레거시 enum 상수명. Attribute.type에 그대로 들어간다. */
|
|
4
|
+
value: string;
|
|
5
|
+
/** 표시값 = 레거시 enum 필드(getSimpleName). 셀렉트 라벨·다이어그램 타입 칸 표기. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** 프리미티브의 박싱 타입(레거시 2번째 인자). 코드젠 보존용. */
|
|
8
|
+
boxed?: string;
|
|
9
|
+
}
|
|
10
|
+
/** CustomType 마커 — Attribute.type이 이 값이면 실제 타입명은 Attribute.customType에 있다. */
|
|
11
|
+
export declare const CUSTOM_TYPE_VALUE = "CustomType";
|
|
12
|
+
/** ⑤ 파생 타입 마커 — groupCode 지정 시 Attribute.type이 이 값으로 자동 설정된다(드롭다운 자유 선택 아님). */
|
|
13
|
+
export declare const GROUP_CODE_ENUM_VALUE = "GroupCodeEnum";
|
|
14
|
+
/** 신규 속성 생성·파생 타입 해제 시 환원할 기본 스칼라 타입(생성 기본값과 동일 출처). */
|
|
15
|
+
export declare const DEFAULT_JAVA_TYPE = "String";
|
|
16
|
+
/** 일반 자바 타입(셀렉트 드롭다운 후보). 레거시 enum 정의 순서 보존. embeddable·predef는 제외. */
|
|
17
|
+
export declare const JAVA_TYPES: readonly JavaTypeDef[];
|
|
18
|
+
/** 저장값 → 표시 라벨. 미등록 값(임베더블 타입명·커스텀명·미지 값)은 그대로 반환(폴백). */
|
|
19
|
+
export declare function javaTypeLabel(value: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* ① 스칼라 자바 타입 셀렉트 후보(단일 출처). JAVA_TYPES에서 비후보(⑤·레거시 표시용)를 빼고
|
|
22
|
+
* ④ CustomType은 "사용자정의" 안내 라벨로 노출. ②embeddable·③customtype은 애초에 JAVA_TYPES에 없음.
|
|
23
|
+
*/
|
|
24
|
+
export declare const SELECTABLE_JAVA_TYPES: readonly JavaTypeDef[];
|
|
25
|
+
/**
|
|
26
|
+
* 타입 셀렉트 items — ① 스칼라 후보 + ③ 주입 customtype 카탈로그 + 현재값 폴백 합성.
|
|
27
|
+
*
|
|
28
|
+
* ③ `predefinedCustomTypes`(호스트 주입)는 ① 후보 뒤에 병합 노출한다 — 단일 컬럼이라 ①과 컬럼 구조가
|
|
29
|
+
* 같고(②embeddable과 달리 부수효과 없음) ④ CustomType과 동질이므로 별도 진입이 아니라 같은 셀렉트에 둔다.
|
|
30
|
+
*
|
|
31
|
+
* open-bluesea BSSelect는 model-value가 items에 없으면 placeholder로 떨어뜨려 값이 빈칸으로 보인다(표시
|
|
32
|
+
* 손상). 현재값이 후보(① + 주입 ③) 밖(②임베더블 타입명·미주입 ③ customtype명·⑤ GroupCodeEnum·미지
|
|
33
|
+
* 레거시 값)이면 라벨과 함께 맨 앞에 합성해 현 상태를 보존 표시한다 — 자유 선택지가 아니라 "현재 보유 값"
|
|
34
|
+
* 표시용(groupCode 비활성 셀렉트의 GroupCodeEnum, ③ 카탈로그 미주입 시 customtype-typed 속성 포함).
|
|
35
|
+
*/
|
|
36
|
+
export declare function typeSelectItems(currentType: string, predefinedCustomTypes?: PredefinedCustomTypeCatalog): JavaTypeDef[];
|
|
37
|
+
/**
|
|
38
|
+
* EMBED 표시 속성의 컬렉션 모드(`@ElementCollection`)를 판정한다 — 컬렉션이면 `collectionType`(기본
|
|
39
|
+
* LIST), 단일(`@Embedded`)이거나 EMBED가 아니면 undefined. 판정 권위는 임베더블을 가리키는 end의
|
|
40
|
+
* multiplicity(결정 3: 별도 boolean 플래그 없음). 컬렉션 모드는 owner에 평탄화 컬럼이 없어(dbAttrs=[])
|
|
41
|
+
* isEmbedAttr=false라 단일 EMBED와 타입 칸이 구분되지 않으므로, 이 신호로 attrTypeCell이 List<>/Set<>로
|
|
42
|
+
* 래핑해 시각 구분한다. 순수 함수(뷰 무관) — Diagram 노드·Explorer 트리 공용.
|
|
43
|
+
*/
|
|
44
|
+
export declare function embedCollectionType(attr: Attribute, associations: Association[]): 'LIST' | 'SET' | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* 속성 타입 칸 표시 — 모델은 type(자바 타입)·dbAttrs[].dataType(물리 DB 타입)을 분리 보관하므로
|
|
47
|
+
* 뷰 모드별로 맞는 출처를 고른다(결정 2026-06-26):
|
|
48
|
+
* CLASS = 자바 타입 라벨 / PHYSICAL·LOGICAL_PHYSICAL = 물리 DB 타입 / LOGICAL = 숨김.
|
|
49
|
+
* CustomType 마커는 실제 타입명(customType)을, 임베드 참조 헤더는 임베더블 타입명을 보인다
|
|
50
|
+
* (임베드의 물리 컬럼 타입은 펼침 서브행이 담당). Diagram 노드·Explorer 트리 공용.
|
|
51
|
+
*/
|
|
52
|
+
export declare function attrTypeCell(mode: DisplayMode, attr: Attribute, collectionType?: 'LIST' | 'SET'): string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Association, Attribute, DbColumn, LogicalModel, ModelId } from './types';
|
|
2
|
+
/** modelId 생성기 — 순수성/테스트 결정성을 위해 주입 가능. 기본은 crypto.randomUUID. */
|
|
3
|
+
export type IdFactory = () => ModelId;
|
|
4
|
+
/**
|
|
5
|
+
* 한 관계가 자식에 요구하는 FK 속성의 "원하는 상태" 스펙.
|
|
6
|
+
* modelId가 없다(매칭 후 reconcile이 신규에만 부여). 매칭 키 = associationRef + sourceAttributeRef.
|
|
7
|
+
*/
|
|
8
|
+
export interface ForeignAttributeSpec {
|
|
9
|
+
associationRef: ModelId;
|
|
10
|
+
sourceAttributeRef: ModelId;
|
|
11
|
+
name: string;
|
|
12
|
+
type: string;
|
|
13
|
+
identifier: boolean;
|
|
14
|
+
notNull: boolean;
|
|
15
|
+
/** 부모 식별자의 컬럼을 미러한 dbAttrs (modelId 없음 — reconcile이 부여) */
|
|
16
|
+
dbAttrs: Omit<DbColumn, 'modelId'>[];
|
|
17
|
+
}
|
|
18
|
+
export interface ReconcilePlan {
|
|
19
|
+
/** 신규 생성할 FK 속성 (modelId·dbAttr modelId 부여됨, order 포함) */
|
|
20
|
+
add: Attribute[];
|
|
21
|
+
/** 기존 FK 속성에 적용할 부분 패치 (부모와 동기화돼야 하는 필드만) */
|
|
22
|
+
update: {
|
|
23
|
+
attributeId: ModelId;
|
|
24
|
+
patch: Partial<Attribute>;
|
|
25
|
+
}[];
|
|
26
|
+
/** 더 이상 근거 관계가 없어 제거할 FK 속성 */
|
|
27
|
+
remove: ModelId[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 한 관계(association)가 자식(end2)에 만들어야 할 FK 속성 스펙들을 계산.
|
|
31
|
+
* 부모(end1)의 현재 유효 식별자(자기 PK + 전파받은 FK 식별자)를 order순으로 미러한다.
|
|
32
|
+
* self-association은 식별 불가 — identifier를 강제로 false로 둔다(INV-3).
|
|
33
|
+
*/
|
|
34
|
+
export declare function computeForeignAttributes(logical: LogicalModel, association: Association): ForeignAttributeSpec[];
|
|
35
|
+
/**
|
|
36
|
+
* 자식 엔터티의 현재 FK 속성을, 들어오는 모든 관계가 요구하는 desired 집합과 맞춘다(diff).
|
|
37
|
+
* - desired에만 있음 → add (신규 modelId 부여, 기존 최대 order 뒤에 append)
|
|
38
|
+
* - 양쪽에 있음 → 동기화 필드 차이만 update
|
|
39
|
+
* - current에만 있음(근거 관계 소멸) → remove
|
|
40
|
+
* 멱등(INV-5): 이미 맞춰진 상태에서 다시 호출하면 빈 계획을 돌려준다.
|
|
41
|
+
*/
|
|
42
|
+
export declare function reconcileForeignAttributes(logical: LogicalModel, childEntityId: ModelId, idFactory?: IdFactory): ReconcilePlan;
|
|
43
|
+
/**
|
|
44
|
+
* changedEntityId의 식별자 변경이 영향을 주는 모든 후손 자식의 reconcile 계획.
|
|
45
|
+
* A→B→C 연쇄와 사이클(A→B→A)을 visited 가드로 안전 종료(INV-6).
|
|
46
|
+
* 클론에 단계별로 적용하며 다음 단계 입력을 갱신하므로, 반환 계획은 *원본* logical 기준이다.
|
|
47
|
+
* self-association은 비식별이라 자식 식별자를 바꾸지 않아 더 전파되지 않는다(자연 종료).
|
|
48
|
+
*/
|
|
49
|
+
export declare function planPropagation(logical: LogicalModel, changedEntityId: ModelId, idFactory?: IdFactory): Map<ModelId, ReconcilePlan>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Multiplicity, Point } from './types';
|
|
2
|
+
export type MarkerMode = 'db' | 'class';
|
|
3
|
+
/** 한 끝(AssociationEnd)의 표기 결정에 필요한 의미 정보. */
|
|
4
|
+
export interface EndSemantics {
|
|
5
|
+
multiplicity: Multiplicity;
|
|
6
|
+
navigable: boolean;
|
|
7
|
+
composition: boolean;
|
|
8
|
+
/** 반대쪽 끝의 navigable — 단방향(this && !other)일 때만 네비 화살표를 그린다. */
|
|
9
|
+
otherNavigable: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface Segment {
|
|
12
|
+
x1: number;
|
|
13
|
+
y1: number;
|
|
14
|
+
x2: number;
|
|
15
|
+
y2: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Circle {
|
|
18
|
+
cx: number;
|
|
19
|
+
cy: number;
|
|
20
|
+
r: number;
|
|
21
|
+
}
|
|
22
|
+
export interface Polygon {
|
|
23
|
+
points: Point[];
|
|
24
|
+
}
|
|
25
|
+
export interface EndMarkers {
|
|
26
|
+
/** 실선 stroke — 까마귀발 갈래·바·스파인·네비 화살표. */
|
|
27
|
+
lines: Segment[];
|
|
28
|
+
/** 중공 원(fill none) — 선택성(optional) 표기. */
|
|
29
|
+
circles: Circle[];
|
|
30
|
+
/** 채워진 다각형(fill=stroke) — 컴포지션 마름모. */
|
|
31
|
+
polygons: Polygon[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 끝점 표기가 끝점에서 진출 방향으로 차지하는 최대 거리(선택성 원의 바깥 둘레, db 모드가 최대).
|
|
35
|
+
* 직각 라우팅이 이보다 짧은 stub으로 꺾으면 표기가 코너에 얹혀 바(one tick)가 진행 반대쪽으로
|
|
36
|
+
* 삐져나오고 선택성 원이 경로를 벗어나 뜬다 → 호출측은 stub을 이 거리보다 길게 잡아야 한다.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MARKER_REACH: number;
|
|
39
|
+
/**
|
|
40
|
+
* 한 끝점의 표기 마커를 산출한다.
|
|
41
|
+
* @param end 엔티티 경계의 끝점 (레거시 point1)
|
|
42
|
+
* @param toward 그 끝이 향하는 다음 점 (레거시 point2). 직각 모드는 stub 방향, 직선 모드는 다음 waypoint/반대끝.
|
|
43
|
+
*/
|
|
44
|
+
export declare function endMarkers(end: Point, toward: Point, sem: EndSemantics, mode: MarkerMode): EndMarkers;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Association, DiagramLayout, Entity, Geo, LogicalGroup, LogicalModel, ModelId, Note, Point, Style } from './types';
|
|
2
|
+
export interface ResolvedEntity {
|
|
3
|
+
entity: Entity;
|
|
4
|
+
geo: Geo;
|
|
5
|
+
collapsed: boolean;
|
|
6
|
+
/** 이 엔티티가 속한 그룹(있으면) — 캔버스가 parent 노드로 배치 */
|
|
7
|
+
groupRef?: ModelId;
|
|
8
|
+
/** 헤더 바 색상 등 (레이아웃 style 참조 통과 — swatch 변경 시 computed 무효화) */
|
|
9
|
+
style?: Style;
|
|
10
|
+
/** 속성별 강조 색상 (attribute modelId 참조) */
|
|
11
|
+
attributeStyles?: Record<ModelId, Style>;
|
|
12
|
+
/** 메서드별 강조 색상 (operation modelId 참조) */
|
|
13
|
+
operationStyles?: Record<ModelId, Style>;
|
|
14
|
+
}
|
|
15
|
+
export interface ResolvedAssociation {
|
|
16
|
+
association: Association;
|
|
17
|
+
waypoints: Point[];
|
|
18
|
+
sourceColumnRef?: ModelId;
|
|
19
|
+
targetColumnRef?: ModelId;
|
|
20
|
+
}
|
|
21
|
+
export interface ResolvedGroup {
|
|
22
|
+
group: LogicalGroup;
|
|
23
|
+
geo: Geo;
|
|
24
|
+
/** 그룹 배경 색상 등 (레이아웃 style 참조 통과 — swatch 변경 시 computed 무효화) */
|
|
25
|
+
style?: Style;
|
|
26
|
+
}
|
|
27
|
+
export interface ResolvedNoteConnection {
|
|
28
|
+
noteRef: ModelId;
|
|
29
|
+
targetRef: ModelId;
|
|
30
|
+
waypoints: Point[];
|
|
31
|
+
}
|
|
32
|
+
export interface ResolvedNote {
|
|
33
|
+
note: Note;
|
|
34
|
+
/**
|
|
35
|
+
* 이 노트가 시각적으로 포함된 그룹(있으면) — 캔버스가 parent 노드로 배치(상대좌표 렌더).
|
|
36
|
+
* 엔티티 멤버십(LogicalGroup.memberEntityRefs, 논리)과 달리 노트 멤버십은
|
|
37
|
+
* GroupLayout.memberNoteRefs(레이아웃)에서 온다. note.geo는 절대좌표(깊은복제) 유지.
|
|
38
|
+
*/
|
|
39
|
+
groupRef?: ModelId;
|
|
40
|
+
}
|
|
41
|
+
export interface ResolvedDiagram {
|
|
42
|
+
entities: ResolvedEntity[];
|
|
43
|
+
associations: ResolvedAssociation[];
|
|
44
|
+
groups: ResolvedGroup[];
|
|
45
|
+
notes: ResolvedNote[];
|
|
46
|
+
/** 노트 → 대상 엔티티 연결선 (대상이 존재하는 것만; dangling은 prune) */
|
|
47
|
+
noteConnections: ResolvedNoteConnection[];
|
|
48
|
+
/** 레이아웃에만 있던(논리에 없는) 정리 대상 항목 */
|
|
49
|
+
prunedEntityRefs: ModelId[];
|
|
50
|
+
prunedAssociationRefs: ModelId[];
|
|
51
|
+
}
|
|
52
|
+
export interface AutoLayoutOptions {
|
|
53
|
+
startX: number;
|
|
54
|
+
startY: number;
|
|
55
|
+
columnGap: number;
|
|
56
|
+
rowGap: number;
|
|
57
|
+
perRow: number;
|
|
58
|
+
defaultSize: {
|
|
59
|
+
width: number;
|
|
60
|
+
height: number;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export declare function resolveDiagram(logical: LogicalModel, layout: DiagramLayout, autoLayoutOptions?: Partial<AutoLayoutOptions>): ResolvedDiagram;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Point } from './types';
|
|
2
|
+
export type Side = 'left' | 'right' | 'top' | 'bottom';
|
|
3
|
+
/** 핸들 측면이 가리키는 "바깥" 단위 방향 (진출/진입 stub 방향) */
|
|
4
|
+
export declare function sideDir(side: Side): Point;
|
|
5
|
+
/**
|
|
6
|
+
* source(측면) → (waypoints…) → target(측면) 를 직각 세그먼트로 잇는 SVG path.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildOrthogonalPath(source: Point, sourceSide: Side, waypoints: Point[], target: Point, targetSide: Side, stub?: number): string;
|
|
9
|
+
/** 직각 path 중점 affordance — 꺾인 직선 세그먼트마다 중점 + 삽입 span 인덱스. */
|
|
10
|
+
export interface SegmentMid {
|
|
11
|
+
point: Point;
|
|
12
|
+
/** waypoint 삽입 인덱스 (insertPoint의 segIndex) */
|
|
13
|
+
segIndex: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 직각 path의 각 직선 세그먼트 중점 — straight 모드의 segmentMidpoints에 대응하는 직각판.
|
|
17
|
+
* 제어점 직선 중점이 아니라 실제 그려지는 꺾은선 위 점이라 affordance가 선 위에 놓인다.
|
|
18
|
+
*/
|
|
19
|
+
export declare function orthogonalMidpoints(source: Point, sourceSide: Side, waypoints: Point[], target: Point, targetSide: Side, stub?: number): SegmentMid[];
|
|
20
|
+
/**
|
|
21
|
+
* 셀프 연관(source===target) 루프 path — 같은 변(보통 우측)의 두 지점에서 바깥으로
|
|
22
|
+
* `extent`만큼 나갔다 직각으로 돌아오는 사각 루프. straight/orthogonal 두 모드 공통으로 쓴다
|
|
23
|
+
* (self는 직선 한 가닥이면 변에 붙은 선으로 붕괴하므로 항상 직각 루프로 그린다).
|
|
24
|
+
*
|
|
25
|
+
* source.y와 target.y가 충분히 벌어져 있어야 루프로 보인다 — 간격 보장은 호출부
|
|
26
|
+
* (useFloatingRoute의 self 분기)가 담당한다.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildSelfLoopPath(source: Point, target: Point, extent?: number): string;
|
|
29
|
+
/**
|
|
30
|
+
* 직선 라우팅 — source → (waypoints…) → target 를 곧은 선분으로 잇는다.
|
|
31
|
+
* waypoint가 없으면 두 끝점을 잇는 단일 직선(대각선). 기본 라우팅 모드.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildStraightPath(source: Point, waypoints: Point[], target: Point): string;
|
|
34
|
+
export type RoutingMode = 'straight' | 'orthogonal';
|
|
35
|
+
export interface Rect {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* rect 중심에서 `toward` 방향으로 나가는 반직선이 rect 경계와 만나는 점 + 그 변(side).
|
|
43
|
+
* 완전 floating 끝점(노트 연결·비앵커 관계)에 사용 — 노드를 옮기면 끝점이 경계를 따라 이동한다.
|
|
44
|
+
*/
|
|
45
|
+
export declare function rectExitPoint(rect: Rect, toward: Point): {
|
|
46
|
+
point: Point;
|
|
47
|
+
side: Side;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* 컬럼 앵커 끝점 — y는 지정 행(rowY)에 고정, 좌/우 중 상대(towardX)를 향한 변에 부착.
|
|
51
|
+
* "행 유지 + 측면 동적": 어느 속성의 FK인지(행)는 보존하되 노드를 옮기면 측면이 자동으로 뒤집힌다.
|
|
52
|
+
*/
|
|
53
|
+
export declare function anchoredEdgePoint(rect: Rect, rowY: number, towardX: number): {
|
|
54
|
+
point: Point;
|
|
55
|
+
side: Side;
|
|
56
|
+
};
|
|
57
|
+
/** 폴리라인 중점들(제어점 사이 가운데) — 더블클릭 waypoint 추가 affordance */
|
|
58
|
+
export declare function segmentMidpoints(source: Point, waypoints: Point[], target: Point): Point[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DbColumn, ModelId } from './types';
|
|
2
|
+
/** SHARED_REF 컬럼의 파생 투영값. insertable/updatable는 정의상 항상 false. */
|
|
3
|
+
export interface ResolvedSharedColumn {
|
|
4
|
+
/** 타깃 컬럼의 물리명(이 컬럼이 read-only로 투영되는 실제 물리 컬럼). */
|
|
5
|
+
physicalName: string;
|
|
6
|
+
insertable: false;
|
|
7
|
+
updatable: false;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 같은 엔터티의 컬럼들을 modelId로 인덱싱 — picker 후보 해석·SHARED_REF 타깃 조회 공용 인덱스.
|
|
11
|
+
* EMBED 펼친 dbAttrs를 포함한 전 컬럼을 평탄화하므로 SHARED_REF 타깃이 임베드 내부여도 조회된다.
|
|
12
|
+
*/
|
|
13
|
+
export declare function indexColumnsByModelId(columns: readonly DbColumn[]): Map<ModelId, DbColumn>;
|
|
14
|
+
/**
|
|
15
|
+
* SHARED_REF 컬럼의 파생 투영을 계산. OWN(sharedColumnRef 부재)이거나 타깃이 dangling(인덱스에
|
|
16
|
+
* 없음)이면 `null` — 호출자는 col.sharedColumnRef 존재 여부로 OWN/SHARED_REF를 구분하고, 이
|
|
17
|
+
* 헬퍼는 "해석 가능한 투영값"만 반환한다.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveSharedColumn(col: DbColumn, columnsById: ReadonlyMap<ModelId, DbColumn>): ResolvedSharedColumn | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL 예약어 베이스라인 — 물리 식별자(테이블·컬럼·인덱스명)가 예약어와 충돌하는지 검사하는 단일 출처.
|
|
3
|
+
*
|
|
4
|
+
* 검증 CHK-NAME-6(`validation.ts`)이 `ctx.reservedWords`로 받아 쓰며, 호스트가 미주입하면 규칙은 skip된다
|
|
5
|
+
* (selectableDataTypes와 동형 — ctx 게이트). 이 상수는 호스트가 주입할 "베이스라인 시드"이자 dev 하니스의
|
|
6
|
+
* 폴백이다. CHK-NAME-6은 `physicalName.toUpperCase()`로 비교하므로 모든 원소는 **대문자**여야 한다.
|
|
7
|
+
*
|
|
8
|
+
* 권위 정의: PostgreSQL 공식 문서 Appendix C "SQL Key Words"
|
|
9
|
+
* (https://www.postgresql.org/docs/current/sql-keywords-appendix.html). 본 프로젝트는 PG 단일 타겟이므로
|
|
10
|
+
* (dbTypes.ts SELECTABLE_DATA_TYPES가 PG 기준인 것과 대칭) PG 키워드 표를 정본으로 삼는다. 멀티 다이얼렉트가
|
|
11
|
+
* 실재하면 다이얼렉트별 셋을 호스트가 확장 주입한다(코어는 PG 베이스라인만 안다).
|
|
12
|
+
*
|
|
13
|
+
* 식별자로 따옴표 없이 쓸 수 없는 두 카테고리를 합집합으로 담는다:
|
|
14
|
+
* (1) reserved — 컬럼·테이블·함수·타입명 어디에도 못 쓰는 완전 예약어.
|
|
15
|
+
* (2) reserved (can be function or type name) — 함수/타입명은 되지만 **컬럼·테이블명은 못 쓴다**.
|
|
16
|
+
* CHK-NAME-6의 검사 대상이 테이블·컬럼·인덱스 식별자라 두 카테고리 모두 충돌 후보다. non-reserved 계열은
|
|
17
|
+
* 식별자로 쓸 수 있어 제외한다(노이즈 방지).
|
|
18
|
+
*
|
|
19
|
+
* 버전 주: SYSTEM_USER는 PostgreSQL 16에서 예약어로 추가됐다. 표는 마이너 버전 간 사실상 안정적이다.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* 물리 식별자로 사용 불가한 PostgreSQL 예약어 합집합(대문자). CHK-NAME-6 `ctx.reservedWords`의 베이스라인.
|
|
23
|
+
* SELECTABLE_DATA_TYPES와 동형으로 "중립명 + PG 기준(문서)" — 호스트가 다이얼렉트 셋으로 스왑/확장한다.
|
|
24
|
+
*/
|
|
25
|
+
export declare const SQL_RESERVED_WORDS: ReadonlySet<string>;
|