create-middag-ui 0.11.0 → 0.13.0

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
@@ -86,7 +86,7 @@ npx @middag-io/react upgrade # Check for updates
86
86
 
87
87
  ## Documentation
88
88
 
89
- - **[Live Demo](https://middag-react-mock.pages.dev)** — 24 screens showing all block types
89
+ - **[Live Demo](https://ui-demo.middag.io)** — 24 screens showing all block types
90
90
  - **[Full Documentation](https://ui-docs.middag.io)** — Getting started, host guides, API reference
91
91
  - **[GitHub](https://github.com/middag-io/middag-react)** — Source code and issues
92
92
 
package/cli.js CHANGED
@@ -20,29 +20,35 @@
20
20
  */
21
21
 
22
22
  import { join } from "node:path";
23
- import { detectHost, HOSTS } from "./lib/detect.js";
24
- import { ask, select, confirm } from "./lib/prompts.js";
23
+ import { detectHost, detectMoodleComponent, HOSTS } from "./lib/detect.js";
24
+ import { ask, confirm, select } from "./lib/prompts.js";
25
25
  import { runTokenFlow } from "./lib/auth.js";
26
26
  import {
27
27
  createTargetDir,
28
- scaffoldPackageJson,
29
- scaffoldTsconfig,
30
- scaffoldViteConfig,
31
- scaffoldEslintConfig,
32
- scaffoldPrettierConfig,
33
- scaffoldIndexHtml,
28
+ scaffoldDemoDirectPage,
34
29
  scaffoldDemoFiles,
35
- scaffoldPageExamples,
36
- scaffoldProApp,
37
- scaffoldFreeApp,
38
- scaffoldFreeAdapters,
39
30
  scaffoldDevShell,
31
+ scaffoldEslintConfig,
32
+ scaffoldFreeAdapters,
33
+ scaffoldFreeApp,
34
+ scaffoldFreeRegister,
40
35
  scaffoldHostEntry,
41
- scaffoldHostViteConfig,
42
36
  scaffoldHostThemeCSS,
37
+ scaffoldHostViteConfig,
38
+ scaffoldIndexHtml,
39
+ scaffoldMoodleAdapters,
40
+ scaffoldMoodlePlugin,
41
+ scaffoldMoodleTailwind,
42
+ scaffoldPackageJson,
43
+ scaffoldPageExamples,
44
+ scaffoldPageResolver,
45
+ scaffoldPrettierConfig,
46
+ scaffoldRouteHelper,
47
+ scaffoldTsconfig,
48
+ scaffoldViteConfig,
43
49
  } from "./lib/scaffold.js";
44
50
  import { runNpmInstall } from "./lib/install.js";
45
- import { log, success, heading, blank, info } from "./lib/ui.js";
51
+ import { blank, heading, info, log, success } from "./lib/ui.js";
46
52
 
47
53
  const TOTAL_STEPS = 10;
48
54
  const cwd = process.cwd();
@@ -70,6 +76,20 @@ if (hostKey) {
70
76
 
71
77
  const host = HOSTS[hostKey];
72
78
 
79
+ // Moodle: detect frankenstyle component name (e.g. "local_middag", "mod_assign")
80
+ let moodleComponent = null;
81
+ if (hostKey === "moodle") {
82
+ moodleComponent = detectMoodleComponent(cwd);
83
+ if (moodleComponent) {
84
+ success(`Moodle component: ${ moodleComponent }`);
85
+ } else {
86
+ info("Could not detect Moodle component from version.php");
87
+ const answer = await ask(" Frankenstyle component (e.g. local_yourplugin): ");
88
+ moodleComponent = answer || "local_myplugin";
89
+ success(`Component: ${ moodleComponent }`);
90
+ }
91
+ }
92
+
73
93
  // ── Step 2: Ask directory ────────────────────────────────────────────────
74
94
 
75
95
  heading(2, TOTAL_STEPS, "Target directory");
@@ -150,10 +170,35 @@ heading(8, TOTAL_STEPS, `Creating ${isPro ? "PRO" : "FREE"} UI module`);
150
170
 
151
171
  scaffoldPageExamples(targetDir);
152
172
 
173
+ // Shared files (both PRO and FREE)
174
+ scaffoldPageResolver(targetDir);
175
+ scaffoldDemoDirectPage(targetDir);
176
+ // Convert frankenstyle "local_middag" → Moodle path "local/middag"
177
+ const moodlePath = moodleComponent ? moodleComponent.replace("_", "/") : null;
178
+ scaffoldRouteHelper(targetDir, hostKey, moodlePath);
179
+
153
180
  if (isPro) {
154
- scaffoldProApp(targetDir);
155
- success("PRO: using MockProductShell from @middag-io/react/mock");
181
+ try {
182
+ const pro = await import("./lib/scaffoldPRO.js");
183
+ pro.scaffoldProRegister(targetDir);
184
+ pro.scaffoldProApp(targetDir);
185
+ pro.scaffoldMockNavigation(targetDir);
186
+ pro.scaffoldMockData(targetDir);
187
+ pro.scaffoldMockEntities(targetDir);
188
+ pro.scaffoldMockPageContracts(targetDir);
189
+ pro.scaffoldMockRoutes(targetDir);
190
+ success("PRO: using MockProductShell from @middag-io/react/mock");
191
+ } catch {
192
+ // npm version — PRO file excluded, fall back to FREE
193
+ info("PRO scaffold not available — using FREE path");
194
+ scaffoldFreeRegister(targetDir);
195
+ scaffoldFreeAdapters(targetDir);
196
+ scaffoldDevShell(targetDir);
197
+ scaffoldFreeApp(targetDir);
198
+ success("FREE: generated DevShell + local Inertia adapters");
199
+ }
156
200
  } else {
201
+ scaffoldFreeRegister(targetDir);
157
202
  scaffoldFreeAdapters(targetDir);
158
203
  scaffoldDevShell(targetDir);
159
204
  scaffoldFreeApp(targetDir);
@@ -165,6 +210,14 @@ scaffoldHostEntry(targetDir, hostKey);
165
210
  scaffoldHostViteConfig(targetDir, hostKey, host);
166
211
  scaffoldHostThemeCSS(targetDir, hostKey, host);
167
212
 
213
+ // Moodle-specific: AMD plugin + Moodle adapters (ajax, strings, notification)
214
+ if (hostKey === "moodle" && moodleComponent) {
215
+ scaffoldMoodlePlugin(targetDir, moodleComponent);
216
+ scaffoldMoodleTailwind(targetDir);
217
+ scaffoldMoodleAdapters(targetDir, moodleComponent);
218
+ success(`Moodle: AMD plugin + Tailwind + adapters for ${ moodleComponent }`);
219
+ }
220
+
168
221
  // ── Step 9: npm install ──────────────────────────────────────────────────
169
222
 
170
223
  heading(9, TOTAL_STEPS, "Installing dependencies");
@@ -211,6 +264,16 @@ console.log(` Production build for ${host.name}:`);
211
264
  console.log(` npm run ${hostBuildScript} \u2192 build for ${host.name}`);
212
265
  console.log(` npm run ${hostWatchScript} \u2192 rebuild on change`);
213
266
 
267
+ if (hostKey === "moodle" && moodleComponent) {
268
+ blank();
269
+ console.log(` Moodle integration (${ moodleComponent }):`);
270
+ console.log(" AMD chunks \u2192 amd/src/ + amd/build/");
271
+ console.log(" CSS \u2192 styles/middag-app.css");
272
+ console.log(" AMD plugin: plugins/vite-plugin-moodle-amd.ts");
273
+ console.log(" Moodle adapters: src/lib/moodle/ (ajax, strings, notification)");
274
+ console.log(" Tailwind entry: src/tailwind.css");
275
+ }
276
+
214
277
  blank();
215
278
  console.log(` Integrate with your ${host.name} plugin:`);
216
279
  console.log(" 1. Import { ContractPage } from '@middag-io/react'");
package/lib/detect.js CHANGED
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { existsSync, readFileSync } from "node:fs";
13
- import { join, dirname } from "node:path";
13
+ import { dirname, join } from "node:path";
14
14
 
15
15
  /** Max ancestor levels to walk when searching for platform markers. */
16
16
  const MAX_DEPTH = 5;
@@ -54,6 +54,26 @@ function isMoodleRootVersion(filePath) {
54
54
  }
55
55
  }
56
56
 
57
+ /**
58
+ * Extract Moodle plugin frankenstyle component name from version.php.
59
+ * Returns e.g. "local_middag", "mod_assign", or null if not found.
60
+ *
61
+ * @param {string} cwd - Directory to check (should be the Moodle plugin root)
62
+ * @returns {string|null} Frankenstyle component name
63
+ */
64
+ export function detectMoodleComponent(cwd) {
65
+ const versionFile = join(cwd, "version.php");
66
+ if (!existsSync(versionFile)) return null;
67
+
68
+ try {
69
+ const content = readFileSync(versionFile, "utf-8");
70
+ const match = content.match(/\$plugin\s*->\s*component\s*=\s*['"]([^'"]+)['"]/);
71
+ return match ? match[1] : null;
72
+ } catch {
73
+ return null;
74
+ }
75
+ }
76
+
57
77
  /**
58
78
  * Detect host platform by checking cwd and ancestor directories.
59
79
  *