@g1cloud/entity-modeler-next 5.0.0-beta.4 → 5.0.0-beta.41

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.
Files changed (38) hide show
  1. package/dist/adapter/diagramAdapter.d.ts +6 -0
  2. package/dist/adapter/healBackfill.d.ts +38 -0
  3. package/dist/agent/resolver.d.ts +140 -4
  4. package/dist/agent/symbolicOp.d.ts +9 -1
  5. package/dist/command/commands.d.ts +4 -3
  6. package/dist/command/op.d.ts +35 -1
  7. package/dist/command/opSync.d.ts +11 -1
  8. package/dist/command/stack.d.ts +11 -1
  9. package/dist/core/associationNav.d.ts +20 -0
  10. package/dist/core/attributeOrder.d.ts +9 -0
  11. package/dist/core/columnResolve.d.ts +22 -0
  12. package/dist/core/fkDerived.d.ts +37 -0
  13. package/dist/core/javaTypes.d.ts +5 -0
  14. package/dist/core/opSubject.d.ts +54 -0
  15. package/dist/core/projectActionLog.d.ts +7 -10
  16. package/dist/core/projectSeqDiff.d.ts +41 -0
  17. package/dist/core/propagation.d.ts +19 -2
  18. package/dist/core/quickFix.d.ts +9 -4
  19. package/dist/core/resolve.d.ts +0 -3
  20. package/dist/core/scaffoldJava.d.ts +30 -1
  21. package/dist/core/stereotype.d.ts +2 -0
  22. package/dist/core/types.d.ts +7 -0
  23. package/dist/core/validation.d.ts +1 -13
  24. package/dist/editor/controller.d.ts +34 -20
  25. package/dist/entity-modeler-next.css +1 -1
  26. package/dist/entity-modeler.js +15438 -13269
  27. package/dist/entity-modeler.umd.cjs +30 -26
  28. package/dist/i18n/ko.d.ts +54 -1
  29. package/dist/index.d.ts +28 -23
  30. package/dist/view/DiagramCanvas.vue.d.ts +4 -0
  31. package/dist/view/HistoryPanel.vue.d.ts +3 -0
  32. package/dist/view/diffOverlay.d.ts +14 -0
  33. package/dist/view/indexColumnRef.d.ts +5 -0
  34. package/dist/view/nodeInternals.d.ts +15 -0
  35. package/dist/view/opConflictNotice.d.ts +8 -6
  36. package/dist/view/swatches.d.ts +3 -2
  37. package/dist/view/useAttributeEditing.d.ts +82 -0
  38. package/package.json +6 -6
package/dist/i18n/ko.d.ts CHANGED
@@ -47,6 +47,10 @@ export declare const ko: {
47
47
  readonly 'em.panel.expandAll': "모두 펼치기";
48
48
  readonly 'em.panel.lockedBanner': "편집 잠김 — 이동·수정·삭제 차단";
49
49
  readonly 'em.panel.openNamed': "{name} 열기";
50
+ readonly 'em.notice.readOnly': "조회 모드에서는 편집할 수 없습니다";
51
+ readonly 'em.notice.entityLocked': "잠긴 엔티티입니다 — 잠금 해제 후 편집하세요";
52
+ readonly 'em.notice.groupLocked': "잠긴 그룹입니다 — 잠금 해제 후 편집하세요";
53
+ readonly 'em.notice.assocLocked': "잠긴 엔티티에 연결된 관계입니다 — 잠금 해제 후 편집하세요";
50
54
  readonly 'em.validation.title': "검증";
51
55
  readonly 'em.validation.noIssues': "검증 이슈가 없습니다.";
52
56
  readonly 'em.validation.noVisibleIssues': "표시할 이슈가 없습니다 (필터 적용 중).";
@@ -74,6 +78,7 @@ export declare const ko: {
74
78
  readonly 'em.export.copyFailed': "복사에 실패했습니다.";
75
79
  readonly 'em.import.title': "가져오기";
76
80
  readonly 'em.import.placeholder': "SQL DDL · Mermaid ER · JSON 백업을 붙여넣으세요.";
81
+ readonly 'em.import.formatGroup': "입력 형식";
77
82
  readonly 'em.import.formatAuto': "자동 감지";
78
83
  readonly 'em.import.formatMermaid': "Mermaid ER";
79
84
  readonly 'em.import.formatDdl': "SQL DDL";
@@ -88,6 +93,11 @@ export declare const ko: {
88
93
  readonly 'em.shortcuts.title': "키보드 단축키";
89
94
  readonly 'em.shortcuts.groupEdit': "편집";
90
95
  readonly 'em.shortcuts.groupMove': "이동 · 정렬";
96
+ readonly 'em.shortcuts.groupExplorer': "탐색기";
97
+ readonly 'em.shortcuts.descExplorerSearch': "탐색기 검색으로 포커스";
98
+ readonly 'em.shortcuts.descExplorerNav': "트리 이동 (←→ 접기·펼치기)";
99
+ readonly 'em.shortcuts.descExplorerSelect': "항목 선택 + 캔버스 이동";
100
+ readonly 'em.shortcuts.descExplorerDetail': "엔티티 상세 편집 열기";
91
101
  readonly 'em.shortcuts.groupOther': "기타";
92
102
  readonly 'em.shortcuts.keyArrows': "방향키";
93
103
  readonly 'em.shortcuts.keyRightClick': "우클릭";
@@ -120,6 +130,14 @@ export declare const ko: {
120
130
  readonly 'em.common.inherit': "기본(따름)";
121
131
  readonly 'em.common.noneParen': "(없음)";
122
132
  readonly 'em.swatch.none': "없음";
133
+ readonly 'em.swatch.red': "빨강";
134
+ readonly 'em.swatch.amber': "주황";
135
+ readonly 'em.swatch.green': "초록";
136
+ readonly 'em.swatch.teal': "청록";
137
+ readonly 'em.swatch.blue': "파랑";
138
+ readonly 'em.swatch.indigo': "남색";
139
+ readonly 'em.swatch.violet': "보라";
140
+ readonly 'em.swatch.pink': "분홍";
123
141
  readonly 'em.inspector.ctxEntityAttrs': "엔티티 · {name} › 속성 · {n}개";
124
142
  readonly 'em.inspector.ctxEntityDivider': "엔티티 · {name} › 구분선";
125
143
  readonly 'em.inspector.ctxEntityAttr': "엔티티 · {name} › 속성 · {attr}";
@@ -135,6 +153,8 @@ export declare const ko: {
135
153
  readonly 'em.assoc.navFieldName': "연관 필드명(nav)";
136
154
  readonly 'em.assoc.cascadeAllNote': "ALL이 개별 cascade를 모두 포함합니다 (CHK-JPA-5).";
137
155
  readonly 'em.assoc.orphanRemovalNote': "반대편이 컬렉션(@ManyToOne/@ManyToMany)이라 orphanRemoval이 무효입니다 (CHK-JPA-14).";
156
+ readonly 'em.assoc.navRequiredNote': "이 방향에 nav 속성이 없어(navigable 꺼짐) cascade·fetch가 적용되지 않습니다.";
157
+ readonly 'em.assoc.ownerNavFixed': "JPA 소유측 참조(@ManyToOne)는 관계 존재와 동치라 항상 켜집니다 — 참조 없는 FK는 관계 대신 일반 컬럼으로 모델링하세요.";
138
158
  readonly 'em.assoc.orderByPlaceholder': "예: name ASC";
139
159
  readonly 'em.assoc.jpaDetails': "JPA 상세";
140
160
  readonly 'em.embed.legend': "임베드";
@@ -169,6 +189,10 @@ export declare const ko: {
169
189
  readonly 'em.attr.nameless': "(이름 없음)";
170
190
  readonly 'em.attr.selectHint': "위 목록에서 속성을 선택하면 편집 폼이 표시됩니다.";
171
191
  readonly 'em.attr.inverseNavHint': "역방향 연관관계 필드 — 물리 컬럼이 없습니다(대상 엔티티 참조).";
192
+ readonly 'em.attr.fkDerivedNote': "외래키(FK)에서 파생된 컬럼입니다 — 형상은 부모 PK를 따르며, 변경은 관계선·식별관계에서 하세요.";
193
+ readonly 'em.attr.scaleTypeHint': "소수부(scale)는 NUMERIC·DECIMAL 타입에만 적용됩니다.";
194
+ readonly 'em.attr.embedFixedHint': "임베더블 정의에서 고정된 값입니다.";
195
+ readonly 'em.attr.embedSharedHint': "다른 컬럼과 공유하는 통화 컬럼입니다 — 대상에서 파생(읽기 전용).";
172
196
  readonly 'em.attr.namePlaceholder': "이름";
173
197
  readonly 'em.attr.typePlaceholder': "타입";
174
198
  readonly 'em.attr.customTypePlaceholder': "커스텀 타입명";
@@ -217,7 +241,6 @@ export declare const ko: {
217
241
  readonly 'em.attr.empty': "속성 없음 — '추가'로 생성";
218
242
  readonly 'em.op.body': "본문";
219
243
  readonly 'em.op.bodyDirty': "본문 ●";
220
- readonly 'em.op.descPlaceholderKo': "설명(ko)";
221
244
  readonly 'em.op.empty': "오퍼레이션 없음 — '추가'로 생성";
222
245
  readonly 'em.index.delete': "인덱스 삭제";
223
246
  readonly 'em.index.empty': "인덱스 없음 — '추가'로 생성";
@@ -234,6 +257,7 @@ export declare const ko: {
234
257
  readonly 'em.index.noColumns': "컬럼 없음 — 좌측에서 추가";
235
258
  readonly 'em.index.selectPrompt': "인덱스를 선택하거나 추가하세요.";
236
259
  readonly 'em.palette.autoLayout': "자동 배치";
260
+ readonly 'em.cmd.title': "명령 팔레트";
237
261
  readonly 'em.cmd.placeholder': "엔티티로 이동하거나 명령 실행…";
238
262
  readonly 'em.cmd.sectionGoto': "이동";
239
263
  readonly 'em.cmd.sectionActions': "명령";
@@ -241,8 +265,13 @@ export declare const ko: {
241
265
  readonly 'em.cmd.groupTag': "그룹";
242
266
  readonly 'em.canvas.emptyTitle': "빈 다이어그램입니다";
243
267
  readonly 'em.canvas.emptyHint': "캔버스를 <strong>우클릭</strong>하거나 좌하단 <strong>+</strong> 버튼으로 첫 엔티티를 추가하세요.";
268
+ readonly 'em.canvas.emptyConnectHint': "엔티티를 두 개 이상 만들면, 엔티티 가장자리에서 <strong>드래그</strong>해 관계를 연결할 수 있어요.";
244
269
  readonly 'em.canvas.emptyShortcutHint': "단축키 도움말은 <kbd>?</kbd> 키";
245
270
  readonly 'em.canvas.emptyReadonly': "표시할 엔티티가 없습니다";
271
+ readonly 'em.canvas.exportFailed': "내보내기에 실패했습니다";
272
+ readonly 'em.conflict.lockedTitle': "편집이 잠겼습니다";
273
+ readonly 'em.conflict.missingDetail': "변경 사항을 저장하지 못했습니다(서버 또는 네트워크 오류). 최신 내용을 다시 불러오세요.";
274
+ readonly 'em.conflict.changedDetail': "다른 곳에서 변경되어 편집이 잠겼습니다. 최신 내용을 다시 불러오세요.";
246
275
  readonly 'em.ctx.addEntity': "엔티티 추가";
247
276
  readonly 'em.ctx.addNote': "노트 추가";
248
277
  readonly 'em.ctx.addGroup': "그룹 추가";
@@ -277,6 +306,7 @@ export declare const ko: {
277
306
  readonly 'em.node.required': "필수 (NOT NULL)";
278
307
  readonly 'em.node.logicalMissing': "(논리명)";
279
308
  readonly 'em.node.editLock': "편집 잠금";
309
+ readonly 'em.node.connectHint': "드래그해 다른 엔티티와 관계 연결";
280
310
  readonly 'em.node.opsSummaryTitle': "오퍼레이션 {n}개 — 클래스 표시 모드에서 펼쳐 보입니다";
281
311
  readonly 'em.node.opsSummary': "오퍼레이션 {n}개";
282
312
  readonly 'em.node.addAttr': "+ 속성";
@@ -288,6 +318,7 @@ export declare const ko: {
288
318
  readonly 'em.explorer.emptyNote': "(빈 노트)";
289
319
  readonly 'em.explorer.diagram': "다이어그램";
290
320
  readonly 'em.explorer.searchPlaceholder': "엔티티·속성 검색 ( / )";
321
+ readonly 'em.explorer.treeAria': "다이어그램 트리";
291
322
  readonly 'em.explorer.searchAria': "엔티티·속성 검색";
292
323
  readonly 'em.explorer.clearSearchAria': "검색어 지우기";
293
324
  readonly 'em.explorer.clearSearchTitle': "지우기 (Esc)";
@@ -318,6 +349,18 @@ export declare const ko: {
318
349
  readonly 'em.history.doRestore': "복원";
319
350
  readonly 'em.history.cancel': "취소";
320
351
  readonly 'em.history.restoreToHere': "이 시점으로 복원";
352
+ readonly 'em.history.diff.compare': "현재와 비교";
353
+ readonly 'em.history.diff.current': "현재";
354
+ readonly 'em.history.diff.exit': "비교 해제";
355
+ readonly 'em.history.diff.count': "누적 변경 {n}건";
356
+ readonly 'em.history.diff.empty': "이 구간의 누적 변경이 없습니다.";
357
+ readonly 'em.history.diff.restorePreview': "되돌아갈 변경 {n}건";
358
+ readonly 'em.history.diff.restorePreviewNone': "되돌아갈 변경이 없습니다.";
359
+ readonly 'em.history.loadMore': "이전 기록 더 보기 ({n})";
360
+ readonly 'em.history.periodLabel': "기간";
361
+ readonly 'em.history.periodFrom': "시작일";
362
+ readonly 'em.history.periodTo': "종료일";
363
+ readonly 'em.history.periodReset': "기간 해제";
321
364
  readonly 'em.check.catName': "이름";
322
365
  readonly 'em.check.catJpa': "JPA";
323
366
  readonly 'em.check.catType': "타입";
@@ -331,6 +374,10 @@ export declare const ko: {
331
374
  readonly 'em.check.name6Column': "컬럼 물리명이 SQL 예약어입니다: \"{name}\"";
332
375
  readonly 'em.check.name6Table': "테이블 물리명이 SQL 예약어입니다: \"{name}\"";
333
376
  readonly 'em.check.name6Index': "인덱스 이름이 SQL 예약어입니다: \"{name}\"";
377
+ readonly 'em.check.name7': "관계/임베드 속성({attrType})의 이름이 비어 있습니다 — 이름이 곧 JPA 필드명이라 코드 생성 시 이 관계가 통째로 누락됩니다. 속성명을 채우세요";
378
+ readonly 'em.check.name8': "속성 \"{name}\"의 컬럼 물리명이 비어 있습니다 — DDL·코드 생성에서 이 컬럼이 통째로 누락됩니다. 물리명을 채우세요";
379
+ readonly 'em.check.name9': "두 엔티티가 같은 테이블 \"{name}\"에 매핑됩니다 — 컬럼이 한 테이블에 뒤섞입니다. 테이블 물리명을 구분하세요";
380
+ readonly 'em.check.name10': "인덱스 이름이 중복됩니다: \"{name}\" — 인덱스 이름은 DB 스키마 전역에서 유일해야 합니다";
334
381
  readonly 'em.check.jpa1': "JPA 엔티티에 식별자(PK) 속성이 없습니다";
335
382
  readonly 'em.check.jpa2': "임베더블 타입은 식별자 속성을 가질 수 없습니다: \"{name}\"";
336
383
  readonly 'em.check.jpa4': "식별 관계 사이클입니다 (PK 무한 의존): {path}";
@@ -348,16 +395,22 @@ export declare const ko: {
348
395
  readonly 'em.check.jpa15': "식별자(@Id) 속성은 자연키(@NaturalId)일 수 없습니다 — 자연키는 PK와 별개의 비즈니스 키입니다: \"{name}\"";
349
396
  readonly 'em.check.jpa16': "자연키(@NaturalId) 속성은 transient(@Transient)일 수 없습니다: \"{name}\"";
350
397
  readonly 'em.check.jpa17': "자연키(@NaturalId) 속성은 not null이 권장됩니다(비즈니스 키는 non-null이 원칙): \"{name}\"";
398
+ readonly 'em.check.jpa18': "cascade가 관계 양쪽(부모·자식)에 모두 설정되어 양방향 전파됩니다 — 의도치 않은 연쇄 저장/삭제·전파 사이클 위험. 보통 cascade는 한쪽에만 둡니다";
399
+ readonly 'em.check.jpa19': "부모에 컬렉션/참조 필드가 있으나 자식({child})에 대응 관계 속성이 없어 JPA 매핑(mappedBy)을 만들 수 없습니다 — 코드젠이 이 관계를 방출하지 못합니다. 자식에 FK 속성을 만들거나 관계를 단방향으로 정리하세요";
400
+ readonly 'em.check.jpa20': "복합 PK(@IdClass/@EmbeddedId)에는 채번(@GeneratedValue)을 쓸 수 없습니다 — 속성 \"{name}\"에 설정되어 있습니다";
351
401
  readonly 'em.check.type1': "타겟 DB가 지원하지 않는 컬럼 타입입니다: \"{dataType}\"";
352
402
  readonly 'em.check.type2': "{dataType} 타입에 length가 지정되지 않았습니다";
353
403
  readonly 'em.check.type3': "공유 대상 컬럼의 타입({targetType})이 {metaName} 정의({metaType})와 다릅니다";
354
404
  readonly 'em.check.type4': "다중값(Multi-Value) 속성은 GroupCodeEnum + VARCHAR 조합에서만 컨버터가 자동 생성됩니다 — 현재({type} / {dataType})에서는 Set<…> 필드만 생성되어 매핑이 불완전할 수 있습니다";
405
+ readonly 'em.check.type6': "속성 \"{name}\"의 컬럼에 데이터 타입이 지정되지 않았습니다 — DDL에서 이 컬럼이 생략됩니다";
355
406
  readonly 'em.check.dsn1': "both-many(M:N) 관계를 조인 엔티티 없이 직접 연결했습니다 — 연관 엔티티 도입을 검토하세요";
356
407
  readonly 'em.check.dsn2': "속성이 하나도 없는 엔티티입니다";
357
408
  readonly 'em.check.dsn3': "모델링된 관계가 없습니다 (연관·상속·임베딩 미참여 — 의도적 생략이면 무시)";
358
409
  readonly 'em.check.dsn4': "속성이 {count}개로 많습니다 (임계치 {threshold} 초과) — 분해를 검토하세요";
359
410
  readonly 'em.check.dsn5Inherited': "인덱스 \"{name}\"가 참조하는 상속 컬럼을 슈퍼클래스 카탈로그에서 찾을 수 없습니다({field}).";
360
411
  readonly 'em.check.dsn5Missing': "인덱스 \"{name}\"가 존재하지 않는 컬럼을 참조합니다.";
412
+ readonly 'em.check.dsn6': "인덱스 \"{name}\"에 컬럼이 없습니다 — 컬럼 없는 인덱스는 DDL·코드 생성에서 산출되지 않습니다";
413
+ readonly 'em.check.dsn7': "인덱스 \"{name}\"에 같은 컬럼이 두 번 이상 들어 있습니다 — 뒤의 중복 항목은 의미가 없습니다";
361
414
  readonly 'em.check.unspecified': "미지정";
362
415
  };
363
416
  /** 메시지 키 — `ko` 카탈로그의 키 집합(단일 진실 소스). */
package/dist/index.d.ts CHANGED
@@ -1,38 +1,43 @@
1
- export * from './core/types';
2
- export * from './core/resolve';
3
- export * from './core/routing';
4
- export * from './core/autolayout';
5
- export * from './core/text';
6
- export * from './core/mermaid';
7
- export * from './core/parseMermaid';
8
- export * from './core/parseSqlDdl';
9
- export * from './core/ddl';
10
- export * from './core/jsonModel';
11
- export * from './core/svg';
12
- export * from './core/validation';
13
- export * from './core/quickFix';
14
- export * from './core/sharedColumn';
1
+ export type { Association, AssociationEnd, AssociationLayout, Attribute, AttributeType, ClassStereotype, DbColumn, DiagramLayout, DisplayMode, EmbeddableCatalog, EmbeddableCatalogEntry, EmbeddableCatalogField, Entity, EntityIndex, EntityJpaAttrs, EntityLayout, Geo, GroupCodeCatalog, GroupCodeCatalogEntry, GroupCodeValue, GroupLayout, IndexColumn, JpaCascadeType, JpaFetchType, LangCode, LogicalGroup, LogicalModel, ModelId, MultiLangText, Multiplicity, Note, NoteConnection, Operation, OperationVisibility, Point, PredefinedCustomTypeCatalog, PredefinedCustomTypeEntry, Size, Style, SuperClassCatalog, SuperClassColumnDef, SuperClassDef, } from './core/types';
2
+ export { resolveDiagram, type AutoLayoutOptions, type ResolvedAssociation, type ResolvedDiagram, type ResolvedEntity, type ResolvedGroup, type ResolvedNote, type ResolvedNoteConnection, } from './core/resolve';
3
+ export type { Rect, RoutingMode, SegmentMid, Side } from './core/routing';
4
+ export { computeAutoLayout, packEntityBoxes, type AutoLayoutGrid, type EntityBoxSpec, type PackBoxesOptions, type PackedEntityBox, } from './core/autolayout';
5
+ export { displayLabel, entityModelToText } from './core/text';
6
+ export { defaultMermaidDialect, entityModelToMermaid, type MermaidDialect } from './core/mermaid';
7
+ export { mermaidErToImportSource, parseMermaidEr } from './core/parseMermaid';
8
+ export { parseSqlDdl, sqlDdlToImportSource, type ParseSqlDdlResult } from './core/parseSqlDdl';
9
+ export { defaultSqlDialect, entityModelToDdl, type DdlContext, type SqlDialect, } from './core/ddl';
10
+ export { DIAGRAM_JSON_FORMAT, DIAGRAM_JSON_VERSION, InvalidDiagramJsonError, diagramToJson, parseDiagramJson, type DiagramJsonEnvelope, } from './core/jsonModel';
11
+ export { renderDiagramSvg, type Corners, type DiagramGeometry, type SvgBox, type SvgEdge, type SvgHLine, type SvgTextFrag, } from './core/svg';
12
+ export { PHYSICAL_NAME_MAX_LENGTH, validateModel, type IssueSeverity, type IssueTargetKind, type ValidationContext, type ValidationIssue, } from './core/validation';
13
+ export { resolveColumnPhysicalName, resolveEffectiveColumn, type ColumnResolveContext } from './core/columnResolve';
14
+ export { resolveQuickFix, type QuickFixPlan } from './core/quickFix';
15
+ export { collectSharedColumns, resolveSharedColumn, sharedColumnScopeEntities, type ResolvedSharedColumn, } from './core/sharedColumn';
15
16
  export { JAVA_TYPES, SELECTABLE_JAVA_TYPES, javaTypeLabel, CUSTOM_TYPE_VALUE, GROUP_CODE_ENUM_VALUE, DEFAULT_JAVA_TYPE, type JavaTypeDef, } from './core/javaTypes';
16
- export { scaffoldEntityJava, type ScaffoldOptions, type ScaffoldedEntity, } from './core/scaffoldJava';
17
+ export { scaffoldEntityJava, isGeneratable, type ScaffoldOptions, type ScaffoldedEntity, } from './core/scaffoldJava';
17
18
  export { migrateLegacyMoney } from './core/migrateLegacyMoney';
19
+ export { multiplicityLabel } from './core/associationNav';
20
+ export { stereotypeLabel } from './core/stereotype';
18
21
  export { mergeDiagram, type MergeDiagramSource, type MergeDiagramOptions, type MergeDiagramResult, } from './core/mergeDiagram';
19
22
  export { synthesizeRestoreOps, deepEqual as restoreDeepEqual, type DiagramSnapshotState } from './core/synthesizeRestoreOps';
20
23
  export { projectFieldAudit, type FieldAuditRecord, type FieldAuditTarget, type FieldAuditEntry } from './core/projectFieldAudit';
21
24
  export { projectEntityAudit, type EntityAuditEntry, type EntityAuditSubject, type EntityAuditSubjectKind } from './core/projectEntityAudit';
22
25
  export { projectActionLog, type ActionGroup, type SubjectAction, type ActionSubject, type ActionSubjectKind, type ActionFieldChange } from './core/projectActionLog';
26
+ export { projectSeqDiff, buildDiffMarks, type SeqDiff, type SeqDiffEntry, type DiffMark } from './core/projectSeqDiff';
23
27
  export { projectInheritedColumns, makeInheritedColumnRef, isInheritedColumnRef, parseInheritedColumnRef, INHERITED_REF_PREFIX, type InheritedColumn, } from './core/inheritedColumns';
24
28
  export { newId } from './core/id';
25
- export * from './command/types';
29
+ export type { Command, EditorState } from './command/types';
26
30
  export { CommandStack, type CommandDirection, type CommandListener } from './command/stack';
27
31
  export * as commands from './command/commands';
28
- export * from './command/op';
32
+ export type { CasUnit, OpCas, OpConflict, OpEmission, OpOrigin, OpResult, OpShape, PersistedOpBatch, } from './command/op';
29
33
  export { OpSyncAdapter, RevCache, type OpSyncOptions, type OpSyncTransport } from './command/opSync';
30
- export * from './agent/symbolicOp';
31
- export * from './agent/resolver';
32
- export * from './agent/schema';
33
- export * from './agent/buildAgentBatch';
34
- export * from './adapter/diagramAdapter';
35
- export type * from './adapter/persisted';
34
+ export { SYMBOLIC_OP_KINDS, type AssocHandle, type AssocSpec, type AttrSpec, type EmbeddableColumnOverride, type EntitySpec, type GroupSpec, type Handle, type IndexColumnSpec, type IndexSpec, type OperationSpec, type SymbolicOp, type SymbolicOpKind, } from './agent/symbolicOp';
35
+ export { resolveSymbolicOps, type ResolveError, type ResolveResult, type ResolverOptions, } from './agent/resolver';
36
+ export { APPLY_MODEL_OPS_INPUT_SCHEMA, SYMBOLIC_OP_SCHEMA } from './agent/schema';
37
+ export { buildAgentBatch, type BuildAgentBatchOptions } from './agent/buildAgentBatch';
38
+ export { fromPersisted, toPersisted, toPersistedV2, type DiagramMeta, } from './adapter/diagramAdapter';
39
+ export { planHealBackfillOps, type HealBackfillPlan } from './adapter/healBackfill';
40
+ export type { PAssocEnd, PAssociation, PAttribute, PDbAttr, PDiagram, PDiagramV2, PEntity, PGeo, PGroup, PIndex, PInlineAttribute, PJpaAttrs, PNote, POperation, PStyle, PV2Association, PV2Entity, PV2Group, PV2Layout, PV2Logical, } from './adapter/persisted';
36
41
  export { default as EntityNode } from './view/EntityNode.vue';
37
42
  export { default as GroupNode } from './view/GroupNode.vue';
38
43
  export { default as NoteNode } from './view/NoteNode.vue';
@@ -1,11 +1,15 @@
1
+ import { DiffMark } from '../core/projectSeqDiff';
1
2
  import { EditorController } from '../editor/controller';
3
+ import { ModelId } from '../core/types';
2
4
  type __VLS_Props = {
3
5
  controller: EditorController;
6
+ diffMarks?: Map<ModelId, DiffMark> | null;
4
7
  };
5
8
  declare function exportSvg(): Promise<void>;
6
9
  declare function exportPng(): Promise<void>;
7
10
  declare const _default: import('vue').DefineComponent<__VLS_Props, {
8
11
  exportSvg: typeof exportSvg;
9
12
  exportPng: typeof exportPng;
13
+ fitView: import('@vue-flow/core').FitView;
10
14
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
11
15
  export default _default;
@@ -1,3 +1,4 @@
1
+ import { DiffMark } from '../core/projectSeqDiff';
1
2
  import { EditorController } from '../editor/controller';
2
3
  type __VLS_Props = {
3
4
  controller: EditorController;
@@ -5,7 +6,9 @@ type __VLS_Props = {
5
6
  };
6
7
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
7
8
  close: () => any;
9
+ diffChange: (marks: Map<string, DiffMark> | null) => any;
8
10
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
9
11
  onClose?: (() => any) | undefined;
12
+ onDiffChange?: ((marks: Map<string, DiffMark> | null) => any) | undefined;
10
13
  }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
11
14
  export default _default;
@@ -0,0 +1,14 @@
1
+ import { InjectionKey, Ref } from 'vue';
2
+ import { ModelId } from '../core/types';
3
+ import { DiffMark } from '../core/projectSeqDiff';
4
+ /**
5
+ * 이력 diff 비교 모드의 캔버스 오버레이 주입 계약(RELATION_HIGHLIGHT 동형 — 일시적 시각 강조,
6
+ * 모델 무관). 셸(EntityModeler/DevApp)이 HistoryPanel의 비교 diff 마크를 소유하고 DiagramCanvas가
7
+ * prop으로 받아 provide, EntityNode가 구독한다(D4-(a) 뷰 소유 — core/controller 무변경).
8
+ *
9
+ * null = 비교 모드 아님(오버레이 없음). removed 대상은 캔버스에 노드가 없어 맵에 없다(D3 패널 전용).
10
+ */
11
+ export interface DiffOverlay {
12
+ marks: Ref<Map<ModelId, DiffMark> | null | undefined>;
13
+ }
14
+ export declare const DIFF_OVERLAY: InjectionKey<DiffOverlay>;
@@ -0,0 +1,5 @@
1
+ import { Attribute, ModelId } from '../core/types';
2
+ /** 속성 modelId → 그 단일 dbAttr modelId 매핑. 다중/0 컬럼 속성은 담지 않는다. */
3
+ export declare function buildIndexRefCanonMap(attributes: readonly Attribute[]): Map<ModelId, ModelId>;
4
+ /** 정규화된 비교 키. 매핑에 없으면(다중 컬럼 속성·dbAttr ref·상속 ref·dangling) 원문 그대로. */
5
+ export declare function canonicalIndexRef(map: ReadonlyMap<ModelId, ModelId>, ref: ModelId): ModelId;
@@ -0,0 +1,15 @@
1
+ import { InjectionKey } from 'vue';
2
+ /**
3
+ * 노드 내부 handle 재측정 요청 수집기 (VE-1 ①) — 캔버스가 provide, EntityNode가 onUpdated마다
4
+ * 자기 id를 mark(무비용 후보 등록). 캔버스는 rAF 배치 flush에서 후보의 기하 시그니처(노드 높이 +
5
+ * 행별 y)를 비교해 **실제로 변한 노드만** `updateNodeInternals(ids)`로 재측정한다.
6
+ *
7
+ * 왜 시그니처 판정이 필수인가: Vue Flow의 updateNodeInternals는 forceUpdate로 handleBounds를
8
+ * 무조건 새 객체로 써 그 노드를 다시 재렌더시킨다 — 재렌더를 무조건 mark하면 측정→재렌더→측정
9
+ * 무한 루프. 시그니처가 무변화면 측정을 생략해 루프가 한 사이클 만에 종료된다. 부수 효과로
10
+ * 텍스트-only 변경·hover 강조 재렌더도 재측정에서 자연 제외된다.
11
+ */
12
+ export interface NodeInternalsCollector {
13
+ mark: (nodeId: string) => void;
14
+ }
15
+ export declare const NODE_INTERNALS: InjectionKey<NodeInternalsCollector>;
@@ -1,12 +1,14 @@
1
1
  import { OpConflict } from '../command/op';
2
+ import { MessageKey } from '../i18n';
2
3
  export interface OpConflictNotice {
3
- /** 배너 제목 — 상태 자체(무엇이 일어났는지). */
4
- title: string;
5
- /** 배너 본문 — 원인 + 복구 방향(다시 불러오기). */
6
- detail: string;
4
+ /** 배너 제목 — 상태 자체(무엇이 일어났는지). 뷰가 t()로 렌더. */
5
+ titleKey: MessageKey;
6
+ /** 배너 본문 — 원인 + 복구 방향(다시 불러오기). 뷰가 t()로 렌더. */
7
+ detailKey: MessageKey;
7
8
  }
8
9
  /**
9
- * 충돌 종류 → 사용자 문구. `missing`은 동시편집이 아니라 전송 실패(혼자 편집 중에도 발생)라 원인을
10
- * 구분한다(호스트 배선 경로와 동일한 kind 오진 방지). null → null(배너 미노출).
10
+ * 충돌 종류 → 사용자 문구 **키**(문구는 i18n 카탈로그 소유 검증 P3 code+params→뷰 지역화 패턴 동형).
11
+ * `missing`은 동시편집이 아니라 전송 실패(혼자 편집 중에도 발생) 원인을 구분한다
12
+ * (호스트 배선 경로와 동일한 kind 오진 방지). null → null(배너 미노출).
11
13
  */
12
14
  export declare function opConflictNotice(conflict: OpConflict | null | undefined): OpConflictNotice | null;
@@ -1,3 +1,4 @@
1
+ import { MessageKey } from '../i18n';
1
2
  import { Style } from '../core/types';
2
3
  export type SwatchToken = 'red' | 'amber' | 'green' | 'teal' | 'blue' | 'indigo' | 'violet' | 'pink';
3
4
  /** 토큰의 컨텍스트별 렌더값 (CSS 변수 참조 — 테마는 [data-theme]로 스왑) */
@@ -31,7 +32,7 @@ export declare function resolveSwatch(token: SwatchToken | null): SwatchRender |
31
32
  * @param soft 그룹처럼 반투명 칠이 필요하면 true.
32
33
  */
33
34
  export declare function swatchMinimapFill(token: SwatchToken | null, soft?: boolean): string | null;
34
- /** 피커 라벨 */
35
- export declare function swatchLabel(token: SwatchToken): string;
35
+ /** 피커 라벨 키 — 소비처가 `t(swatchLabelKey(token))`으로 로케일 렌더 */
36
+ export declare function swatchLabelKey(token: SwatchToken): MessageKey;
36
37
  /** 피커에 칠할 대표색 (바 색 — 피커도 [data-theme]에 따라 전환) */
37
38
  export declare function swatchSwatchColor(token: SwatchToken): string;
@@ -0,0 +1,82 @@
1
+ import { ComputedRef } from 'vue';
2
+ import { EditorController } from '../editor/controller';
3
+ import { Attribute, EmbeddableCatalogEntry, Entity, GroupCodeValue, MultiLangText } from '../core/types';
4
+ import { JavaTypeDef } from '../core/javaTypes';
5
+ export declare function useAttributeEditing(c: EditorController, entityId: () => string): {
6
+ entity: ComputedRef<Entity | null>;
7
+ isEmbeddable: ComputedRef<boolean>;
8
+ focusedAttrIds: ComputedRef<Set<string>>;
9
+ personalInfoItems: string[];
10
+ piiLabel: (v: string) => string;
11
+ idn: <T>(s: T) => T;
12
+ setAttr: (a: Attribute, patch: Partial<Attribute>) => void;
13
+ isManagedFk: (a: Attribute) => boolean;
14
+ setNaturalId: (a: Attribute, v: boolean) => void;
15
+ clearNaturalIdPatch: () => Partial<Attribute>;
16
+ setIdentifier: (a: Attribute, v: boolean) => void;
17
+ setTransient: (a: Attribute, v: boolean) => void;
18
+ dbLocked: (a: Attribute) => boolean;
19
+ fkDerived: (a: Attribute) => boolean;
20
+ fkOriginPhysical: (a: Attribute, i?: number) => string | undefined;
21
+ typeValueOf: (t: JavaTypeDef) => string;
22
+ typeLabelOf: (t: JavaTypeDef) => string;
23
+ setAttrType: (a: Attribute, v: string | undefined) => void;
24
+ setAttrCustomType: (a: Attribute, v: string) => void;
25
+ setDb: (a: Attribute, patch: Record<string, unknown>) => void;
26
+ scaleApplicable: (a: Attribute) => boolean;
27
+ scaleHint: (a: Attribute) => string | undefined;
28
+ setDbLogical: (a: Attribute, value: MultiLangText) => void;
29
+ setAttrDescription: (a: Attribute, value: MultiLangText) => void;
30
+ attrPiiValue: (a: Attribute) => string;
31
+ setAttrPii: (a: Attribute, v: string) => void;
32
+ predefinedCustomTypeCatalog: ComputedRef<import('..').PredefinedCustomTypeCatalog>;
33
+ embeddableCatalog: ComputedRef<import('..').EmbeddableCatalog>;
34
+ predefinedLabel: (e: EmbeddableCatalogEntry) => string;
35
+ groupCodeCatalog: ComputedRef<import('..').GroupCodeCatalog>;
36
+ attrGroupCodes: (a: Attribute) => GroupCodeValue[];
37
+ attrCodeItems: (a: Attribute) => (GroupCodeValue | "none")[];
38
+ codeValueOf: (v: GroupCodeValue | "none") => string;
39
+ codeLabelOf: (v: GroupCodeValue | "none") => string;
40
+ setAttrGroupCode: (a: Attribute, v: string | undefined) => void;
41
+ setAttrCode: (a: Attribute, v: string) => void;
42
+ setAttrDefaultValue: (a: Attribute, v: string) => void;
43
+ isEmbedExpanded: (a: Attribute) => boolean;
44
+ setDbAt: (a: Attribute, i: number, patch: Record<string, unknown>) => void;
45
+ setDbLogicalAt: (a: Attribute, i: number, value: MultiLangText) => void;
46
+ embedColMeta: (a: Attribute, i: number) => {
47
+ name?: string;
48
+ physicalName?: string;
49
+ dataType?: string;
50
+ length?: number;
51
+ scale?: number;
52
+ shareable?: boolean;
53
+ logicalName?: MultiLangText;
54
+ } | undefined;
55
+ fixedDataType: (a: Attribute, i: number) => string;
56
+ fixedLength: (a: Attribute, i: number) => number | undefined;
57
+ fixedScale: (a: Attribute, i: number) => number | undefined;
58
+ updatableItems: string[];
59
+ updatableLabel: (v: string) => string;
60
+ updatableValue: (col: Attribute["dbAttrs"][number] | undefined) => string;
61
+ setUpdatableAt: (a: Attribute, i: number, v: string) => void;
62
+ setUpdatable: (a: Attribute, v: string) => void;
63
+ insertableItems: string[];
64
+ insertableLabel: (v: string) => string;
65
+ insertableValue: (col: Attribute["dbAttrs"][number] | undefined) => string;
66
+ setInsertableAt: (a: Attribute, i: number, v: string) => void;
67
+ setInsertable: (a: Attribute, v: string) => void;
68
+ scopeEntities: ComputedRef<Entity[]>;
69
+ columnsById: ComputedRef<Map<string, import('..').DbColumn>>;
70
+ sharedCandidates: ComputedRef<{
71
+ modelId: string;
72
+ physical: string;
73
+ isCurrency: boolean;
74
+ ownerName: string | undefined;
75
+ }[]>;
76
+ sharedItems: () => string[];
77
+ sharedLabel: (v: string) => string;
78
+ sharedValue: (col: Attribute["dbAttrs"][number] | undefined) => string;
79
+ setSharedAt: (a: Attribute, i: number, v: string) => void;
80
+ isShared: (col: Attribute["dbAttrs"][number] | undefined) => boolean;
81
+ sharedPhysical: (col: Attribute["dbAttrs"][number]) => string;
82
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@g1cloud/entity-modeler-next",
3
3
  "private": false,
4
- "version": "5.0.0-beta.4",
4
+ "version": "5.0.0-beta.41",
5
5
  "description": "Vue 3 visual entity-modeling / class-diagram editor",
6
6
  "type": "module",
7
7
  "files": [
@@ -31,8 +31,7 @@
31
31
  "@vue-flow/background": "^1.3.2",
32
32
  "@vue-flow/controls": "^1.1.2",
33
33
  "@vue-flow/core": "^1.42.1",
34
- "@vue-flow/minimap": "^1.5.2",
35
- "pinia": "^2.2.0"
34
+ "@vue-flow/minimap": "^1.5.2"
36
35
  },
37
36
  "devDependencies": {
38
37
  "@g1cloud/open-bluesea-core": "1.0.0-alpha.9",
@@ -45,7 +44,7 @@
45
44
  "typescript": "^5.6.0",
46
45
  "vite": "^6.0.0",
47
46
  "vite-plugin-dts": "^5.0.3",
48
- "vitest": "^2.1.0",
47
+ "vitest": "^3.0.0",
49
48
  "vue": "^3.5.0",
50
49
  "vue-tsc": "^2.1.0"
51
50
  },
@@ -55,7 +54,8 @@
55
54
  "preview": "vite preview",
56
55
  "test": "vitest run",
57
56
  "test:watch": "vitest",
58
- "verify:m0": "node scripts/verify-m0.mjs",
59
- "typecheck": "vue-tsc --noEmit"
57
+ "verify": "node scripts/verify-all.mjs",
58
+ "typecheck": "vue-tsc --noEmit",
59
+ "check": "pnpm run test && pnpm run build"
60
60
  }
61
61
  }