@iyulab/enterprise 0.8.0 → 0.8.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/CHANGELOG.md +218 -0
- package/dist/FormRow.d.ts +1 -1
- package/dist/FormSection.d.ts +1 -1
- package/dist/helpers/messages.d.ts +2 -1
- package/package.json +11 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **`@types/react` was missing from the manifest**, so a standalone checkout (outside the
|
|
8
|
+
monorepo workspace, where hoisting used to paper over it) failed to typecheck against this
|
|
9
|
+
package's React-facing exports. Declared explicitly.
|
|
10
|
+
|
|
11
|
+
## 0.8.0
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- ⚠**헬퍼 라벨이 «영어 기본 + 로케일 레지스트리»로 이주했다** — `ProgressHelper` 6건 ·
|
|
16
|
+
`UrgencyHelper` 8건이 한국어 리터럴이었다.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { Locale } from '@iyulab/components';
|
|
20
|
+
import { messages } from '@iyulab/enterprise';
|
|
21
|
+
|
|
22
|
+
Locale.set('ko'); // 검증 메시지와 함께 전환된다
|
|
23
|
+
messages.register('ja', { progressDone: '完了' }); // 언어를 더하거나 문구를 덮는다
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
⚠**한국어 환경은 종전과 같은 문구를 본다** — 내장 로케일에 `ko` 가 들어 있고, 활성 로케일은
|
|
27
|
+
브라우저 언어에서 감지된다(`ko-KR` → `ko`). 그 밖의 환경은 이제 **영어**를 본다.
|
|
28
|
+
|
|
29
|
+
⚠**호출자가 준 `labels` 인자는 여전히 최우선**이다(`getUrgencyText`) — 종전 계약 유지.
|
|
30
|
+
|
|
31
|
+
★자체 레지스트리를 만들지 않고 `@iyulab/components` 의 `Locale.namespace()` 를 쓴다. 앱
|
|
32
|
+
하나에서 로케일을 두 번 전환하게 만들지 않기 위해서다.
|
|
33
|
+
|
|
34
|
+
### Requires
|
|
35
|
+
|
|
36
|
+
- `@iyulab/components >= 1.23.0` (`Locale.namespace`) — peer 하한을 올렸다.
|
|
37
|
+
|
|
38
|
+
## 0.7.1
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- 🔴**하우스 프리셋이 한 줄도 적용되지 않았다** — `0.7.0` 의 프리셋은 **구조적으로 무효**였다.
|
|
43
|
+
|
|
44
|
+
```css
|
|
45
|
+
/* components/styles/light.css */ :root { … } /* 특이도 (0,1,0) */
|
|
46
|
+
/* enterprise/styles/preset.css */ :where(:root){ … } /* 특이도 (0,0,0) ← 항상 진다 */
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`:where()` 는 특이도를 0 으로 만들므로 **로드 순서와 무관하게** 기본 시트가 이긴다.
|
|
50
|
+
그리고 프리셋 40선언 중 **기본 시트에 없는 것이 0개**여서, 특이도 0 이 이길 수 있는
|
|
51
|
+
자리가 **하나도 없었다**. 40선언 전부가 사문이었다.
|
|
52
|
+
|
|
53
|
+
⚠**의도는 옳았다** — *"프리셋이 소비자 브랜드를 덮으면 안 된다"*. 그러나 특이도 0 은
|
|
54
|
+
**이겨야 할 상대(기본값)와 지지 말아야 할 상대(브랜드)를 구분하지 못한다.**
|
|
55
|
+
|
|
56
|
+
⇒ **`:root` 로 선언하고 층은 «로드 순서»로 세운다.** 소비자가 이미 통제하는 축이다.
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
import '@iyulab/components/styles/light.css'; // 기본값
|
|
60
|
+
import '@iyulab/enterprise/styles/preset.css'; // 하우스 — 기본값을 덮는다
|
|
61
|
+
import './brand.css'; // 소비자 브랜드 — 하우스를 덮는다
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
⚠**이 실패는 조용했다** — 오류도 경고도 없어, 로드해 보고도 *"프리셋 값이 우리 값과
|
|
65
|
+
우연히 같았나 보다"* 로 읽히는 형태였다.
|
|
66
|
+
|
|
67
|
+
★**계약 테스트는 통과하고 있었다.** `:where()` 로 감싸졌는지를 물었을 뿐 **효력이
|
|
68
|
+
있는지**를 묻지 않았다. 이제 둘을 잰다 — *기본 시트를 이길 수 있는가*(특이도)와
|
|
69
|
+
*이길 것이 있는가*(기본값과 다른 선언이 하나 이상인가).
|
|
70
|
+
|
|
71
|
+
- **`0.7.0` 을 이미 로드한 소비자**: 렌더가 바뀐다. 그것이 프리셋이 원래 하려던 일이다.
|
|
72
|
+
프리셋을 로드하지 않은 소비자는 **변화 없다**.
|
|
73
|
+
|
|
74
|
+
## 0.7.0
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- 🆕**하우스 스타일 프리셋** — `@iyulab/enterprise/styles/preset.css`
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
import '@iyulab/enterprise/styles/preset.css';
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`@iyulab/components` 가 여는 **토큰 축**에 이유랩의 값을 채운 한 장이다. 축(이름·단 수)은
|
|
85
|
+
`components` 소유이고 이 파일은 **값만** 정한다 — 타이포 스케일(LOB 밀도) · 반경(컨트롤 단을
|
|
86
|
+
한 단씩 올림) · 엘리베이션(순수 검정 → **청흑 틴트**, 라이트/다크 각각).
|
|
87
|
+
|
|
88
|
+
**계약 셋** (`tests/preset-contract.test.ts` 가 강제한다):
|
|
89
|
+
⑴ **선택적 로드** — 로드하지 않은 소비자는 `components` 의 중립 기본값을 그대로 받는다.
|
|
90
|
+
⑵ **`--u-*` 값만 덮는다** — 새 클래스·새 선택자 0개.
|
|
91
|
+
⑶ 🔴**소비자가 항상 이긴다** — 선택자를 `:where()` 로 감싸 **특이도 0** 으로 선언한다.
|
|
92
|
+
⚠**이 항목은 `0.7.1` 에서 정정됐다** — 특이도 0 은 기본 시트도 이기지 못해 프리셋이
|
|
93
|
+
통째로 무효였다. 지금은 `:root` 이고 층은 **로드 순서**로 선다.
|
|
94
|
+
|
|
95
|
+
**정하지 않는 것**: 중립 램프의 색조(웜/쿨) — 역할 토큰 다수가 중립에서 파생되므로 램프를
|
|
96
|
+
옮기면 대비가 함께 움직인다. 전수 대비 검증 전에는 손대지 않는다. **브랜드 색** — 소비앱의
|
|
97
|
+
몫이고 프리셋은 브랜드를 갖지 않는다.
|
|
98
|
+
|
|
99
|
+
⚠**빌드에 복사 단계가 붙었다**(`scripts/copy-styles.mjs`). `index.ts` 에서 import 하면
|
|
100
|
+
프리셋이 **강제 로드**되어 계약 ⑴이 깨지므로, 번들과 무관하게 파일만 옮긴다.
|
|
101
|
+
복사할 CSS 가 0개면 **실패한다** — 경로가 어긋났을 때 조용히 초록이 되지 않게.
|
|
102
|
+
|
|
103
|
+
### Fixed
|
|
104
|
+
|
|
105
|
+
- 🔴**`FormSection` 제목에서 `text-transform: uppercase` 와 `letter-spacing` 제거**
|
|
106
|
+
|
|
107
|
+
한글에는 대문자가 없어 `uppercase` 가 **아무 효과가 없고**, 제목에 영문이 섞이면 그것만
|
|
108
|
+
커져 오히려 어수선해진다. 양수 `letter-spacing` 은 **한글 가독성을 떨어뜨린다** —
|
|
109
|
+
라틴 소문자 조판 관례를 그대로 옮기면 안 되는 자리다.
|
|
110
|
+
⇒ 위계는 **크기·굵기·색** 세 신호로만 만든다. 영문 전용 UI 에서 눈썹 텍스트가 필요하면
|
|
111
|
+
`titleStyle` 로 `--u-text-overline-*` 단을 지정한다(그 단은 영문·숫자 라벨을 전제한다).
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
|
|
115
|
+
- **`FormSection`·`FormRow` 의 크기·여백이 토큰 참조가 된다** — `11px`·`20px`·`10px`·`6px`·`8px`
|
|
116
|
+
리터럴이 `--u-text-label-*` · `--u-space-{xs,sm,xl}` 로 바뀌었다.
|
|
117
|
+
⚠**제목 글자가 11px → 13px(`label` 단)로 커진다.** 종전 값은 스케일 축이 생기기 전이라
|
|
118
|
+
고립돼 있었고, 이제 폼 라벨·표 머리행과 **같은 층**을 쓴다.
|
|
119
|
+
오버라이드 계약(§2-1)은 그대로다 — 호출자의 `style`·`titleStyle` 이 여전히 뒤에 온다.
|
|
120
|
+
|
|
121
|
+
### Docs
|
|
122
|
+
|
|
123
|
+
- 헌장에 **L0.5 하우스 스타일 프리셋** 절 신설. ★하우스 값은 **cross-consumer 수요 게이트(§3-1)의
|
|
124
|
+
대상이 아니다** — 게이트가 지키는 것은 **새 표면**이고 프리셋은 표면을 열지 않는다.
|
|
125
|
+
|
|
126
|
+
### 요구 사항
|
|
127
|
+
|
|
128
|
+
`@iyulab/components` **1.21.0 이상**(타입 스케일·여백 상단·반경 상단 축).
|
|
129
|
+
|
|
130
|
+
## 0.6.0
|
|
131
|
+
|
|
132
|
+
### Fixed
|
|
133
|
+
|
|
134
|
+
- **매니페스트가 산출물과 어긋나 있었다** — 양방향 모두.
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
제거 @iyulab/components · @iyulab/data-components · @iyulab/modern-app
|
|
138
|
+
→ dist 가 셋 다 import 하지 않는다(소스에서도 0건)
|
|
139
|
+
추가 react → peerDependencies
|
|
140
|
+
→ dist 가 import 하는데 dependencies·peerDependencies·devDependencies
|
|
141
|
+
어디에도 선언이 없었다
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
★**미사용 선언의 비용은 디스크가 아니라 사본이다.** `0.x` 캐럿은 마이너를 고정하므로
|
|
145
|
+
(`^0.6.0` 은 `0.8.0` 을 받지 못한다) 소비자가 셸을 올릴수록 중복이 확정된다. 지금은
|
|
146
|
+
`dist` 가 import 하지 않아 로드되지 않지만, 그 무해 판정의 근거는 *"지금 import 하지
|
|
147
|
+
않는다"* 하나뿐이었다 — 커스텀 엘리먼트를 등록하는 패키지가 섞여 있어 한 줄이면
|
|
148
|
+
`customElements.define` 이 두 번 불린다.
|
|
149
|
+
|
|
150
|
+
★**`react` 미선언이 더 위험했다.** 번들에서 external 로 빼 놓고 요구하지 않았으니,
|
|
151
|
+
지금 동작하는 이유는 소비자가 React 앱이라 **우연히 있기 때문**이다.
|
|
152
|
+
|
|
153
|
+
⚠**이 패키지의 렌더·동작은 변하지 않는다** — 제거된 셋은 `dist` 가 참조한 적이 없다.
|
|
154
|
+
`--u-*` 커스텀 프로퍼티는 리터럴 폴백과 함께 쓰므로 코드 의존이 아니다(토큰 시트를
|
|
155
|
+
로드하면 그 값을 따라간다).
|
|
156
|
+
|
|
157
|
+
🔴**다만 설치 그래프는 바뀐다.** 이 셋을 `enterprise` 의 전이 의존으로 받아 쓰던
|
|
158
|
+
소비자는 **자기 매니페스트에 직접 선언해야 한다** — 원래 그것이 옳고, 호이스팅에
|
|
159
|
+
기대던 것이 우연히 동작하고 있었을 뿐이다. 엄격한 설치기(pnpm 등)에서는 애초에
|
|
160
|
+
그렇게 쓸 수 없었다.
|
|
161
|
+
⇒ 업그레이드 시 `@iyulab/components`·`@iyulab/data-components`·`@iyulab/modern-app` 를
|
|
162
|
+
직접 쓰고 있다면 자기 `dependencies` 에 있는지 확인할 것.
|
|
163
|
+
|
|
164
|
+
- **`odata-query` 가 번들에 인라인돼 있었다** — external 목록에 없어 라이브러리 코드가
|
|
165
|
+
`dist` 에 통째로 실렸고, 그러면서 `dependencies` 에도 선언돼 있었다. 소비자가 같은
|
|
166
|
+
것을 **두 벌** 갖는 형태다. external 로 옮겼다(선언은 그대로).
|
|
167
|
+
|
|
168
|
+
## 0.5.0
|
|
169
|
+
|
|
170
|
+
### Added
|
|
171
|
+
|
|
172
|
+
- ★**[LOB 계층 헌장](./docs/lob-layers.md)** — 이 패키지가 **무엇을 소유하고 무엇을 소유하지
|
|
173
|
+
않는지**를 정한 문서. L0~L3 계층 정의 · 오버라이드 계약 · 카탈로그 등급 · 의존 방향.
|
|
174
|
+
|
|
175
|
+
- **오버라이드 계약이 1급 조항이다** — 소비자가 조정할 경로가 없는 패턴은 이 계층에
|
|
176
|
+
들어올 수 없다. 경로가 없으면 소비자는 통째로 복제하게 되고, 그러면 이 계층은
|
|
177
|
+
**쓰기 전보다 나쁜 상태**를 만든다.
|
|
178
|
+
- **카탈로그에 등급을 매긴다** — 반복이 실측된 것만 착수하고, 요청만 있는 것은
|
|
179
|
+
**만들지 않는다**고 명시한다.
|
|
180
|
+
- ★**프레임워크 전제를 못 박는다**: *L0·L1 은 프레임워크 중립, L2·L3 는 React 전제.*
|
|
181
|
+
적어 두지 않으면 다른 프레임워크의 소비자가 나타났을 때 아무도 결정하지 않은 채
|
|
182
|
+
갈라진다.
|
|
183
|
+
|
|
184
|
+
헌장과 구현이 어긋나면 실패하는 대조 테스트 6건이 함께 있다 — 계층 헌장의 실패 형태는
|
|
185
|
+
위반이 아니라 **표류**이고, 표류는 문서와 코드가 각각 멀쩡해 보여서 눈에 띄지 않는다.
|
|
186
|
+
|
|
187
|
+
- **`FormRow`에 `columns`** — 2열 고정이 맞지 않을 때 컴포넌트를 복제하지 않고 조정한다.
|
|
188
|
+
(README 가 *"로드맵에 있다"* 고 적어 두었던 항목이다.)
|
|
189
|
+
- **`FormSection`·`FormRow`에 `className`·`style`**(+ `FormSection`의 `titleStyle`) —
|
|
190
|
+
기본값 **뒤에** 병합되므로 필요한 항목만 골라 덮을 수 있다.
|
|
191
|
+
- **`FormSection`의 `title`이 `ReactNode`를 받는다** — 종전에는 `string` 이라 배지·아이콘을
|
|
192
|
+
붙이려면 블록을 복제해야 했다.
|
|
193
|
+
|
|
194
|
+
### Fixed
|
|
195
|
+
|
|
196
|
+
- **폼 블록 제목이 브랜드 색을 따르지 않던 문제 수정** — 팔레트(`--u-blue-600`)를 직접
|
|
197
|
+
읽고 있었다. 소비자가 브랜드를 맞추려면 팔레트를 덮는 수밖에 없었고, 그러면 *진짜
|
|
198
|
+
파랑*이 필요한 곳까지 함께 바뀐다. 역할 토큰(`--u-primary-color`)에서 파생하도록 고쳤다.
|
|
199
|
+
- **폼 블록 제목의 대비 부족 해소** — 11px 텍스트가 3.68:1 로 WCAG AA(4.5:1)에 미달했다.
|
|
200
|
+
한 단 어두운 파생값(4.85:1)으로 교체했다.
|
|
201
|
+
|
|
202
|
+
## 0.4.0
|
|
203
|
+
|
|
204
|
+
### Added
|
|
205
|
+
|
|
206
|
+
- **`createODataService(config)`** — OData v4 + custom REST 서비스 팩토리. 여러 소비앱이 동일하게 재작성하던 CRUD 래퍼(401 세션 처리, 에러 메시지 추출, 성공 토스트, 204 빈-바디 안전 파싱)를 범용 primitive 로 승격.
|
|
207
|
+
- 도메인/로케일 요소는 주입: `baseUrl`, `onUnauthorized`, `notify`(토스트 훅), `messages`(문구 오버라이드 — 기본 영어), `formatError`(에러 포매팅 훅).
|
|
208
|
+
- 반환 서비스: `odataGet/odataGetById/odataCount/odataPost/odataPostQuiet/odataPatch/odataDelete`, `apiGet/apiPost/apiPatch/apiDelete`, `fetchRaw`, `odataUrl`/`apiUrl`, `sourceDefaults`(flex-table `useODataSource` 용).
|
|
209
|
+
- `ApiError`(HTTP status 포함) 함께 export.
|
|
210
|
+
- 신규 의존성: `@iyulab/http-client`, `odata-query`.
|
|
211
|
+
- `vitest` 단위 테스트 인프라 도입(모노레포 표준) — `npm test`.
|
|
212
|
+
- **`createAuthClient<TUser, TCredentials>(config)`** — 쿠키 세션 인증 클라이언트 팩토리. `fetchMe`(미인증 시 null)/`login`/`logout` 흐름을 승격. 사용자·자격증명 형태는 제네릭으로 앱이 정의(라이브러리는 URL 호출만). 원시 `fetch` 사용(401 인터셉터 우회 — null 이 곧 미인증 신호). `getPermissions` 지정 시 성공/로그아웃마다 권한 store 자동 갱신.
|
|
213
|
+
- **권한 스냅샷 store** — `createPermissionStore(initial?)`(factory) + 기본 싱글톤 바인딩 free 함수(`setPermissions`/`getPermissions`/`hasPermission`/`hasAnyPermission`/`hasAllPermissions`/`clearPermissions`). 권한 코드는 불투명 문자열, false-by-default, `subscribe` 반응형 훅. React·Lit 공통.
|
|
214
|
+
|
|
215
|
+
### Notes
|
|
216
|
+
|
|
217
|
+
- 토스트/문구·사용자 형태·권한 코드를 모두 주입/제네릭으로 받으므로 서비스·인증 모듈은 `@iyulab/modern-app` 에 의존하지 않는다(순수·테스트 용이).
|
|
218
|
+
- 도메인 요소(엔티티 목록, `isPortalUser` 같은 도메인 판정, 권한 코드 상수)는 라이브러리에 넣지 않고 앱 adapter 에 남긴다.
|
package/dist/FormRow.d.ts
CHANGED
package/dist/FormSection.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LocaleNamespace } from '@iyulab/components';
|
|
1
2
|
/**
|
|
2
3
|
* `@iyulab/enterprise` 의 화면 문자열 — **영어 기본 + 로케일 레지스트리**.
|
|
3
4
|
*
|
|
@@ -22,4 +23,4 @@
|
|
|
22
23
|
*/
|
|
23
24
|
export type EnterpriseMessageKey = 'progressNotStarted' | 'progressEarly' | 'progressInProgress' | 'progressPastMid' | 'progressAlmost' | 'progressDone' | 'urgencyOverdue' | 'urgencyCritical' | 'urgencyUrgent' | 'urgencySoon' | 'urgencyNormal' | 'daysOverdue' | 'daysToday' | 'daysRemaining';
|
|
24
25
|
/** 이 패키지의 문자열 묶음. 소비자는 `messages.register(locale, table)` 로 덮거나 언어를 더한다. */
|
|
25
|
-
export declare const messages:
|
|
26
|
+
export declare const messages: LocaleNamespace<EnterpriseMessageKey>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/enterprise",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Enterprise utilities and components for iyulab framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"enterprise",
|
|
@@ -17,10 +17,15 @@
|
|
|
17
17
|
"dist",
|
|
18
18
|
"package.json",
|
|
19
19
|
"README.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
20
21
|
"LICENSE"
|
|
21
22
|
],
|
|
22
23
|
"type": "module",
|
|
23
24
|
"types": "dist/index.d.ts",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"sideEffects": false,
|
|
24
29
|
"exports": {
|
|
25
30
|
".": {
|
|
26
31
|
"types": "./dist/index.d.ts",
|
|
@@ -29,15 +34,18 @@
|
|
|
29
34
|
"./styles/preset.css": "./dist/styles/preset.css"
|
|
30
35
|
},
|
|
31
36
|
"scripts": {
|
|
32
|
-
"build": "vite build && node scripts/copy-styles.mjs",
|
|
33
|
-
"test": "vitest run"
|
|
37
|
+
"build": "npm run typecheck && vite build && node scripts/copy-styles.mjs",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"typecheck": "tsc --noEmit"
|
|
34
40
|
},
|
|
35
41
|
"dependencies": {
|
|
36
42
|
"@iyulab/http-client": "^0.10.0",
|
|
37
43
|
"odata-query": "^8.1.0"
|
|
38
44
|
},
|
|
39
45
|
"devDependencies": {
|
|
46
|
+
"@iyulab/components": "^1.23.0",
|
|
40
47
|
"@types/node": "^26.1.1",
|
|
48
|
+
"@types/react": "^19.2.14",
|
|
41
49
|
"typescript": "^5.9.3",
|
|
42
50
|
"vite": "^8.1.4",
|
|
43
51
|
"vite-plugin-dts": "^5.0.3",
|