@g1cloud/entity-modeler-next 5.1.5 → 5.1.7

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/i18n/ko.d.ts CHANGED
@@ -194,8 +194,12 @@ export declare const ko: {
194
194
  readonly 'em.attr.fkDerivedNote': "외래키(FK)에서 파생된 컬럼입니다 — 형상은 부모 PK를 따르며, 변경은 관계선·식별관계에서 하세요.";
195
195
  readonly 'em.attr.scaleTypeHint': "소수부(scale)는 NUMERIC·DECIMAL 타입에만 적용됩니다.";
196
196
  readonly 'em.attr.embedFixedHint': "임베더블 정의에서 고정된 값입니다.";
197
+ readonly 'em.attr.fkFixedHint': "부모 PK 컬럼에서 상속된 값입니다 — 형상은 부모를 따릅니다.";
197
198
  readonly 'em.attr.embedSharedHint': "다른 컬럼과 공유하는 통화 컬럼입니다 — 대상에서 파생(읽기 전용).";
198
- readonly 'em.attr.derivedIdNote': "파생 식별(@MapsId) 스칼라 @Id 필드명입니다. 연관 필드명은 관계선을 클릭해 편집하며, 비우면 부모 PK 물리명에서 파생됩니다.";
199
+ readonly 'em.attr.derivedIdField': "파생 식별 @Id 필드";
200
+ readonly 'em.attr.assocField': "연관 필드명(@MapsId)";
201
+ readonly 'em.attr.derivedIdNote': "이 속성은 **두 Java 필드**를 냅니다 — 위 이름 칸은 스칼라 @Id 필드명(비우면 부모 PK 물리명에서 파생)이고, 여기는 @MapsId 연관 필드명입니다. 같은 값을 관계선 인스펙터에서도 편집할 수 있습니다.";
202
+ readonly 'em.attr.joinColumnOnlyNote': "복합 외래키의 형제 컬럼입니다 — JPA 필드는 관계당 하나뿐이라 이 이름은 방출되지 않습니다. 필드명은 «{anchor}»에서 편집하세요.";
199
203
  readonly 'em.attr.namePlaceholder': "이름";
200
204
  readonly 'em.attr.typePlaceholder': "타입";
201
205
  readonly 'em.attr.customTypePlaceholder': "커스텀 타입명";
@@ -238,6 +242,7 @@ export declare const ko: {
238
242
  readonly 'em.attr.detailExpand': "상세 펼치기";
239
243
  readonly 'em.attr.semanticLegend': "의미";
240
244
  readonly 'em.attr.embedChildCols': "임베더블 — 하위 컬럼 {n}개";
245
+ readonly 'em.attr.fkChildCols': "복합 외래키 — 컬럼 {n}개";
241
246
  readonly 'em.attr.overrideCollapse': "오버라이드 접기";
242
247
  readonly 'em.attr.overrideExpand': "오버라이드 펼치기";
243
248
  readonly 'em.attr.overrideLegend': "컬럼 오버라이드";
@@ -314,13 +319,14 @@ export declare const ko: {
314
319
  readonly 'em.node.logicalMissing': "(논리명)";
315
320
  readonly 'em.node.editLock': "편집 잠금";
316
321
  readonly 'em.node.connectHint': "드래그해 다른 엔티티와 관계 연결";
322
+ readonly 'em.node.derivedIdRow': "파생 식별(@MapsId)이 방출하는 스칼라 @Id 필드입니다 — 모델에는 연관 속성 하나로 저장되며, 편집은 그 속성의 인스펙터에서 합니다.";
317
323
  readonly 'em.node.embedRepeatedShow': "이 엔티티에서 값이 같아 접힌 컬럼 {count}개 보기";
318
324
  readonly 'em.node.embedRepeatedHide': "값이 같아 반복되는 컬럼 접기";
319
325
  readonly 'em.node.embedAttrHide': "이 임베드 컬럼 접기";
320
326
  readonly 'em.node.embedAttrShow': "접힌 임베드 컬럼 {count}개 보기";
321
- readonly 'em.node.embedAllHide': "이 엔티티의 임베드 컬럼 모두 접기";
322
- readonly 'em.node.embedAllShow': "접힌 임베드 컬럼 모두 펼치기";
323
- readonly 'em.node.embedAllSummary': "임베드 컬럼 {n}개 숨김";
327
+ readonly 'em.node.embedAllHide': "이 엔티티의 서브컬럼 모두 접기";
328
+ readonly 'em.node.embedAllShow': "접힌 서브컬럼 모두 펼치기";
329
+ readonly 'em.node.embedAllSummary': "서브컬럼 {n}개 숨김";
324
330
  readonly 'em.node.opsSummaryTitle': "오퍼레이션 {n}개 — 클래스 표시 모드에서 펼쳐 보입니다";
325
331
  readonly 'em.node.opsSummary': "오퍼레이션 {n}개";
326
332
  readonly 'em.node.addAttr': "+ 속성";
@@ -399,7 +405,6 @@ export declare const ko: {
399
405
  readonly 'em.check.jpa2': "임베더블 타입은 식별자 속성을 가질 수 없습니다: \"{name}\"";
400
406
  readonly 'em.check.jpa4': "식별 관계 사이클입니다 (PK 무한 의존): {path}";
401
407
  readonly 'em.check.jpa5': "{which}: cascade ALL이 개별 cascade와 중복됩니다 (ALL이 모두 포함)";
402
- readonly 'em.check.jpa6': "{which}: orphanRemoval이 cascade {cascade}와 의미가 겹칩니다";
403
408
  readonly 'em.check.jpa7': "{which}: 컬렉션(to-many) 연관에 EAGER 페치는 성능 위험이 있습니다";
404
409
  readonly 'em.check.jpa8': "JPA 엔티티에 테이블 물리명이 설정되지 않았습니다";
405
410
  readonly 'em.check.jpa9': "{which}: 단일(to-one) 연관에 컬렉션 메타(collectionType/collectionTable/orderColumn)는 무의미합니다 — @ElementCollection은 컬렉션에서만 적용됩니다";
@@ -70,6 +70,36 @@ export interface EntityColumnResolution {
70
70
  * 고유한 값(1회)은 새 정보이므로 포함하지 않고, 반복이 없는 속성은 맵에 아예 넣지 않는다.
71
71
  */
72
72
  redundantSlots: ReadonlyMap<ModelId, ReadonlySet<number>>;
73
+ /**
74
+ * **CLASS 표시 모드의 행 목록** — 모델 속성이 아니라 «방출될 Java 필드» 기준(`scaffoldJava.classFields`).
75
+ *
76
+ * 행 목록이 모델과 다른 경우는 셋이다: `@MapsId` 1행→2행 · 복합 FK 형제 1행→0행 ·
77
+ * navigable off inverse 1행→0행. ⚠️**같아도 담는다** — 관계 행의 `targetName`(CLASS 타입 칸의 출처)은
78
+ * 행 목록이 모델과 같은 엔티티에도 필요하기 때문이다(다를 때만 담았다가 타입 칸이 비는 결함을 냈다).
79
+ * 비용은 아래 `sameClassRows` 가 **속성 참조 단축**으로 흡수한다(비합성 행은 모델 객체를 그대로 든다).
80
+ *
81
+ * ★여기서 계산하는 이유는 `derivedIdFieldName` 과 같다 — 노드는 반응성 스코프 때문에 `logical` 을
82
+ * 직접 못 본다(위 「참조 안정화」). 판정·산식은 코드젠 것을 그대로 쓰고 뷰가 재기술하지 않는다.
83
+ * ⚠️이 축은 **엔티티 로컬이 아니다**(관계·대상 엔티티를 읽는다) — MapsId 해소가 이미 그렇고,
84
+ * 무효화 범위는 아래 값 비교가 좁힌다.
85
+ */
86
+ classRows?: readonly ClassDisplayRow[];
87
+ }
88
+ /** CLASS 행 하나 — 값 비교가 싸도록 **평탄**하게 담는다(대상 엔티티 객체를 통째로 들지 않는다). */
89
+ export interface ClassDisplayRow {
90
+ /** 표시용 속성. 합성 스칼라(@MapsId)는 **모델에 없는 가상 속성**이다. */
91
+ attr: Attribute;
92
+ synthetic: boolean;
93
+ /**
94
+ * 이 행을 만든 **모델 속성**의 id(합성 행이면 그 FK, 아니면 자기 자신).
95
+ * 합성 행을 클릭했을 때 «없는 것»을 선택하지 않고 **실물 FK 를 지목**하는 데 쓴다 —
96
+ * 그 FK 의 인스펙터가 스칼라명 서브행을 갖고 있으므로 사용자가 갈 곳이 정확히 거기다.
97
+ */
98
+ sourceAttrId: ModelId;
99
+ /** relation-* 의 대상 클래스명 — CLASS 타입 칸의 출처. */
100
+ targetName?: string;
101
+ /** inverse nav 의 컬렉션 래핑. */
102
+ collection?: 'LIST' | 'SET';
73
103
  }
74
104
  /** 엔티티 modelId → 그 엔티티 행들의 해소 결과. */
75
105
  export type ColumnResolutionIndex = ReadonlyMap<ModelId, EntityColumnResolution>;
@@ -19,6 +19,8 @@ export declare const embedSlotKey: (entityId: string, attrId: string) => string;
19
19
  export declare const ENTITY_FOLD_PREFIX = "all:";
20
20
  /** 속성 통째 축 키의 접두. */
21
21
  export declare const ATTR_FOLD_PREFIX = "one:";
22
+ /** 복합 FK 축 접두 — 다중 컬럼 FK 의 서브컬럼(기본 **접힘**). */
23
+ export declare const FK_FOLD_PREFIX = "fk:";
22
24
  /**
23
25
  * 엔티티 일괄 축의 키. `modelId`는 UUID 라 `:` 를 담지 않으므로 접두 있는 키는 반복 축 키와
24
26
  * 절대 겹치지 않는다(반복 축 키의 접두는 항상 엔티티 UUID 다).
@@ -29,8 +31,14 @@ export declare const embedAllKey: (entityId: string) => string;
29
31
  * 둘은 동시에 상태를 가질 수 있고(통째를 풀면 반복 접힘이 그대로 살아난다) 그것이 의도다.
30
32
  */
31
33
  export declare const embedAttrKey: (entityId: string, attrId: string) => string;
34
+ /**
35
+ * 복합 FK 축의 키 — 다중 컬럼 FK 속성의 서브컬럼을 접는다. 임베드 두 축과 **같은 슬롯**에 살고
36
+ * 접두로만 갈린다(모듈 헤더의 표). 기본값이 **접힘**인 근거는 그 헤더 ★★ 참조.
37
+ */
38
+ export declare const fkSlotKey: (entityId: string, attrId: string) => string;
32
39
  /**
33
40
  * 이 키의 기본 접힘 여부 — 캔버스가 `useTreeCollapse`에 그대로 넘긴다. **키의 순수 함수**여야 하며
34
- * (그 헤더 ①·②), 축별 기본값 근거는 이 모듈 헤더의 표에 있다. 접두가 없는 키(=반복 축)만 접힘이다.
41
+ * (그 헤더 ①·②), 축별 기본값 근거는 이 모듈 헤더의 표에 있다.
42
+ * **접힘 = 반복 축(접두 없음) + 복합 FK 축(`fk:`)** — 둘 다 정보 손실이 0인 축이다.
35
43
  */
36
44
  export declare const embedDefaultCollapsed: (key: string) => boolean;
@@ -2,6 +2,7 @@ import { ComputedRef } from 'vue';
2
2
  import { EditorController } from '../editor/controller';
3
3
  import { Attribute, EmbeddableCatalogEntry, Entity, GroupCodeValue, MultiLangText } from '../core/types';
4
4
  import { JavaTypeDef } from '../core/javaTypes';
5
+ import { isMultiColumnFk } from '../core/fkDerived';
5
6
  export declare function useAttributeEditing(c: EditorController, entityId: () => string): {
6
7
  entity: ComputedRef<Entity | null>;
7
8
  isEmbeddable: ComputedRef<boolean>;
@@ -14,6 +15,10 @@ export declare function useAttributeEditing(c: EditorController, entityId: () =>
14
15
  rowName: (a: Attribute) => string;
15
16
  rowNamePlaceholder: (a: Attribute) => string;
16
17
  setRowName: (a: Attribute, v: string) => void;
18
+ assocFieldName: (a: Attribute) => string;
19
+ setAssocFieldName: (a: Attribute, v: string) => void;
20
+ nameLocked: (a: Attribute) => boolean;
21
+ nameLockedHint: (a: Attribute) => string;
17
22
  isManagedFk: (a: Attribute) => boolean;
18
23
  setNaturalId: (a: Attribute, v: boolean) => void;
19
24
  clearNaturalIdPatch: () => Partial<Attribute>;
@@ -45,9 +50,11 @@ export declare function useAttributeEditing(c: EditorController, entityId: () =>
45
50
  setAttrCode: (a: Attribute, v: string) => void;
46
51
  setAttrDefaultValue: (a: Attribute, v: string) => void;
47
52
  isEmbedExpanded: (a: Attribute) => boolean;
53
+ isMultiColFk: typeof isMultiColumnFk;
54
+ hasColumnSlots: (a: Attribute) => boolean;
48
55
  setDbAt: (a: Attribute, i: number, patch: Record<string, unknown>) => void;
49
56
  setDbLogicalAt: (a: Attribute, i: number, value: MultiLangText) => void;
50
- embedColMeta: (a: Attribute, i: number) => {
57
+ colSlotMeta: (a: Attribute, i: number) => {
51
58
  name?: string;
52
59
  physicalName?: string;
53
60
  dataType?: string;
@@ -59,6 +66,7 @@ export declare function useAttributeEditing(c: EditorController, entityId: () =>
59
66
  fixedDataType: (a: Attribute, i: number) => string;
60
67
  fixedLength: (a: Attribute, i: number) => number | undefined;
61
68
  fixedScale: (a: Attribute, i: number) => number | undefined;
69
+ slotFixedHint: (a: Attribute) => string;
62
70
  updatableItems: string[];
63
71
  updatableLabel: (v: string) => string;
64
72
  updatableValue: (col: Attribute["dbAttrs"][number] | undefined) => string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@g1cloud/entity-modeler-next",
3
3
  "private": false,
4
- "version": "5.1.5",
4
+ "version": "5.1.7",
5
5
  "description": "Vue 3 visual entity-modeling / class-diagram editor",
6
6
  "type": "module",
7
7
  "files": [