create-middag-ui 0.26.1 → 0.26.2
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/cli.js +28 -2
- package/lib/detect.js +28 -0
- package/lib/scaffold.js +50 -2
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { join } from "node:path";
|
|
23
|
-
import { detectHost, detectMoodleComponent, HOSTS } from "./lib/detect.js";
|
|
23
|
+
import { detectHost, detectMoodleComponent, detectPhpHost, HOSTS } from "./lib/detect.js";
|
|
24
24
|
import { ask, confirm, select } from "./lib/prompts.js";
|
|
25
25
|
import { runTokenFlow } from "./lib/auth.js";
|
|
26
26
|
import {
|
|
@@ -92,6 +92,32 @@ if (hostKey) {
|
|
|
92
92
|
|
|
93
93
|
const host = HOSTS[hostKey];
|
|
94
94
|
|
|
95
|
+
// Custom host: probe for a PHP backend so the production build targets the
|
|
96
|
+
// PHP doc-root (public/build) with a base-href that keeps lazy chunks resolving.
|
|
97
|
+
let phpHost = null;
|
|
98
|
+
if (hostKey === "custom") {
|
|
99
|
+
const php = detectPhpHost(cwd);
|
|
100
|
+
if (php && php.docRoot) {
|
|
101
|
+
const fwLabel = php.framework ? ` (${php.framework})` : "";
|
|
102
|
+
if (nonInteractive) {
|
|
103
|
+
phpHost = php;
|
|
104
|
+
success(`PHP host detected${fwLabel} → build to public/build (--yes mode)`);
|
|
105
|
+
} else {
|
|
106
|
+
const docRel = php.docRoot.replace(cwd, ".");
|
|
107
|
+
const ok = await confirm(
|
|
108
|
+
`PHP backend detected${fwLabel}. Build assets into ${docRel}/build?`,
|
|
109
|
+
true,
|
|
110
|
+
);
|
|
111
|
+
if (ok) {
|
|
112
|
+
phpHost = php;
|
|
113
|
+
success("Production build will target the PHP doc-root (public/build)");
|
|
114
|
+
} else {
|
|
115
|
+
info("Keeping generic custom build (../dist)");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
95
121
|
// Moodle: detect frankenstyle component name (e.g. "local_middag", "mod_assign")
|
|
96
122
|
let moodleComponent = null;
|
|
97
123
|
if (hostKey === "moodle") {
|
|
@@ -249,7 +275,7 @@ if (isPro) {
|
|
|
249
275
|
|
|
250
276
|
// Host-specific production files (entry, vite config, theme CSS)
|
|
251
277
|
scaffoldHostEntry(targetDir, hostKey);
|
|
252
|
-
scaffoldHostViteConfig(targetDir, hostKey, host, withLicensing);
|
|
278
|
+
scaffoldHostViteConfig(targetDir, hostKey, host, withLicensing, phpHost);
|
|
253
279
|
scaffoldHostThemeCSS(targetDir, hostKey, host);
|
|
254
280
|
|
|
255
281
|
// Moodle-specific: AMD plugin + Moodle adapters (ajax, strings, notification)
|
package/lib/detect.js
CHANGED
|
@@ -113,3 +113,31 @@ export function detectHost(cwd) {
|
|
|
113
113
|
|
|
114
114
|
return null;
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Detect a PHP host and its doc-root, walking cwd + ancestors.
|
|
119
|
+
*
|
|
120
|
+
* Used to refine the 'custom' host: a PHP backend's production build must
|
|
121
|
+
* target the doc-root (public/build) with a proper base-href so lazy chunks
|
|
122
|
+
* resolve. PHP marker priority: composer.json (universal) → public/ doc-root;
|
|
123
|
+
* bin/console (Symfony) / artisan (Laravel) only refine the framework hint.
|
|
124
|
+
*
|
|
125
|
+
* @param {string} cwd - Directory the scaffold runs in (ui/ goes under here)
|
|
126
|
+
* @returns {{ lang: 'php', framework: string|null, appRoot: string, docRoot: string|null } | null}
|
|
127
|
+
*/
|
|
128
|
+
export function detectPhpHost(cwd) {
|
|
129
|
+
let dir = cwd;
|
|
130
|
+
for (let i = 0; i <= MAX_DEPTH; i++) {
|
|
131
|
+
if (existsSync(join(dir, "composer.json"))) {
|
|
132
|
+
const docRoot = existsSync(join(dir, "public")) ? join(dir, "public") : null;
|
|
133
|
+
let framework = null;
|
|
134
|
+
if (existsSync(join(dir, "artisan"))) framework = "laravel";
|
|
135
|
+
else if (existsSync(join(dir, "bin", "console"))) framework = "symfony";
|
|
136
|
+
return { lang: "php", framework, appRoot: dir, docRoot };
|
|
137
|
+
}
|
|
138
|
+
const parent = dirname(dir);
|
|
139
|
+
if (parent === dir) break;
|
|
140
|
+
dir = parent;
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
package/lib/scaffold.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
11
|
-
import { basename, dirname, join } from "node:path";
|
|
11
|
+
import { basename, dirname, join, relative } from "node:path";
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { error, success, warn } from "./ui.js";
|
|
14
14
|
|
|
@@ -1435,7 +1435,7 @@ ${postMountCode}
|
|
|
1435
1435
|
* @param {object} host - HOSTS[hostKey] object
|
|
1436
1436
|
* @param {boolean} withLicensing - Whether to emit @middag-io/licensing delivery manifest plugin
|
|
1437
1437
|
*/
|
|
1438
|
-
export function scaffoldHostViteConfig(targetDir, hostKey, host, withLicensing = false) {
|
|
1438
|
+
export function scaffoldHostViteConfig(targetDir, hostKey, host, withLicensing = false, phpHost = null) {
|
|
1439
1439
|
const filePath = join(targetDir, `vite.config.${hostKey}.ts`);
|
|
1440
1440
|
const label = `vite.config.${hostKey}.ts`;
|
|
1441
1441
|
if (skipIfExists(filePath, label)) return;
|
|
@@ -1524,10 +1524,58 @@ export default defineConfig({
|
|
|
1524
1524
|
},
|
|
1525
1525
|
},
|
|
1526
1526
|
});
|
|
1527
|
+
`;
|
|
1528
|
+
writeFile(filePath, content, label);
|
|
1529
|
+
return;
|
|
1530
|
+
} else if (hostKey === "custom" && phpHost && phpHost.docRoot) {
|
|
1531
|
+
// PHP host: app-entry build into the doc-root. base:"/build/" scopes
|
|
1532
|
+
// lazy-chunk import URLs (heavy blocks: ChartPanel, FormPanel, DateField)
|
|
1533
|
+
// to where PHP serves /public/build — without it dynamic imports 404.
|
|
1534
|
+
// entry-custom.tsx self-executes (registerDefaults + createInertiaApp), so
|
|
1535
|
+
// this is an APP build (rollupOptions.input), NOT a library build.
|
|
1536
|
+
const docRootName = basename(phpHost.docRoot);
|
|
1537
|
+
const rel = relative(targetDir, join(phpHost.docRoot, "build")) || "../public/build";
|
|
1538
|
+
const outDirExpr = `resolve(__dirname, ${JSON.stringify(rel)})`;
|
|
1539
|
+
const content = `/**
|
|
1540
|
+
* Vite build config for the custom host (PHP) — production build target.
|
|
1541
|
+
*
|
|
1542
|
+
* Builds src/entry-custom.tsx as an APP entry (self-executes: registerDefaults
|
|
1543
|
+
* + createInertiaApp) so the bundle runs when the PHP shell loads
|
|
1544
|
+
* \`<script type="module" src="/build/app.js">\`. base:"/build/" scopes lazy
|
|
1545
|
+
* chunk import URLs to where the assets are served (${docRootName}/build).
|
|
1546
|
+
*
|
|
1547
|
+
* The dev server (\`npm run dev\`) uses vite.config.ts instead.
|
|
1548
|
+
*/
|
|
1549
|
+
import { defineConfig } from "vite";
|
|
1550
|
+
import react from "@vitejs/plugin-react";
|
|
1551
|
+
${licensingImport.trimEnd()}
|
|
1552
|
+
import { resolve } from "path";
|
|
1553
|
+
|
|
1554
|
+
export default defineConfig({
|
|
1555
|
+
plugins: [react()${licensingPluginEntry}],
|
|
1556
|
+
define: { "process.env.NODE_ENV": JSON.stringify("production") },
|
|
1557
|
+
resolve: { alias: { "@/": resolve(__dirname, "src") + "/" } },
|
|
1558
|
+
base: "/build/",
|
|
1559
|
+
build: {
|
|
1560
|
+
outDir: ${outDirExpr},
|
|
1561
|
+
emptyOutDir: true,
|
|
1562
|
+
cssCodeSplit: false,
|
|
1563
|
+
rollupOptions: {
|
|
1564
|
+
input: resolve(__dirname, "src/entry-custom.tsx"),
|
|
1565
|
+
output: {
|
|
1566
|
+
entryFileNames: "app.js",
|
|
1567
|
+
chunkFileNames: "[name]-[hash].js",
|
|
1568
|
+
assetFileNames: (assetInfo) =>
|
|
1569
|
+
assetInfo.name?.endsWith(".css") ? "style.css" : "[name]-[hash][extname]",
|
|
1570
|
+
},
|
|
1571
|
+
},
|
|
1572
|
+
},
|
|
1573
|
+
});
|
|
1527
1574
|
`;
|
|
1528
1575
|
writeFile(filePath, content, label);
|
|
1529
1576
|
return;
|
|
1530
1577
|
} else {
|
|
1578
|
+
// Generic custom (non-PHP) or PHP without a public/ doc-root — lib mode.
|
|
1531
1579
|
outDir = `resolve(__dirname, "../dist")`;
|
|
1532
1580
|
formats = `["es"]`;
|
|
1533
1581
|
libName = `"MiddagUI"`;
|