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 +1 -1
- package/cli.js +79 -16
- package/lib/detect.js +21 -1
- package/lib/scaffold.js +319 -58
- package/lib/scaffoldPRO.js +228 -0
- package/lib/templates/pro/app.tsx +50 -0
- package/lib/templates/pro/main.tsx +21 -0
- package/lib/templates/pro/mock-data.ts +28 -0
- package/lib/templates/pro/mock-entities.ts +13 -0
- package/lib/templates/pro/mock-navigation.ts +59 -0
- package/lib/templates/pro/mock-routes.tsx +90 -0
- package/lib/templates/pro/register-pro.ts +75 -0
- package/lib/templates/shared/demo-page.tsx +45 -0
- package/lib/templates/shared/moodle-ajax.ts +33 -0
- package/lib/templates/shared/moodle-notification.ts +23 -0
- package/lib/templates/shared/moodle-strings.ts +62 -0
- package/lib/templates/shared/page-resolver.tsx +51 -0
- package/lib/templates/shared/register-free.ts +64 -0
- package/lib/templates/shared/route-helper-custom.ts +44 -0
- package/lib/templates/shared/route-helper-moodle.ts +66 -0
- package/lib/templates/shared/route-helper-wp.ts +58 -0
- package/lib/templates/shared/tailwind.css +12 -0
- package/lib/templates/shared/vite-plugin-moodle-amd.ts +122 -0
- package/package.json +1 -1
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://
|
|
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,
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
155
|
-
|
|
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 {
|
|
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
|
*
|