create-mendix-widget-gleam 3.0.2 → 4.0.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gleam 언어로 Mendix Pluggable Widget 프로젝트를 스케폴딩하는 CLI 도구.
4
4
 
5
- JSX 없이, **Gleam + [glendix](https://hexdocs.pm/glendix/)**로 React 컴포넌트를 작성하여 Mendix Studio Pro에서 동작하는 위젯을 만든다.
5
+ JSX 없이, **Gleam + [glendix](https://hexdocs.pm/glendix/)/[mendraw](https://hexdocs.pm/mendraw/)**로 React 컴포넌트를 작성하여 Mendix Studio Pro에서 동작하는 위젯을 만든다.
6
6
 
7
7
  ## 사용법
8
8
 
@@ -27,14 +27,12 @@ my-widget/
27
27
  editor_preview.gleam # Studio Pro 디자인 뷰 미리보기
28
28
  components/
29
29
  hello_world.gleam # Hello World 공유 컴포넌트
30
- widgets/ # .mpk 위젯 파일 (glendix/widget로 바인딩)
31
- bindings.json # 외부 React 컴포넌트 바인딩 설정
32
30
  package.json # npm 의존성 (React, 외부 라이브러리 등)
33
- gleam.toml # Gleam 프로젝트 설정 (glendix >= 3.0.0 의존성 포함)
31
+ gleam.toml # Gleam 프로젝트 설정 (glendix >= 4.0.3 + mendraw >= 1.1.11 의존성 포함)
34
32
  CLAUDE.md # AI 어시스턴트용 프로젝트 컨텍스트
35
33
  ```
36
34
 
37
- React/Mendix FFI 및 JS Interop 바인딩은 프로젝트에 포함되지 않으며, [glendix](https://hexdocs.pm/glendix/) Hex 패키지로 제공된다.
35
+ React/Mendix FFI 및 JS Interop 바인딩은 프로젝트에 포함되지 않으며, [glendix](https://hexdocs.pm/glendix/) 및 [mendraw](https://hexdocs.pm/mendraw/) Hex 패키지로 제공된다.
38
36
 
39
37
  ## 생성 후 시작하기
40
38
 
@@ -43,7 +41,7 @@ cd my-widget
43
41
  gleam run -m glendix/install # 의존성 설치
44
42
  gleam run -m glendix/dev # 개발 서버 시작
45
43
  gleam run -m glendix/build # 프로덕션 빌드 (.mpk 생성)
46
- gleam run -m glendix/marketplace # Marketplace 위젯 검색/다운로드
44
+ gleam run -m mendraw/marketplace # Marketplace 위젯 검색/다운로드
47
45
  gleam run -m glendix/define # 위젯 프로퍼티 정의 TUI 에디터
48
46
  ```
49
47
 
@@ -51,9 +49,9 @@ gleam run -m glendix/define # 위젯 프로퍼티 정의 TUI 에디터
51
49
 
52
50
  생성된 프로젝트는 [glendix](https://hexdocs.pm/glendix/) Hex 패키지를 의존성으로 사용한다. glendix가 React 원시 함수와 Mendix Pluggable Widget API 전체에 대한 타입 안전한 Gleam 바인딩을 제공한다:
53
51
 
54
- - **React** — `react`, `react/attribute`, `react/hook`, `react/event`, `react/html`, `react/svg`, `react/svg_attribute`, `binding`, `widget`
55
- - **Mendix** — `mendix`, `mendix/editable_value`, `mendix/action`, `mendix/list_value`, `mendix/selection`, `mendix/reference`, `mendix/reference_set`, `mendix/date`, `mendix/big`, `mendix/filter` 등
56
- - **JS Interop** — `js/array`, `js/object`, `js/json`, `js/promise`, `js/dom`, `js/timer`
52
+ - **React** — `redraw`, `redraw/dom/attribute`, `redraw/hooks`, `redraw/dom/events`, `redraw/dom/html`, `redraw/dom/svg`; bindings via `glendix/binding`
53
+ - **Mendix** (mendraw) — `mendraw/mendix`, `mendraw/mendix/editable_value`, `mendraw/mendix/action`, `mendraw/mendix/list_value`, `mendraw/mendix/selection`, `mendraw/mendix/reference`, `mendraw/mendix/reference_set`, `mendraw/mendix/date`, `mendraw/mendix/decimal`, `mendraw/mendix/filter` 등
54
+ - **JS Interop** (glendix) — `glendix/js/array`, `glendix/js/object`, `glendix/js/json`, `glendix/js/promise`, `glendix/js/dom`, `glendix/js/timer`
57
55
 
58
56
  ## 라이선스
59
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mendix-widget-gleam",
3
- "version": "3.0.2",
3
+ "version": "4.0.1",
4
4
  "description": "Scaffold a Mendix Pluggable Widget powered by Gleam",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/src/i18n.mjs CHANGED
@@ -48,11 +48,10 @@ const messages = {
48
48
  "progress.depsInstalled": "Dependencies installed",
49
49
  "error.depsInstallFail":
50
50
  "⚠ Dependency installation failed. Run manually in the project directory:",
51
- "progress.playwrightInstalling": "Installing Playwright Chromium...",
52
- "progress.playwrightInstalled": "Playwright Chromium installed",
53
- "progress.playwrightExists": "Playwright Chromium already installed",
54
- "error.playwrightFail":
55
- "⚠ Playwright browser installation failed. Run manually in the project directory:",
51
+ "progress.glendixInstalling": "Running glendix/install...",
52
+ "progress.glendixInstalled": "glendix/install complete",
53
+ "error.glendixInstallFail":
54
+ "⚠ glendix/install failed. Run manually:",
56
55
  "progress.buildingWidget": "Building widget...",
57
56
  "progress.widgetBuilt": "Widget build complete",
58
57
  "error.buildFail":
@@ -119,11 +118,10 @@ const messages = {
119
118
  "progress.depsInstalled": "의존성 설치 완료",
120
119
  "error.depsInstallFail":
121
120
  "⚠ 의존성 설치 실패. 프로젝트 디렉토리에서 직접 실행하세요:",
122
- "progress.playwrightInstalling": "Playwright Chromium 설치 중...",
123
- "progress.playwrightInstalled": "Playwright Chromium 설치 완료",
124
- "progress.playwrightExists": "Playwright Chromium 이미 설치됨",
125
- "error.playwrightFail":
126
- "⚠ Playwright 브라우저 설치 실패. 프로젝트 디렉토리에서 직접 실행하세요:",
121
+ "progress.glendixInstalling": "glendix/install 실행 중...",
122
+ "progress.glendixInstalled": "glendix/install 완료",
123
+ "error.glendixInstallFail":
124
+ "⚠ glendix/install 실패. 직접 실행하세요:",
127
125
  "progress.buildingWidget": "위젯 빌드 중...",
128
126
  "progress.widgetBuilt": "위젯 빌드 완료",
129
127
  "error.buildFail":
@@ -190,11 +188,10 @@ const messages = {
190
188
  "progress.depsInstalled": "依存関係インストール完了",
191
189
  "error.depsInstallFail":
192
190
  "⚠ 依存関係インストール失敗。プロジェクトディレクトリで直接実行してください:",
193
- "progress.playwrightInstalling": "Playwright Chromiumインストール中...",
194
- "progress.playwrightInstalled": "Playwright Chromiumインストール完了",
195
- "progress.playwrightExists": "Playwright Chromiumインストール済み",
196
- "error.playwrightFail":
197
- "⚠ Playwrightブラウザインストール失敗。プロジェクトディレクトリで直接実行してください:",
191
+ "progress.glendixInstalling": "glendix/installを実行中...",
192
+ "progress.glendixInstalled": "glendix/install完了",
193
+ "error.glendixInstallFail":
194
+ "⚠ glendix/install失敗。直接実行してください:",
198
195
  "progress.buildingWidget": "ウィジェットビルド中...",
199
196
  "progress.widgetBuilt": "ウィジェットビルド完了",
200
197
  "error.buildFail":
package/src/index.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { resolve, dirname, join } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { mkdir, writeFile } from "node:fs/promises";
7
+ import { mkdir, writeFile, readFile } from "node:fs/promises";
8
8
  import { execSync } from "node:child_process";
9
9
  import { collect_options } from "../tui/build/dev/javascript/tui/tui.mjs";
10
10
  import { collectOptions } from "./prompts.mjs";
@@ -14,7 +14,6 @@ import { scaffold } from "./scaffold.mjs";
14
14
  import { t, getTemplateComments, getLangLabel } from "./i18n.mjs";
15
15
  import { generateClaudeMdContent } from "./templates/claude_md.mjs";
16
16
  import { generateReadmeContent } from "./templates/readme_md.mjs";
17
- import { generateWidgetsReadmeContent } from "./templates/widgets_readme.mjs";
18
17
  import { generateLicenseContent } from "./licenses.mjs";
19
18
 
20
19
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -28,7 +27,9 @@ const DIM = "\x1b[2m";
28
27
  const YELLOW = "\x1b[33m";
29
28
  const MAGENTA = "\x1b[35m";
30
29
 
31
- const VERSION = "1.0.0";
30
+ const VERSION = JSON.parse(
31
+ await readFile(join(__dirname, "..", "package.json"), "utf-8"),
32
+ ).version;
32
33
 
33
34
  const HELP = `
34
35
  ${BOLD}create-mendix-widget-gleam${RESET} — Create Gleam + Mendix Pluggable Widget projects
@@ -66,9 +67,12 @@ const BANNER_LINES = [
66
67
 
67
68
  const header = '\n' + BANNER_LINES.map(([g, l]) =>
68
69
  `${CYAN}${BOLD}${g}${RESET}${MAGENTA}${l}${RESET}`
69
- ).join('\n') + `\n${DIM} create-mendix-widget-gleam v${VERSION}${RESET}\n`;
70
+ ).join('\n') + '\n';
70
71
 
71
72
  export async function main(args) {
73
+ // Ctrl+C 즉시 종료
74
+ process.on("SIGINT", () => process.exit(130));
75
+
72
76
  // Flag handling
73
77
  if (args.includes("--help") || args.includes("-h")) {
74
78
  console.log(HELP);
@@ -146,7 +150,6 @@ export async function main(args) {
146
150
  // Build template comments (i18n for template placeholders)
147
151
  const templateComments = {
148
152
  ...getTemplateComments(lang),
149
- widgets_readme: generateWidgetsReadmeContent(lang),
150
153
  };
151
154
 
152
155
  // Scaffold options
@@ -221,35 +224,19 @@ export async function main(args) {
221
224
  console.error(` ${CYAN}${pmConfig.install}${RESET}\n`);
222
225
  }
223
226
 
224
- // Install Playwright Chromium (only if not already installed)
227
+ // Run glendix/install
228
+ console.log(`\n${BOLD}${t(lang, "progress.glendixInstalling")}${RESET}\n`);
225
229
  try {
226
- const chromiumExists =
227
- execSync(
228
- `node -e "const fs=require('fs'),pw=require('playwright');process.stdout.write(String(fs.existsSync(pw.chromium.executablePath())))"`,
229
- { cwd: targetDir, encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"] },
230
- ).trim() === "true";
231
-
232
- if (!chromiumExists) {
233
- console.log(`\n${BOLD}${t(lang, "progress.playwrightInstalling")}${RESET}\n`);
234
- try {
235
- execSync("npx playwright install chromium", {
236
- cwd: targetDir,
237
- stdio: "inherit",
238
- });
239
- console.log(`\n${GREEN}✓${RESET} ${t(lang, "progress.playwrightInstalled")}`);
240
- } catch {
241
- console.error(
242
- `\n${YELLOW}${t(lang, "error.playwrightFail")}${RESET}`,
243
- );
244
- console.error(
245
- ` ${CYAN}npx playwright install chromium${RESET}\n`,
246
- );
247
- }
248
- } else {
249
- console.log(`${GREEN}✓${RESET} ${t(lang, "progress.playwrightExists")}`);
250
- }
230
+ execSync("gleam run -m glendix/install", {
231
+ cwd: targetDir,
232
+ stdio: "inherit",
233
+ });
234
+ console.log(`\n${GREEN}✓${RESET} ${t(lang, "progress.glendixInstalled")}`);
251
235
  } catch {
252
- // playwright package not installed — ignore
236
+ console.error(
237
+ `\n${YELLOW}${t(lang, "error.glendixInstallFail")}${RESET}`,
238
+ );
239
+ console.error(` ${CYAN}gleam run -m glendix/install${RESET}\n`);
253
240
  }
254
241
 
255
242
  // Production build
@@ -276,7 +263,7 @@ ${BOLD}${t(lang, "done.nextSteps")}${RESET}
276
263
  ${CYAN}cd ${names.kebabCase}${RESET}
277
264
  ${CYAN}gleam run -m glendix/dev${RESET} ${DIM}${t(lang, "done.devServer")}${RESET}
278
265
  ${CYAN}gleam run -m glendix/build${RESET} ${DIM}${t(lang, "done.prodBuild")}${RESET}
279
- ${CYAN}gleam run -m glendix/marketplace${RESET} ${DIM}${t(lang, "done.marketplace")}${RESET}
266
+ ${CYAN}gleam run -m mendraw/marketplace${RESET} ${DIM}${t(lang, "done.marketplace")}${RESET}
280
267
  `);
281
268
 
282
269
  // etch TUI 이벤트 서버의 stdin 리스너가 이벤트 루프를 유지하므로 명시적 종료
@@ -15,24 +15,25 @@ export function generateClaudeMdContent(lang, names, pm, pmConfig, organization)
15
15
 
16
16
  return `# ${names.pascalCase}
17
17
 
18
- A project for developing Mendix Pluggable Widgets with Gleam. Widgets are implemented using only Gleam + [glendix](https://hexdocs.pm/glendix/) bindings, without JSX.
18
+ A project for developing Mendix Pluggable Widgets with Gleam. Widgets are implemented using only Gleam + [glendix](https://hexdocs.pm/glendix/)/[mendraw](https://hexdocs.pm/mendraw/) bindings, without JSX.
19
19
 
20
20
  ## Commands
21
21
 
22
22
  \`\`\`bash
23
- gleam run -m glendix/install # Install dependencies (Gleam deps + npm + bindings.json code generation)
23
+ gleam run -m glendix/install # Install dependencies (Gleam deps + npm + TOML widget download + binding generation)
24
24
  gleam run -m glendix/build # Production build (.mpk output)
25
25
  gleam run -m glendix/dev # Dev server (HMR, port 3000)
26
26
  gleam run -m glendix/start # Link with Mendix test project
27
27
  gleam run -m glendix/release # Release build
28
28
  gleam run -m glendix/lint # Run ESLint
29
29
  gleam run -m glendix/lint_fix # ESLint auto-fix
30
- gleam run -m glendix/marketplace # Search/download Marketplace widgets
30
+ gleam run -m mendraw/marketplace # Search/download Marketplace widgets
31
+ gleam run -m mendraw/install # Generate widget bindings
31
32
  gleam test # Run tests
32
33
  gleam format # Format code
33
34
  \`\`\`
34
35
 
35
- If you add external React packages to bindings.json, install the npm package manually before running \`glendix/install\`.
36
+ If you add external React packages to \`gleam.toml [tools.glendix.bindings]\`, install the npm package manually before running \`glendix/install\`.
36
37
 
37
38
  ## Hard Rules
38
39
 
@@ -41,7 +42,7 @@ IMPORTANT: Breaking these rules will break the build or compromise the architect
41
42
  - **Do not write JSX/JS files directly.** All widget logic and UI must be written in Gleam
42
43
  - **Do not write FFI files (.mjs) in the widget project.** React/Mendix FFI is provided by the glendix package
43
44
  - **Do not manually manage bridge JS files (src/*.js).** glendix auto-generates/deletes them at build time
44
- - **React bindings use \`redraw\`/\`redraw_dom\` packages.** glendix v3.0 no longer provides React bindings directly
45
+ - **React bindings use \`redraw\`/\`redraw_dom\` packages.** glendix does not provide React bindings directly
45
46
  - The Gleam compilation output path (\`build/dev/javascript/{gleam.toml name}/\`) must match the Rollup input path
46
47
  - Mendix widget names allow only alphabetic characters (a-zA-Z)
47
48
 
@@ -53,7 +54,7 @@ IMPORTANT: Breaking these rules will break the build or compromise the architect
53
54
 
54
55
  ## Architecture
55
56
 
56
- Widget entry point signature: \`pub fn widget(props: JsProps) -> Element\` — identical to a React functional component. \`JsProps\` from \`glendix/mendix\`, \`Element\` from \`redraw\`.
57
+ Widget entry point signature: \`pub fn widget(props: JsProps) -> Element\` — identical to a React functional component. \`JsProps\` from \`mendraw/mendix\`, \`Element\` from \`redraw\`.
57
58
 
58
59
  - \`src/${names.snakeCase}.gleam\` — Main widget (called by Mendix runtime)
59
60
  - \`src/editor_config.gleam\` — Studio Pro property panel configuration
@@ -61,8 +62,7 @@ Widget entry point signature: \`pub fn widget(props: JsProps) -> Element\` — i
61
62
  - \`src/components/\` — Shared components
62
63
  - \`src/${names.pascalCase}.xml\` — Widget property definitions. Adding \`<property>\` triggers automatic type generation by the build tool
63
64
  - \`src/package.xml\` — Mendix package manifest
64
- - \`bindings.json\` — External React component binding configuration
65
- - \`widgets/\` — .mpk widget file bindings (used via \`glendix/widget\`)
65
+ - \`gleam.toml [tools.glendix.bindings]\` — External React component binding configuration
66
66
 
67
67
  ## Build Pipeline
68
68
 
@@ -93,6 +93,7 @@ src/*.gleam → gleam build → build/dev/javascript/**/*.mjs → Bridge JS (aut
93
93
  For detailed glendix API and Gleam syntax, see:
94
94
 
95
95
  - docs/glendix_guide.md — Complete React/Mendix bindings guide (elements, Hooks, events, Mendix types, practical patterns, troubleshooting)
96
+ - docs/mendraw_guide.md — mendraw usage guide (Marketplace download, classic widget support)
96
97
  - docs/gleam_language_tour.md — Gleam syntax reference (types, pattern matching, FFI, use keyword, etc.)
97
98
 
98
99
  ## Mendix Documentation Sources