create-mendix-widget-gleam 2.0.7 → 2.0.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mendix-widget-gleam",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "description": "Scaffold a Mendix Pluggable Widget powered by Gleam",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/src/index.mjs CHANGED
@@ -197,19 +197,20 @@ async function generateClaudeMd(targetDir, names, pm, pmConfig) {
197
197
 
198
198
  const content = `# ${names.pascalCase}
199
199
 
200
- Gleam 언어로 Mendix Pluggable Widget을 개발하여 "Hello World"를 화면에 렌더링하는 프로젝트.
200
+ Gleam 언어로 Mendix Pluggable Widget을 개발하는 프로젝트.
201
201
 
202
202
  ## Goal
203
203
 
204
- **JSX를 사용하지 않고, 오직 Gleam으로만** 위젯을 작성한다. Gleam 코드를 JavaScript로 컴파일하고, 컴파일된 JS가 곧 Mendix Pluggable Widget의 진입점이 된다. React와 Mendix API 바인딩은 [glendix](https://hexdocs.pm/glendix/) 패키지가 제공한다.
204
+ **JSX를 사용하지 않고, 오직 Gleam으로만** 위젯을 작성한다. Gleam 코드를 JavaScript로 컴파일하고, 컴파일된 JS가 곧 Mendix Pluggable Widget의 진입점이 된다.
205
205
 
206
206
  ## Tech Stack
207
207
 
208
208
  - **Gleam** → JavaScript 컴파일 (target: javascript)
209
- - **[glendix](https://hexdocs.pm/glendix/)** — React + Mendix Pluggable Widget API의 Gleam FFI 바인딩 (Hex 패키지)
209
+ - **[glendix](https://hexdocs.pm/glendix/)** — React + Mendix Pluggable Widget API의 Gleam FFI 바인딩 (Hex 패키지). React 원시 함수와 Mendix 런타임 타입 접근자를 타입 안전하게 제공
210
210
  - **Mendix Pluggable Widget** (React 19)
211
211
  - **Package Manager**: ${pm} (기본 npm 의존성은 \`gleam run -m glendix/install\`로 설치, \`bindings.json\` 외부 React 패키지는 수동 설치 필요)
212
212
  - **Build**: \`@mendix/pluggable-widgets-tools\` (Rollup 기반)
213
+ - **Package**: \`.mpk\` (ZIP 아카이브) → Mendix Studio Pro에 배포
213
214
 
214
215
  ## Architecture
215
216
 
@@ -220,28 +221,94 @@ src/
220
221
  editor_preview.gleam # Studio Pro 디자인 뷰 미리보기
221
222
  components/
222
223
  hello_world.gleam # Hello World 공유 컴포넌트
223
- ${names.pascalCase}.xml # 위젯 속성 정의
224
+ ${names.pascalCase}.xml # 위젯 속성 정의 (Mendix Studio Pro용)
224
225
  package.xml # Mendix 패키지 매니페스트
225
226
  ui/
226
227
  ${names.pascalCase}.css # 위젯 스타일시트
227
228
  widgets/ # .mpk 위젯 파일 (glendix/widget로 바인딩)
228
229
  bindings.json # 외부 React 컴포넌트 바인딩 설정
229
- package.json # npm 의존성 (React, 외부 라이브러리 등)
230
- gleam.toml # Gleam 프로젝트 설정 (glendix 의존성 포함)
230
+ package.json # npm 의존성 (React, 빌드 도구 등)
231
+ gleam.toml # Gleam 프로젝트 설정
231
232
  docs/
232
- gleam_language_tour.md # Gleam 언어 레퍼런스
233
- glendix_guide.md # glendix 사용 가이드
233
+ gleam_language_tour.md # Gleam 언어 레퍼런스 (문법 전체)
234
+ glendix_guide.md # glendix 사용 가이드 (React/Mendix 바인딩 전체)
234
235
  \`\`\`
235
236
 
236
- React/Mendix FFI 바인딩은 프로젝트에 포함되지 않으며, [glendix](https://hexdocs.pm/glendix/) Hex 패키지로 제공된다.
237
+ ## glendix React + Mendix 바인딩 패키지
238
+
239
+ React FFI와 Mendix API 바인딩은 별도 Hex 패키지 [glendix](https://hexdocs.pm/glendix/)로 분리되어 있다. 이 프로젝트는 glendix를 의존성으로 사용한다.
240
+
241
+ glendix가 제공하는 모듈:
242
+
243
+ React:
244
+ - \`glendix/react\` — 핵심 타입(\`ReactElement\`, \`JsProps\`, \`Component\`, \`Context\`, \`Ref\`) + \`element\`/\`element_\`/\`void_element\`/\`component_el\`/\`component_el_\`/\`void_component_el\`/\`fragment\`/\`text\`/\`none\` + 조건부 렌더링(\`when\`, \`when_some\`) + \`define_component\`/\`memo\`/\`StrictMode\`/\`Suspense\`/\`Profiler\`/\`portal\`/\`forwardRef\`
245
+ - \`glendix/react/attribute\` — Attribute 리스트 API (\`[attribute.class("x"), event.on_click(handler)]\`) + 90+ HTML 속성 함수 + \`attribute.none()\` 조건부 속성
246
+ - \`glendix/react/hook\` — React Hooks (\`useState\`, \`useEffect\`, \`useLayoutEffect\`, \`useInsertionEffect\`, \`useMemo\`, \`useCallback\`, \`useRef\`, \`useReducer\`, \`useContext\`, \`useId\`, \`useTransition\`, \`useDeferredValue\`, \`useOptimistic\`, \`useImperativeHandle\`, \`useLazyState\`, \`useSyncExternalStore\`, \`useDebugValue\`)
247
+ - \`glendix/react/event\` — 15개 이벤트 타입 + 148+ 핸들러 Attribute (캡처 단계 포함) + 67+ 접근자
248
+ - \`glendix/react/html\` — 75+ HTML 태그 편의 함수 (순수 Gleam, FFI 없음)
249
+ - \`glendix/react/svg\` — 57 SVG 요소 편의 함수 (순수 Gleam, FFI 없음)
250
+ - \`glendix/react/svg_attribute\` — 97+ SVG 전용 속성 함수 (순수 Gleam, FFI 없음)
251
+ - \`glendix/binding\` — 외부 React 컴포넌트 바인딩 (\`bindings.json\` + \`binding.module\`/\`binding.resolve\`)
252
+ - \`glendix/widget\` — .mpk 위젯 컴포넌트 바인딩 (\`widget.component\`)
253
+
254
+ Mendix:
255
+ - \`glendix/mendix\` — \`ValueStatus\`, \`ObjectItem\`, JsProps 접근자
256
+ - \`glendix/mendix/editable_value\` — 편집 가능한 값
257
+ - \`glendix/mendix/action\` — 액션 실행
258
+ - \`glendix/mendix/dynamic_value\` — 동적 읽기 전용 값
259
+ - \`glendix/mendix/list_value\` — 리스트 데이터 + 정렬/필터
260
+ - \`glendix/mendix/list_attribute\` — 리스트 아이템별 접근
261
+ - \`glendix/mendix/selection\` — 단일/다중 선택
262
+ - \`glendix/mendix/reference\` — 단일 연관 참조 (ReferenceValue)
263
+ - \`glendix/mendix/reference_set\` — 다중 연관 참조 (ReferenceSetValue)
264
+ - \`glendix/mendix/date\` — JS Date 래퍼 (월 1-based)
265
+ - \`glendix/mendix/big\` — Big.js 고정밀 십진수 래퍼
266
+ - \`glendix/mendix/file\` — 파일/이미지
267
+ - \`glendix/mendix/icon\` — 아이콘
268
+ - \`glendix/mendix/formatter\` — 값 포맷팅/파싱
269
+ - \`glendix/mendix/filter\` — 필터 조건 빌더
270
+
271
+ 빌드 스크립트:
272
+ - \`glendix/cmd\` — 셸 명령어 실행 + 패키지 매니저 자동 감지 (\`exec\`, \`detect_runner\`, \`run_tool\`)
273
+ - \`glendix/build\` — 프로덕션 빌드 (\`gleam run -m glendix/build\`)
274
+ - \`glendix/dev\` — 개발 서버 (\`gleam run -m glendix/dev\`)
275
+ - \`glendix/start\` — Mendix 연동 (\`gleam run -m glendix/start\`)
276
+ - \`glendix/install\` — 의존성 설치 (\`gleam run -m glendix/install\`)
277
+ - \`glendix/release\` — 릴리즈 빌드 (\`gleam run -m glendix/release\`)
278
+ - \`glendix/lint\` — ESLint 실행 (\`gleam run -m glendix/lint\`)
279
+ - \`glendix/lint_fix\` — ESLint 자동 수정 (\`gleam run -m glendix/lint_fix\`)
280
+ - \`glendix/marketplace\` — Mendix Marketplace 위젯 검색/다운로드 (\`gleam run -m glendix/marketplace\`)
281
+
282
+ ## Integration Strategy: Gleam + glendix → Mendix Widget
283
+
284
+ JSX 파일 없이 Gleam + glendix로 위젯을 구현한다. glendix가 React 원시 함수와 Mendix 런타임 타입 접근을 타입 안전하게 제공하므로, 위젯 프로젝트에서는 비즈니스 로직에만 집중한다.
285
+
286
+ 핵심 원리:
287
+ - Gleam 함수 \`fn(JsProps) -> ReactElement\`는 React 함수형 컴포넌트와 동일한 시그니처
288
+ - glendix의 FFI 레이어(\`react_ffi.mjs\`, \`mendix_ffi.mjs\`)는 얇은 어댑터일 뿐, 위젯 로직과 UI 구조는 전부 Gleam 코드
289
+ - Mendix가 전달하는 props(순수 JS 객체)를 \`mendix.get_prop\`/\`mendix.get_string_prop\` 등으로 접근
290
+ - Mendix 복합 타입(\`EditableValue\`, \`ActionValue\`, \`ListValue\` 등)은 opaque type + FFI 접근자로 타입 안전하게 다룸
291
+ - JS \`undefined\` ↔ Gleam \`Option\` 변환은 FFI 경계에서 자동 처리
292
+ - HTML 속성은 Attribute 리스트 기반 선언적 API로 구성 (\`[attribute.class("x"), event.on_click(handler)]\`)
293
+ - Gleam List는 linked list이므로 FFI에서 \`.toArray()\` 호출 후 React.createElement에 spread
294
+ - Gleam 튜플 \`#(a, b)\` = JS \`[a, b]\` — useState 반환값과 직접 호환
295
+
296
+ 핵심 제약사항:
297
+ - Mendix 위젯의 진입점은 MUST React 컴포넌트여야 한다 (\`pluginWidget="true"\`)
298
+ - Gleam 컴파일 출력은 ES 모듈 형식이므로 Rollup 번들링과 호환된다
299
+ - 위젯 ID 형식: \`mendix.${names.lowerCase}.${names.pascalCase}\`
300
+ - JSX 파일을 작성하지 않는다. 모든 React 로직은 Gleam + glendix로 구현한다
301
+ - Gleam 컴파일 출력이 Mendix 빌드 도구의 진입점으로 연결되도록 빌드 설정 커스터마이징이 필요하다
237
302
 
238
303
  ## Build Pipeline
239
304
 
240
305
  \`\`\`
241
306
  [src/*.gleam] + [glendix 패키지 (Hex)]
242
- ↓ gleam run -m glendix/build
243
- [build/dev/javascript/${names.snakeCase}/*.mjs]
244
- [build/dev/javascript/glendix/glendix/*.mjs]
307
+ ↓ gleam run -m glendix/build (내부적으로 gleam build 자동 수행)
308
+ [build/dev/javascript/${names.snakeCase}/*.mjs] (gleam.toml name 기준)
309
+ [build/dev/javascript/glendix/glendix/*.mjs] (glendix 컴파일 출력)
310
+ [build/dev/javascript/glendix/glendix/react_ffi.mjs]
311
+ [build/dev/javascript/glendix/glendix/mendix_ffi.mjs]
245
312
  ↓ 브릿지 JS (자동 생성)가 import
246
313
  ↓ Rollup (pluggable-widgets-tools build:web)
247
314
  [dist/1.0.0/mendix.${names.lowerCase}.${names.pascalCase}.mpk]
@@ -249,8 +316,10 @@ React/Mendix FFI 바인딩은 이 프로젝트에 포함되지 않으며, [glend
249
316
 
250
317
  ## Commands
251
318
 
319
+ 모든 명령어는 \`gleam\`으로 통일. \`gleam run -m\`은 Gleam 컴파일을 자동 수행한 뒤 스크립트를 실행한다.
320
+
252
321
  \`\`\`bash
253
- gleam run -m glendix/install # 의존성 설치 + 바인딩 코드 생성 (외부 React 패키지는 사전에 수동 설치 필요)
322
+ gleam run -m glendix/install # 의존성 설치 (Gleam deps 자동 + PM 자동 감지, bindings.json 바인딩 코드 생성. 단, 외부 React 패키지는 사전에 수동 설치 필요)
254
323
  gleam run -m glendix/build # 위젯 프로덕션 빌드 (.mpk 생성)
255
324
  gleam run -m glendix/dev # 개발 서버 (HMR, port 3000)
256
325
  gleam run -m glendix/start # Mendix 테스트 프로젝트와 연동 개발
@@ -258,7 +327,7 @@ gleam run -m glendix/lint # ESLint 실행
258
327
  gleam run -m glendix/lint_fix # ESLint 자동 수정
259
328
  gleam run -m glendix/release # 릴리즈 빌드
260
329
  gleam run -m glendix/marketplace # Mendix Marketplace 위젯 검색/다운로드
261
- gleam build --target javascript # Gleam → JS 컴파일만
330
+ gleam build --target javascript # Gleam → JS 컴파일만 (스크립트 없이)
262
331
  gleam test # Gleam 테스트 실행
263
332
  gleam format # Gleam 코드 포맷팅
264
333
  \`\`\`
@@ -268,52 +337,57 @@ gleam format # Gleam 코드 포맷팅
268
337
  \`docs/glendix_guide.md\` 파일에 glendix 패키지의 사용법이 수록되어 있다. 주요 내용:
269
338
  - 프로젝트 설정 및 첫 번째 위젯 만들기
270
339
  - 핵심 개념: opaque 타입, undefined ↔ Option 변환, Attribute 리스트 API
271
- - React 바인딩: 엘리먼트 생성, Attribute 리스트, HTML 태그 함수, Hooks, 이벤트 처리, 조건부/리스트 렌더링, 스타일, 외부 React 컴포넌트 바인딩, .mpk 위젯 바인딩
272
- - Mendix 바인딩: Props 접근, ValueStatus, EditableValue, ActionValue, DynamicValue, ListValue, ListAttribute, Selection, Reference, Filter, JsDate, Big
340
+ - React 바인딩: 엘리먼트 생성(\`element\`/\`element_\`/\`void_element\`/\`component_el\`), Attribute 리스트, HTML 태그 함수, Hooks(\`useState\`/\`useEffect\`/\`useMemo\`/\`useCallback\`/\`useRef\` 등), 이벤트 처리, 조건부/리스트 렌더링, 스타일, 외부 React 컴포넌트 바인딩(\`bindings.json\`), .mpk 위젯 바인딩(\`widgets/\`)
341
+ - Mendix 바인딩: Props 접근, ValueStatus, EditableValue, ActionValue, DynamicValue, ListValue(페이지네이션/정렬), ListAttribute, Selection, Reference, Filter 빌더, JsDate, Big, FileValue/WebIcon/ValueFormatter
273
342
  - Marketplace 연동: Mendix Marketplace에서 위젯 검색/다운로드 (\`glendix/marketplace\`)
274
343
  - 실전 패턴: 폼 입력 위젯, 데이터 테이블, 검색 가능 리스트, 컴포넌트 합성
275
- - 트러블슈팅
344
+ - 트러블슈팅: 빌드/런타임 에러, Hook 규칙
276
345
 
277
- ## glendix Modules
278
-
279
- React:
280
- - \`glendix/react\` — 핵심 타입 + element/element_/void_element/component_el + fragment/text/none + 조건부 렌더링 + define_component/memo/Context
281
- - \`glendix/react/attribute\` — Attribute 리스트 API (90+ HTML 속성 함수)
282
- - \`glendix/react/hook\` — React Hooks (useState, useEffect, useMemo, useCallback, useRef 등)
283
- - \`glendix/react/event\` — 15개 이벤트 타입 + 148+ 핸들러 Attribute + 67+ 접근자
284
- - \`glendix/react/html\` — 75+ HTML 태그 편의 함수
285
- - \`glendix/react/svg\` — 57 SVG 요소 편의 함수
286
- - \`glendix/react/svg_attribute\` — 97+ SVG 전용 속성 함수
287
- - \`glendix/binding\` — 외부 React 컴포넌트 바인딩
288
- - \`glendix/widget\` — .mpk 위젯 컴포넌트 바인딩
289
- - \`glendix/marketplace\` — Mendix Marketplace 위젯 검색/다운로드
346
+ ## Gleam Language Reference
290
347
 
291
- Mendix:
292
- - \`glendix/mendix\` \`ValueStatus\`, \`ObjectItem\`, Props 접근자
293
- - \`glendix/mendix/editable_value\` 편집 가능한
294
- - \`glendix/mendix/action\` 액션 실행
295
- - \`glendix/mendix/dynamic_value\` 동적 읽기 전용
296
- - \`glendix/mendix/list_value\` 리스트 데이터 + 정렬/필터
297
- - \`glendix/mendix/list_attribute\` 리스트 아이템별 접근
298
- - \`glendix/mendix/selection\` — 단일/다중 선택
299
- - \`glendix/mendix/reference\` — 단일 연관 참조
300
- - \`glendix/mendix/reference_set\` — 다중 연관 참조
301
- - \`glendix/mendix/date\` — JS Date 래퍼
302
- - \`glendix/mendix/big\` — Big.js 고정밀 십진수 래퍼
303
- - \`glendix/mendix/file\` — 파일/이미지
304
- - \`glendix/mendix/icon\` — 아이콘
305
- - \`glendix/mendix/formatter\` — 값 포맷팅/파싱
306
- - \`glendix/mendix/filter\` — 필터 조건 빌더
348
+ \`docs/gleam_language_tour.md\` 파일에 Gleam 문법 전체가 수록되어 있다. 주요 특징:
349
+ - 정적 타입, 불변 데이터, 패턴 매칭
350
+ - \`pub fn\` 으로 외부 공개 함수 선언
351
+ - \`import gleam/모듈\` 표준 라이브러리 사용
352
+ - JavaScript 타겟 시 \`@external(javascript, "모듈", "함수")\` JS 함수 호출 가능
353
+ - Result 타입(\`Ok\`, \`Error\`)으로 에러 처리
354
+ - \`use\` 키워드로 콜백 체이닝 간소화
307
355
 
308
356
  ## Mendix Widget Conventions
309
357
 
310
- - 위젯 ID: \`mendix.${names.lowerCase}.${names.pascalCase}\`
311
- - JSX 파일을 작성하지 않는다. 모든 React 로직은 Gleam + glendix로 구현
312
- - 위젯 프로젝트에 FFI 파일을 직접 작성하지 않는다 React/Mendix FFI는 glendix가 제공
358
+ - \`src/${names.pascalCase}.xml\`: 위젯 속성 정의. \`<property>\` 추가 시 빌드 도구가 자동으로 타입 생성
359
+ - \`src/package.xml\`: 패키지 매니페스트. \`widgetFile\` 경로와 컴파일 출력 경로 지정
360
+ - 위젯 컴포넌트는 \`default export\` 또는 \`named export\` 함수형 React 컴포넌트
361
+ - \`needsEntityContext="true"\` → 위젯이 Mendix 데이터 컨텍스트 필요
362
+ - \`offlineCapable="true"\` → 오프라인 지원
363
+ - editorConfig도 Gleam으로 작성. 브릿지 JS는 glendix가 빌드 시 자동 생성/삭제한다
364
+
365
+ ## Mendix Documentation
366
+
367
+ Mendix 공식 문서 사이트(docs.mendix.com)는 접근 불가. 대신 GitHub raw 소스를 사용:
368
+ - Base: \`https://github.com/mendix/docs/blob/development/content/en/docs\`
369
+ - Pluggable Widgets API: \`apidocs-mxsdk/apidocs/pluggable-widgets/\`
370
+ - How-to: \`howto/extensibility/\`
371
+ - Widget 빌드 도구 소스: \`https://github.com/mendix/widgets-tools\`
372
+ - 공식 위젯 예제: \`https://github.com/mendix/web-widgets\`
373
+
374
+ ## Important Notes
375
+
376
+ - Gleam 컴파일 출력 경로와 Rollup 번들링 입력 경로가 MUST 일치해야 한다
377
+ - \`package.json\`의 \`packagePath: "mendix"\`가 위젯 배포 경로를 결정한다
378
+ - Mendix 위젯 이름은 영문자(a-zA-Z)만 허용된다
379
+ - \`.mpk\` 파일은 \`dist/\` 디렉토리에 생성된다
380
+ - 테스트 프로젝트 경로: \`./tests/testProject\`
381
+ - Gleam→JS→Mendix Widget 파이프라인은 공식 지원되지 않는 조합이므로, 빌드 설정 커스터마이징이 필요할 수 있다
382
+ - **JSX/JS 파일을 직접 작성하지 않는다.** 모든 위젯 로직과 UI는 Gleam으로 작성하고 JS로 컴파일한다
383
+ - Mendix 빌드 도구가 요구하는 브릿지 JS 파일(진입점, editorConfig, editorPreview)은 glendix가 빌드 시 자동 생성/삭제한다. 수동 관리 불필요
384
+ - Redraw 등 외부 Gleam React 라이브러리는 사용하지 않는다. glendix가 Gleam FFI로 React API를 직접 바인딩한다
385
+ - React/Mendix FFI 바인딩은 glendix 패키지에서 제공한다. 위젯 프로젝트에 FFI 파일을 직접 작성하지 않는다
313
386
 
314
387
  ## Code Style
315
388
 
316
389
  - Gleam 파일: \`gleam format\` 사용
390
+ - Gleam 컴파일 출력 JS: 수동 편집하지 않는다
317
391
  - 한국어 주석 사용
318
392
  `;
319
393