@g1cloud/entity-modeler-next 5.2.18 → 5.2.20
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/agent/resolver.d.ts +57 -2
- package/dist/core/indexCleanup.d.ts +14 -1
- package/dist/core/javaTypes.d.ts +75 -4
- package/dist/editor/attribute.d.ts +7 -2
- package/dist/editor/commandPlans.d.ts +2 -1
- package/dist/editor/controller.d.ts +9 -0
- package/dist/entity-modeler-next.css +1 -1
- package/dist/entity-modeler.js +10331 -10202
- package/dist/entity-modeler.umd.cjs +20 -20
- package/dist/i18n/ko.d.ts +1 -0
- package/dist/view/useAttributeEditing.d.ts +1 -0
- package/package.json +3 -2
package/dist/agent/resolver.d.ts
CHANGED
|
@@ -153,6 +153,24 @@ export type ResolveError = {
|
|
|
153
153
|
entity: Handle;
|
|
154
154
|
handle: Handle;
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* `groupCode` 는 있는데 `type` 이 `GroupCodeEnum` 이 아니다 — 위 `groupcode-required` 의 **반대 방향**.
|
|
158
|
+
*
|
|
159
|
+
* ★커플링은 XOR 이 아니라 **동치**다(`core/javaTypes.isGroupCodeCouplingBroken`). 종전엔 한 방향만
|
|
160
|
+
* 막았고, 그래서 «`groupCode` 는 남긴 채 `type` 만 `String` 으로» 가 add·update 전부 통과했다 —
|
|
161
|
+
* 코드 enum 에 묶인 속성이 평범한 문자열을 방출하는 **깨진 파생**이다. GUI 는 `setAttributeGroupCode`
|
|
162
|
+
* 가 둘을 항상 함께 바꿔 이 상태를 만들 수 없으므로, 막지 않으면 AI 경로에만 생기는 형상이 된다.
|
|
163
|
+
* ⇒ 고칠 자리는 둘 중 하나다: `type` 을 `GroupCodeEnum` 으로 두거나, `groupCode` 를 함께 비우거나
|
|
164
|
+
* (같은 patch 에 둘을 함께 주면 통과한다 — 판정이 **결과 상태** 기준이다).
|
|
165
|
+
*/
|
|
166
|
+
| {
|
|
167
|
+
code: 'groupcode-type-mismatch';
|
|
168
|
+
opIndex: number;
|
|
169
|
+
entity: Handle;
|
|
170
|
+
handle: Handle;
|
|
171
|
+
type: string;
|
|
172
|
+
groupCode: string;
|
|
173
|
+
}
|
|
156
174
|
/** 물리 컬럼을 만들면서 dataType 미지정 — 빈 타입 컬럼은 DDL에서 드롭된다(발명 대신 요구). */
|
|
157
175
|
| {
|
|
158
176
|
code: 'datatype-required';
|
|
@@ -287,9 +305,16 @@ export type ResolveError = {
|
|
|
287
305
|
}
|
|
288
306
|
/**
|
|
289
307
|
* attribute.update patch의 평탄 dbAttr 키를 스칼라 단일 컬럼으로 매핑할 수 없음. 스칼라(NORMAL·단일 dbAttr)면
|
|
290
|
-
* `dbAttrs[0]`로 자동 매핑되지만, 모호/불가한 대상은 거부한다: EMBED_PREDEF/다중 dbAttr(어느 컬럼인지 모호
|
|
291
|
-
*
|
|
308
|
+
* `dbAttrs[0]`로 자동 매핑되지만, 모호/불가한 대상은 거부한다: EMBED_PREDEF/다중 dbAttr(어느 컬럼인지 모호),
|
|
309
|
+
* dbAttrs 0개/transient(머지할 컬럼 없음), `sharedColumnRef` 평탄(opaque modelId),
|
|
292
310
|
* flat + dotted-dbAttrs 혼용($set 충돌). 통과 시 논리 노드 blind-write로 orphan 오염이라 거부.
|
|
311
|
+
*
|
|
312
|
+
* ★★**거부는 «갈 곳»을 함께 말해야 한다**(2026-09-02 정정 — 「모르는 값을 발명하지 말 것」의 짝):
|
|
313
|
+
* - **다중 dbAttr** → *바인딩* 축(물리명·정밀도·공유)은 `embeddableOverrides`, **개별 컬럼 필드**(논리명 등)는
|
|
314
|
+
* **dotted `dbAttrs.<i>.<field>`**. ⚠️종전엔 이 분기가 `embeddableOverrides` «만» 지목했는데 그 배열엔
|
|
315
|
+
* 논리명 축이 없어 **열린 문(dotted) 옆에서 막힌 문을 가리키고** 있었다(실사용에서 raw `/ops` 우회를
|
|
316
|
+
* 유발했다 — 불필요했다). dotted 는 아래 `attribute-patch-unknown-key` 가 이미 허용하는 접두다.
|
|
317
|
+
* - **dbAttrs 0개** → `fieldLogicalName`(아래 주석 — 이쪽은 처음부터 대안을 지목하고 있었다).
|
|
293
318
|
*/
|
|
294
319
|
| {
|
|
295
320
|
code: 'attribute-patch-dbattr-flat-key';
|
|
@@ -409,6 +434,36 @@ export type ResolveError = {
|
|
|
409
434
|
current: string;
|
|
410
435
|
requested: string;
|
|
411
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* attribute.update patch의 `type` — **동반 구조가 함께 가야 성립**하는 전환이라 거부.
|
|
439
|
+
*
|
|
440
|
+
* ★위 `attrType` 게이트의 **짝**이다(2026-09-02 신설). 그쪽은 `attrType` 을 직접 준 경우를 막는데,
|
|
441
|
+
* `type` 만 주는 경로가 열려 있었다: `{type:'Money'}` 를 NORMAL 속성에 주면 `type` 만 갈리고
|
|
442
|
+
* `attrType`·`dbAttrs` 는 그대로라 **컬럼 1개짜리 EMBED 아닌 Money** 라는 모순이 남는다(반대로
|
|
443
|
+
* EMBED_PREDEF 에 `{type:'String'}` 를 주면 컬럼 2개짜리 String 이 된다). 통과시키면 그 자리는
|
|
444
|
+
* 코드젠·DDL·검증이 각자 다르게 읽는 **조용한 반쪽 적용**이고, `attrType` 게이트가 막으려던 *「아무도
|
|
445
|
+
* 관리하지 않는데 사용자도 고칠 수 없는」* 상태의 같은 부류다. ⚠️GUI 는 같은 조작을 **지원**하므로
|
|
446
|
+
* (`editor/attribute.convertAttributeType` — 삭제+추가 합성) 막지 않으면 *「GUI 로는 되는데 AI 로는
|
|
447
|
+
* 조용히 깨진다」* 가 된다. 판정선은 `core/javaTypes.isStructuralTypeChange` 로 **공유**한다.
|
|
448
|
+
* ⇒ 대안이 실재하므로 표현력 부족이 아니다 — `reason` 이 그 경로를 지목한다.
|
|
449
|
+
*/
|
|
450
|
+
| {
|
|
451
|
+
code: 'attribute-type-conversion-unsupported';
|
|
452
|
+
opIndex: number;
|
|
453
|
+
entity: Handle;
|
|
454
|
+
handle: Handle;
|
|
455
|
+
/**
|
|
456
|
+
* `core/javaTypes.typeOwner` 의 부류를 그대로 전달한다 — **사용자가 갈 곳이 갈린다**:
|
|
457
|
+
* - `column-count` — 컬럼 개수 축이 갈린다(`EMBED_PREDEF` 출발 또는 ② 임베더블 목적지)
|
|
458
|
+
* ⇒ **`attribute.remove` + `attribute.add`**(+ 자리 복원이 필요하면 `attribute.reorder`).
|
|
459
|
+
* - `association-owned` — `EMBED_OWN`/`EMBED_REF` 라 컬럼이 association source 소유 ⇒ 관계 op 소관.
|
|
460
|
+
* - `derived` — `RELATION_*` 이라 `type` 이 파생값이다(부모 PK 의 Java 타입 / 상대 엔티티)
|
|
461
|
+
* ⇒ 고칠 자리는 **부모 쪽 또는 관계**이지 이 속성이 아니다(GUI 도 같은 이유로 잠근다).
|
|
462
|
+
*/
|
|
463
|
+
reason: 'column-count' | 'association-owned' | 'derived';
|
|
464
|
+
current: string;
|
|
465
|
+
requested: string;
|
|
466
|
+
}
|
|
412
467
|
/** association.update patch 미지 키(스키마는 하드 폐색 — REST 직접 호출 대비 심층 방어). */
|
|
413
468
|
| {
|
|
414
469
|
code: 'association-patch-unknown-key';
|
|
@@ -12,5 +12,18 @@ export type IndexColumnCleanup = {
|
|
|
12
12
|
*
|
|
13
13
|
* ⚠️한 조작에서 여러 속성이 사라지면 **한 번에** 넘길 것 — 속성마다 따로 호출하면 각 산출이 원본 기준이라
|
|
14
14
|
* 나중 패치가 앞의 정리를 되돌린다.
|
|
15
|
+
*
|
|
16
|
+
* ★`survivingRefs` — **속성은 사라지지만 그것이 가리키던 자리는 살아남는** 조작용(`convertAttributeType`
|
|
17
|
+
* 의 자리 보존 전환이 그렇다: 삭제+추가 합성이라 속성 id 는 갈리는데 승계된 dbAttr 은 modelId 째 다음
|
|
18
|
+
* 속성으로 넘어간다). 그런 ref 는 «이번 조작이 깨뜨린 ref» 가 아니므로 위 규율대로 정리 대상이 아니다 —
|
|
19
|
+
* 빼면 살아있는 컬럼을 가리키던 인덱스가 조용히 비고, 그것이 이 모듈이 막으려던 **무신호 소실** 그
|
|
20
|
+
* 자체가 된다. 미지정이면 종전과 같다(전부 고아).
|
|
21
|
+
*
|
|
22
|
+
* ★★**집합이 아니라 «맵»인 이유**(2026-09-02 정정): 종전엔 `survivingColumnIds`(Set)였고 그것이 **컬럼
|
|
23
|
+
* 표기만 지켰다**. 그런데 `columnRef` 는 두 표기가 공존하고(`indexColumnRef.ts`) **편집 뷰가 만드는
|
|
24
|
+
* 인덱스는 속성 modelId 를 쓴다**(`EntityIndexSection.candidateItems`·`EntityIndexesWide.availItems`).
|
|
25
|
+
* 전환은 속성 id 를 새로 부여하므로, 컬럼이 승계돼도 **GUI 로 만든 인덱스는 그대로 비워졌다** —
|
|
26
|
+
* 막으려던 실패 모드가 같은 조작의 다른 표기로 재발한 형태다. 옛 ref → 새 ref 를 받아 **갈아끼운다**.
|
|
27
|
+
* 1컬럼 승계는 정규형(dbAttr 표기)으로 접어 넘기는 것이 자연스럽다(`indexRefResolver.canon` 동형).
|
|
15
28
|
*/
|
|
16
|
-
export declare function planIndexColumnCleanup(entity: Entity, removedAttributeIds: readonly ModelId[]): IndexColumnCleanup[];
|
|
29
|
+
export declare function planIndexColumnCleanup(entity: Entity, removedAttributeIds: readonly ModelId[], survivingRefs?: ReadonlyMap<ModelId, ModelId>): IndexColumnCleanup[];
|
package/dist/core/javaTypes.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Entity, Association, Attribute, DisplayMode, PredefinedCustomTypeCatalog } from './types';
|
|
1
|
+
import { Entity, Association, Attribute, DbColumn, DisplayMode, EmbeddableCatalog, PredefinedCustomTypeCatalog, PredefinedCustomTypeEntry } from './types';
|
|
2
2
|
export interface JavaTypeDef {
|
|
3
3
|
/** 저장값 = 레거시 enum 상수명. Attribute.type에 그대로 들어간다. */
|
|
4
4
|
value: string;
|
|
@@ -81,10 +81,24 @@ export declare function isNullLoadUnsafePrimitive(javaType: string | undefined,
|
|
|
81
81
|
*/
|
|
82
82
|
export declare const SELECTABLE_JAVA_TYPES: readonly JavaTypeDef[];
|
|
83
83
|
/**
|
|
84
|
-
* 타입 셀렉트 items — ① 스칼라 후보 + ③ 주입 customtype 카탈로그 + 현재값 폴백 합성.
|
|
84
|
+
* 타입 셀렉트 items — ① 스칼라 후보 + ③ 주입 customtype 카탈로그 + ② 임베더블 + 현재값 폴백 합성.
|
|
85
85
|
*
|
|
86
86
|
* ③ `predefinedCustomTypes`(호스트 주입)는 ① 후보 뒤에 병합 노출한다 — 단일 컬럼이라 ①과 컬럼 구조가
|
|
87
|
-
* 같고
|
|
87
|
+
* 같고 ④ CustomType과 동질이므로 별도 진입이 아니라 같은 셀렉트에 둔다.
|
|
88
|
+
*
|
|
89
|
+
* ★②`embeddables`는 **컬럼 개수가 바뀌는** 선택지라 성격이 다르지만 그래도 여기 둔다(2026-09-02) —
|
|
90
|
+
* 목록에 없으면 EMBED_PREDEF 속성의 현재값이 아래 폴백으로만 보이고 **다른 타입으로 바꾸는 순간
|
|
91
|
+
* 되돌아갈 수 없다**. 그것이 직렬화 타입에서 실사용 보고로 드러났던 바로 그 함정이고(`serializedTypes`
|
|
92
|
+
* 주석), ②는 그 **두 번째 사본**이었다. 선택 시 부수효과(자리 보존 전환 = 삭제+추가 합성)는
|
|
93
|
+
* `editor/attribute.convertAttributeType`가 소유한다 — 이 함수는 «고를 수 있게» 할 뿐이다.
|
|
94
|
+
* ⇒ 부수효과로 레거시 ③`CustomMoneyType`(1컬럼, 라벨 `Money`) 속성을 GUI에서 ②`Money`(2컬럼)로
|
|
95
|
+
* 승격할 수 있게 된다 — 종전엔 v1→v2 마이그레이션(`migrateLegacyMoney`)만이 그 경로였다. 두 항목은
|
|
96
|
+
* `Money` ↔ `Money (금액)` 로 갈려 보이고, 그것이 **레거시 값을 잃지 않으면서 옮겨 갈 수 있는** 상태다.
|
|
97
|
+
* ⚠️★**이 근거는 도입 당시 자기소멸해 있었다**(2026-09-02 사용자 보고 · 같은 날 정정): 같은 커밋이
|
|
98
|
+
* 와이드 뷰에 EMBED 가드를 더해 EMBED 속성의 셀렉트가 **양쪽 다 `disabled`** 가 됐고, 그러면
|
|
99
|
+
* *「바꾸는 순간」* 자체가 없어 병합이 실효를 갖지 못했다. 진입만 열리고 출구가 없는 **단방향 트랩**이
|
|
100
|
+
* 된 것이고(*「한번 가면 못 돌아오는 형태」*), 그 함정의 **세 번째 사본**을 그 트랙이 새로 만든 셈이다.
|
|
101
|
+
* ⇒ 가드를 `EMBED_OWN`·`EMBED_REF`(association 이 정체성인 둘)로 좁혀 위 문장이 **이제 참이다**.
|
|
88
102
|
*
|
|
89
103
|
* open-bluesea BSSelect는 model-value가 items에 없으면 placeholder로 떨어뜨려 값이 빈칸으로 보인다(표시
|
|
90
104
|
* 손상). 현재값이 후보(① + 주입 ③) 밖(②임베더블 타입명·미주입 ③ customtype명·⑤ GroupCodeEnum·미지
|
|
@@ -100,7 +114,64 @@ export declare const SELECTABLE_JAVA_TYPES: readonly JavaTypeDef[];
|
|
|
100
114
|
* 타입으로 돌릴수 없는 상태」*). 폴백은 **밖에서 들어온 미지 타입**을 잃지 않기 위한 안전망이지
|
|
101
115
|
* «선택 가능한 타입»의 출처가 아니다 — 그 둘을 섞으면 편집이 한 방향으로만 흐른다.
|
|
102
116
|
*/
|
|
103
|
-
export declare function typeSelectItems(currentType: string, predefinedCustomTypes?: PredefinedCustomTypeCatalog, serializedTypes?: readonly string[]): JavaTypeDef[];
|
|
117
|
+
export declare function typeSelectItems(currentType: string, predefinedCustomTypes?: PredefinedCustomTypeCatalog, serializedTypes?: readonly string[], embeddables?: EmbeddableCatalog): JavaTypeDef[];
|
|
118
|
+
/**
|
|
119
|
+
* `type` 을 **누가 소유하는가** — 이 값이 「이 속성 혼자의 값」인지 가르는 단일 출처.
|
|
120
|
+
*
|
|
121
|
+
* 이 리포에서 편집 어포던스와 AI 거부가 **반복해서 같은 선을 각자 그려** 왔고 그때마다 갈렸다
|
|
122
|
+
* (와이드 ↔ 인스펙터 EMBED 가드 · GUI ↔ resolver `type` 축). 판별 유니온으로 못박아 소비처가
|
|
123
|
+
* 「어느 부류인가」를 묻게 한다 — 부울 셋을 나열하면 새 `attrType` 이 생겼을 때 조용히 `own` 이 된다.
|
|
124
|
+
*
|
|
125
|
+
* - `structural` — **동반 구조(`dbAttrs` 개수)가 함께 가야** 성립. `EMBED_PREDEF`.
|
|
126
|
+
* - `association` — **association 이 정체성**(어느 임베더블인지 관계가 정한다). `EMBED_OWN`·`EMBED_REF`.
|
|
127
|
+
* - `derived` — **다른 곳에서 파생**. `RELATION_OWN`(부모 PK 의 Java 타입) · `RELATION_REF`(상대 엔티티).
|
|
128
|
+
* - `own` — 사용자가 정하는 값. `NORMAL`.
|
|
129
|
+
*
|
|
130
|
+
* ⚠️`DIVIDER` 는 의도적으로 `own` 이다 — 계약상 `type=''` 이지만 **검증·코드젠·DDL 이 그 행을 통째로
|
|
131
|
+
* 건너뛰므로**(`core/types.AttributeType` 주석) 값이 실려도 어디서도 읽히지 않는다. 읽히지 않는 값을
|
|
132
|
+
* 막는 것은 게이트를 과하게 만든다.
|
|
133
|
+
* ⚠️`groupCode` 결합(⑤ `GroupCodeEnum`)은 **여기 없다** — `attrType` 이 아니라 «형제 필드»와의 커플링이라
|
|
134
|
+
* 판정 입력이 다르다(`isGroupCodeCouplingBroken`). 섞으면 「결과 상태로 재야 하는 축」과 「출발만 보면
|
|
135
|
+
* 되는 축」이 한 함수에 들어간다.
|
|
136
|
+
*/
|
|
137
|
+
export type TypeOwner = 'own' | 'structural' | 'association' | 'derived';
|
|
138
|
+
export declare function typeOwner(attr: Pick<Attribute, 'attrType'>): TypeOwner;
|
|
139
|
+
/**
|
|
140
|
+
* 이 타입 변경이 **`type` 하나로 표현할 수 없는** 자리인가 — 동반 구조가 함께 가야 하거나 그 값의
|
|
141
|
+
* 소유자가 따로 있는 변경이다. GUI 와 AI 가 **같은 선**을 보게 하려고 여기 둔다.
|
|
142
|
+
*
|
|
143
|
+
* 참인 경우가 둘이다: **출발이 `own` 이 아니거나**(위 `typeOwner`), **목적지가 ② 임베더블**이거나
|
|
144
|
+
* (1컬럼이 N컬럼이 된다 — 목적지 의존이라 `typeOwner` 로는 못 잡는 유일한 축).
|
|
145
|
+
*
|
|
146
|
+
* ★소비처가 둘이고 **하는 일이 다르다**: GUI 는 `structural` 을 «자리 보존 전환»(`convertAttributeType`
|
|
147
|
+
* — 삭제+추가 합성)으로 **처리**하고 나머지는 셀렉트를 잠그며, AI(`agent/resolver`)는 patch 로 표현할
|
|
148
|
+
* 수 없으므로 **전부 거부**한다(op 배치는 `attribute.remove`+`attribute.add`(+`reorder`)로 같은 일을
|
|
149
|
+
* 낼 수 있어 표현력 부족이 아니다). 판정선만 공유하고 처방은 각자다 — 선이 갈리면 *「GUI 로는 되는데
|
|
150
|
+
* AI 로는 조용히 반쪽 적용」* 이 된다.
|
|
151
|
+
* ★같은 값 재전송(라운드트립 에코)은 변경이 아니므로 거짓이다(`attrType` 게이트의 에코 통과와 동형).
|
|
152
|
+
*/
|
|
153
|
+
export declare function isStructuralTypeChange(attr: Pick<Attribute, 'attrType' | 'type'>, targetType: string, embeddables: EmbeddableCatalog): boolean;
|
|
154
|
+
/**
|
|
155
|
+
* ⑤ 파생 타입 커플링이 깨졌는가 — **`GroupCodeEnum` 과 `groupCode` 결합은 «항상 함께»**다(XOR 이면 깨짐).
|
|
156
|
+
*
|
|
157
|
+
* ★종전엔 **한 방향만** 강제했다(`type=GroupCodeEnum` 인데 `groupCode` 없음 = `groupcode-required`, 세 자리).
|
|
158
|
+
* 반대 방향 — `groupCode` 는 남긴 채 `type` 만 다른 값으로 — 은 **add·update 전부 열려 있었고**, 그러면
|
|
159
|
+
* 코드 enum 에 묶인 속성이 `String` 을 방출하는 **깨진 파생**이 조용히 생긴다(GUI 는 `setAttributeGroupCode`
|
|
160
|
+
* 가 둘을 항상 함께 바꿔서 이 상태를 만들 수 없다 = 또 하나의 GUI↔AI 비대칭이었다).
|
|
161
|
+
* ⇒ 불변식을 XOR 한 줄로 못박아 **세 자리가 같은 술어**를 본다. 판정은 **결과 상태**로 하는 것이 전제다
|
|
162
|
+
* (patch 만 보면 「type 은 두고 groupCode 만 제거」를, 기존 값만 보면 그 반대를 놓친다 — CC-3·CC-5 규율).
|
|
163
|
+
*/
|
|
164
|
+
export declare function isGroupCodeCouplingBroken(type: string | undefined, groupCode: string | undefined): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* ③ predefined customtype 을 고를 때 그 **단일 컬럼**에 실릴 물리 메타 — 카탈로그가 소유한다.
|
|
167
|
+
*
|
|
168
|
+
* ★함수로 뽑아 둔 이유: 이 시드를 하는 자리가 **둘**이다 — 컬럼 개수가 안 바뀌는 평범한 타입 변경
|
|
169
|
+
* (`view/useAttributeEditing.setAttrType`)과, EMBED_PREDEF 에서 ③ 으로 되돌아오는 **자리 보존 전환**
|
|
170
|
+
* (`editor/attribute.convertAttributeType`). 두 자리가 규칙을 각자 적으면 이 리포가 반복해 싸운
|
|
171
|
+
* 미러 드리프트가 그대로 열린다(VE-4). `length`·`scale` 은 카탈로그 미지정이면 **환원**한다 —
|
|
172
|
+
* 남겨 두면 이전 타입의 값이 새 타입 컬럼에 붙어 stale 원천이 된다(`setDb` 의 scale 환원과 동형).
|
|
173
|
+
*/
|
|
174
|
+
export declare function seedPredefinedCustomTypeColumn(base: DbColumn, entry: PredefinedCustomTypeEntry): DbColumn;
|
|
104
175
|
/**
|
|
105
176
|
* EMBED 표시 속성의 컬렉션 모드(`@ElementCollection`)를 판정한다 — 컬렉션이면 `collectionType`(기본
|
|
106
177
|
* LIST), 단일(`@Embedded`)이거나 EMBED가 아니면 undefined. 판정 권위는 임베더블을 가리키는 end의
|
|
@@ -2,7 +2,7 @@ import { Ref } from 'vue';
|
|
|
2
2
|
import { Command, EditorState } from '../command/types';
|
|
3
3
|
import { Translator } from '../i18n';
|
|
4
4
|
import { EditorController, Selection } from './controller';
|
|
5
|
-
import { EmbeddableCatalog, ModelId } from '../core/types';
|
|
5
|
+
import { EmbeddableCatalog, ModelId, PredefinedCustomTypeCatalog } from '../core/types';
|
|
6
6
|
/** 이 축이 팩토리 클로저에서 쓰는 것 전부. 늘어나면 여기 선언이 먼저 늘어난다(= 의존 인벤토리). */
|
|
7
7
|
export interface AttributeContext {
|
|
8
8
|
/** 편집 대상 reactive 상태(속성만 교체되므로 참조 안정). */
|
|
@@ -15,6 +15,11 @@ export interface AttributeContext {
|
|
|
15
15
|
gateEntityLocked: (entityId: ModelId) => boolean;
|
|
16
16
|
/** 호스트 주입 임베더블 카탈로그(`addPredefinedEmbed`의 슬롯 골격 소스). */
|
|
17
17
|
embeddableCatalog: Ref<EmbeddableCatalog>;
|
|
18
|
+
/**
|
|
19
|
+
* 호스트 주입 ③ predefined customtype 카탈로그 — `convertAttributeType` 이 **되돌림 목적지**로
|
|
20
|
+
* ③ 을 받을 때 그 단일 컬럼 메타를 시드하는 출처(②와 같은 성격의 주입이라 나란히 둔다).
|
|
21
|
+
*/
|
|
22
|
+
predefinedCustomTypeCatalog: Ref<PredefinedCustomTypeCatalog>;
|
|
18
23
|
/** UI 크롬 번역기 — FK 직접 삭제 차단 안내 문구용. */
|
|
19
24
|
t: Translator;
|
|
20
25
|
/** 차단 안내(텍스트별 단기 dedup) — 무음 차단을 막는 백스톱. */
|
|
@@ -22,4 +27,4 @@ export interface AttributeContext {
|
|
|
22
27
|
/** 삭제된 행을 선택이 가리키지 않도록 해제하는 쓰기(`removeAttributes`). */
|
|
23
28
|
selection: Ref<Selection>;
|
|
24
29
|
}
|
|
25
|
-
export declare function createAttributeApi(ctx: AttributeContext): Pick<EditorController, 'addPredefinedEmbed' | 'addSerializedTypeAttribute' | 'addAttribute' | 'addDivider' | 'updateAttribute' | 'setAttributeGroupCode' | 'setEmbedColumns' | 'removeAttribute' | 'removeAttributes' | 'setAttributeSwatch' | 'setAttributeSwatches' | 'reorderAttributes'>;
|
|
30
|
+
export declare function createAttributeApi(ctx: AttributeContext): Pick<EditorController, 'addPredefinedEmbed' | 'convertAttributeType' | 'addSerializedTypeAttribute' | 'addAttribute' | 'addDivider' | 'updateAttribute' | 'setAttributeGroupCode' | 'setEmbedColumns' | 'removeAttribute' | 'removeAttributes' | 'setAttributeSwatch' | 'setAttributeSwatches' | 'reorderAttributes'>;
|
|
@@ -23,8 +23,9 @@ export declare function removeAttributeCommands(entityId: ModelId, attributeIds:
|
|
|
23
23
|
/**
|
|
24
24
|
* 누산된 제거가 남길 인덱스 dangling 정리 명령 — 조작의 서브명령 **맨 끝**에 한 번 붙인다.
|
|
25
25
|
* `logical`은 제거 **전** 상태여야 한다(사라지는 속성의 dbAttr modelId를 알아야 하므로).
|
|
26
|
+
* `survivingRefs`는 그대로 통과시킨다 — 의미·근거는 `core/indexCleanup.planIndexColumnCleanup` 소유.
|
|
26
27
|
*/
|
|
27
|
-
export declare function indexCleanupCommands(logical: LogicalModel, removed: RemovedAttributes): Command[];
|
|
28
|
+
export declare function indexCleanupCommands(logical: LogicalModel, removed: RemovedAttributes, survivingRefs?: ReadonlyMap<ModelId, ModelId>): Command[];
|
|
28
29
|
/**
|
|
29
30
|
* 식별자 전파 reconcile 계획을 자식 엔터티 대상 서브명령 배열로 변환.
|
|
30
31
|
* 1차 변경(관계 생성/삭제 등)과 함께 composite로 묶으면 전파 FK 동기화가 하나의 undo/redo
|
|
@@ -379,6 +379,15 @@ export interface EditorController {
|
|
|
379
379
|
* 대상 엔티티가 없으면 no-op(null).
|
|
380
380
|
*/
|
|
381
381
|
addPredefinedEmbed(entityId: ModelId, embeddableType: string): ModelId | null;
|
|
382
|
+
/**
|
|
383
|
+
* 기존 속성의 타입을 **자리 보존 전환** — 타입 셀렉트가 «컬럼 개수 축이 갈리는» 값을 낼 때의 착지점.
|
|
384
|
+
* `addPredefinedEmbed`가 꼬리에 **새 행**을 만드는 것과 달리 이쪽은 그 자리에서 형상을 바꾼다(사용처
|
|
385
|
+
* 순서를 어긋내지 않는다). `targetType`이 ② 임베더블 카탈로그에 있으면 `EMBED_PREDEF`로, 없으면
|
|
386
|
+
* `NORMAL`로 착지한다 — 즉 **되돌림도 이 경로다**(단방향이 아니다).
|
|
387
|
+
* 대상이 없거나 전환 불가(FK 파생 · 임베더블 착지인데 식별자 · `EMBED_OWN`/`EMBED_REF`/`RELATION_*`/
|
|
388
|
+
* `DIVIDER` 출발 · `groupCode` 결합 · 같은 타입 재선택)면 no-op(null).
|
|
389
|
+
*/
|
|
390
|
+
convertAttributeType(entityId: ModelId, attributeId: ModelId, targetType: string): ModelId | null;
|
|
382
391
|
addAttribute(entityId: ModelId, partial?: Partial<Attribute>): ModelId | null;
|
|
383
392
|
/**
|
|
384
393
|
* 시각 구획 행(DIVIDER) 추가 — 거대 엔티티에서 속성 묶음을 끊는 구분선. DB 컬럼·타입·식별자 없이
|