@mozole/cli 2.0.0-b → 2.1.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/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +147 -23
- package/dist/cli.js.map +1 -1
- package/dist/commands/add.d.ts +7 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +87 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/adopt.d.ts +2 -0
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +243 -45
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/assets.d.ts +28 -0
- package/dist/commands/assets.d.ts.map +1 -0
- package/dist/commands/assets.js +176 -0
- package/dist/commands/assets.js.map +1 -0
- package/dist/commands/backend.d.ts +5 -0
- package/dist/commands/backend.d.ts.map +1 -0
- package/dist/commands/backend.js +68 -0
- package/dist/commands/backend.js.map +1 -0
- package/dist/commands/new.d.ts +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +13 -5
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/prototype.d.ts.map +1 -1
- package/dist/commands/prototype.js +68 -20
- package/dist/commands/prototype.js.map +1 -1
- package/dist/commands/release.d.ts +10 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +181 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/commands/ui.d.ts +12 -1
- package/dist/commands/ui.d.ts.map +1 -1
- package/dist/commands/ui.js +182 -68
- package/dist/commands/ui.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +37 -5
- package/dist/commands/verify.js.map +1 -1
- package/dist/scaffold/agents.d.ts.map +1 -1
- package/dist/scaffold/agents.js +40 -6
- package/dist/scaffold/agents.js.map +1 -1
- package/dist/scaffold/backend.d.ts +1 -1
- package/dist/scaffold/backend.d.ts.map +1 -1
- package/dist/scaffold/backend.js +63 -31
- package/dist/scaffold/backend.js.map +1 -1
- package/dist/scaffold/components.d.ts +8 -0
- package/dist/scaffold/components.d.ts.map +1 -0
- package/dist/scaffold/components.js +305 -0
- package/dist/scaffold/components.js.map +1 -0
- package/dist/scaffold/design.d.ts.map +1 -1
- package/dist/scaffold/design.js +47 -25
- package/dist/scaffold/design.js.map +1 -1
- package/dist/scaffold/flagship.d.ts +5 -0
- package/dist/scaffold/flagship.d.ts.map +1 -1
- package/dist/scaffold/flagship.js +161 -102
- package/dist/scaffold/flagship.js.map +1 -1
- package/dist/scaffold/index.d.ts +1 -1
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +22 -7
- package/dist/scaffold/index.js.map +1 -1
- package/dist/scaffold/library.d.ts +3 -0
- package/dist/scaffold/library.d.ts.map +1 -0
- package/dist/scaffold/library.js +98 -0
- package/dist/scaffold/library.js.map +1 -0
- package/dist/scaffold/phases.d.ts.map +1 -1
- package/dist/scaffold/phases.js +19 -14
- package/dist/scaffold/phases.js.map +1 -1
- package/dist/scaffold/repomap.d.ts +3 -3
- package/dist/scaffold/repomap.d.ts.map +1 -1
- package/dist/scaffold/repomap.js +22 -10
- package/dist/scaffold/repomap.js.map +1 -1
- package/dist/scaffold/standard.d.ts.map +1 -1
- package/dist/scaffold/standard.js +3 -2
- package/dist/scaffold/standard.js.map +1 -1
- package/dist/scaffold/tokens.js +4 -4
- package/dist/scaffold/tools-guide.d.ts +3 -0
- package/dist/scaffold/tools-guide.d.ts.map +1 -0
- package/dist/scaffold/tools-guide.js +117 -0
- package/dist/scaffold/tools-guide.js.map +1 -0
- package/dist/scaffold/workflow.d.ts +5 -0
- package/dist/scaffold/workflow.d.ts.map +1 -0
- package/dist/scaffold/workflow.js +221 -0
- package/dist/scaffold/workflow.js.map +1 -0
- package/dist/ui/CockpitApp.d.ts +13 -0
- package/dist/ui/CockpitApp.d.ts.map +1 -0
- package/dist/ui/CockpitApp.js +612 -0
- package/dist/ui/CockpitApp.js.map +1 -0
- package/dist/ui/ToolsPanel.d.ts +6 -0
- package/dist/ui/ToolsPanel.d.ts.map +1 -0
- package/dist/ui/ToolsPanel.js +128 -0
- package/dist/ui/ToolsPanel.js.map +1 -0
- package/dist/utils/fs.d.ts +7 -0
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +169 -3
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/project-files.d.ts +4 -0
- package/dist/utils/project-files.d.ts.map +1 -0
- package/dist/utils/project-files.js +49 -0
- package/dist/utils/project-files.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +32 -4
package/dist/commands/adopt.js
CHANGED
|
@@ -1,52 +1,250 @@
|
|
|
1
|
+
import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
1
3
|
import path from "node:path";
|
|
2
4
|
import pc from "picocolors";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { generateFlagshipPackageJson } from "../scaffold/flagship.js";
|
|
6
|
+
import { scaffoldNewProject } from "../scaffold/index.js";
|
|
7
|
+
import { generateStandardPackageJson } from "../scaffold/standard.js";
|
|
8
|
+
import { linkWorkflowPolicies } from "../scaffold/workflow.js";
|
|
9
|
+
import { atomicWrite, exists, isDirectory, writeFiles } from "../utils/fs.js";
|
|
10
|
+
import { enableBackend } from "./backend.js";
|
|
9
11
|
export async function adoptProject(options = {}) {
|
|
10
|
-
const targetDir =
|
|
11
|
-
|
|
12
|
-
if (!(await exists(targetDir))) {
|
|
12
|
+
const targetDir = path.resolve(options.targetDir ?? process.cwd());
|
|
13
|
+
if (!(await isDirectory(targetDir)))
|
|
13
14
|
throw new Error(`Directory not found: ${targetDir}`);
|
|
15
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
16
|
+
const hasPackage = await exists(pkgPath);
|
|
17
|
+
const pkg = hasPackage ? JSON.parse(await readFile(pkgPath, "utf8")) : {};
|
|
18
|
+
const dependencies = { ...pkg.devDependencies, ...pkg.dependencies };
|
|
19
|
+
const foreignFramework = dependencies.vue ||
|
|
20
|
+
dependencies.svelte ||
|
|
21
|
+
dependencies["@angular/core"] ||
|
|
22
|
+
dependencies.angular ||
|
|
23
|
+
dependencies.next ||
|
|
24
|
+
dependencies.nuxt;
|
|
25
|
+
if (hasPackage && foreignFramework) {
|
|
26
|
+
throw new Error("Adopt supports Vite + React projects. Migrate this project's framework to Vite + React before adopting; no files were changed.");
|
|
14
27
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
if (!hasPackage) {
|
|
29
|
+
const contents = await readdir(targetDir);
|
|
30
|
+
if (contents.some((file) => !file.startsWith(".") && !/^(README|LICENSE|AGENTS|CLAUDE)(\.|$)/i.test(file))) {
|
|
31
|
+
throw new Error("A nonempty project needs a Vite + React package.json before adoption.");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (options.backend && !["none", "php", "node"].includes(options.backend))
|
|
35
|
+
throw new Error("Invalid backend runtime.");
|
|
36
|
+
const flagship = options.flagship ?? Boolean(dependencies.wouter);
|
|
37
|
+
if (flagship &&
|
|
38
|
+
(dependencies["@react-router/dev"] ||
|
|
39
|
+
dependencies["react-router"] ||
|
|
40
|
+
dependencies["react-router-dom"])) {
|
|
41
|
+
throw new Error("Convert React Router framework routes to Wouter before adopting as Flagship.");
|
|
42
|
+
}
|
|
43
|
+
const name = options.projectName ?? pkg.name ?? path.basename(targetDir);
|
|
44
|
+
const metadataPath = path.join(targetDir, ".mozole/project.json");
|
|
45
|
+
const metadata = (await exists(metadataPath))
|
|
46
|
+
? JSON.parse(await readFile(metadataPath, "utf8"))
|
|
47
|
+
: {};
|
|
48
|
+
const backend = metadata.backend ??
|
|
49
|
+
((await exists(path.join(targetDir, "server/index.mjs")))
|
|
50
|
+
? "node"
|
|
51
|
+
: (await exists(path.join(targetDir, "api/index.php")))
|
|
52
|
+
? "php"
|
|
53
|
+
: "none");
|
|
54
|
+
if (options.backend &&
|
|
55
|
+
options.backend !== "none" &&
|
|
56
|
+
backend !== "none" &&
|
|
57
|
+
options.backend !== backend) {
|
|
58
|
+
throw new Error(`Existing ${backend} backend must be migrated explicitly before switching runtime.`);
|
|
59
|
+
}
|
|
60
|
+
const framework = Boolean(dependencies["@react-router/dev"]);
|
|
61
|
+
if (hasPackage &&
|
|
62
|
+
dependencies.tailwindcss &&
|
|
63
|
+
!/^(?:\^|~)?4(?:\.|$)/.test(dependencies.tailwindcss)) {
|
|
64
|
+
throw new Error("Adopt requires Tailwind v4. Migrate the existing Tailwind configuration first; no files were changed.");
|
|
65
|
+
}
|
|
66
|
+
const expected = JSON.parse(flagship
|
|
67
|
+
? generateFlagshipPackageJson("adopted-project")
|
|
68
|
+
: generateStandardPackageJson("adopted-project"));
|
|
69
|
+
// Existing Vite SPAs retain their entry and routing composition.
|
|
70
|
+
if (hasPackage && !flagship && !framework) {
|
|
71
|
+
const { "@react-router/node": _node, "@react-router/serve": _serve, isbot: _bot, ...filteredDeps } = expected.dependencies;
|
|
72
|
+
expected.dependencies = filteredDeps;
|
|
73
|
+
const { "@react-router/dev": _dev, ...filteredDevDeps } = expected.devDependencies;
|
|
74
|
+
expected.devDependencies = filteredDevDeps;
|
|
75
|
+
expected.devDependencies["@vitejs/plugin-react"] = "^4.3.4";
|
|
76
|
+
expected.scripts = {
|
|
77
|
+
dev: "vite",
|
|
78
|
+
build: "tsc --noEmit && vite build",
|
|
79
|
+
preview: "vite preview",
|
|
80
|
+
typecheck: "tsc --noEmit",
|
|
81
|
+
verify: "mozole verify",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const report = [];
|
|
85
|
+
if (hasPackage &&
|
|
86
|
+
!flagship &&
|
|
87
|
+
!framework &&
|
|
88
|
+
!dependencies["react-router"] &&
|
|
89
|
+
!dependencies["react-router-dom"]) {
|
|
90
|
+
report.push("React Router was added. Mount a BrowserRouter or RouterProvider when composing route-aware layouts into existing pages.");
|
|
91
|
+
}
|
|
92
|
+
for (const section of ["dependencies", "devDependencies"]) {
|
|
93
|
+
for (const [dependency, version] of Object.entries(expected[section])) {
|
|
94
|
+
if (dependencies[dependency]) {
|
|
95
|
+
if (dependencies[dependency] !== version)
|
|
96
|
+
report.push(`Review dependency ${dependency}: preserved ${dependencies[dependency]}, scaffold baseline ${version}.`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
pkg[section] = { ...pkg[section], [dependency]: version };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
pkg.name ??= name;
|
|
104
|
+
pkg.type ??= "module";
|
|
105
|
+
pkg.private ??= true;
|
|
106
|
+
pkg.scripts = { ...expected.scripts, ...pkg.scripts };
|
|
107
|
+
const temp = await mkdtemp(path.join(os.tmpdir(), "mozole-adopt-"));
|
|
108
|
+
const written = [];
|
|
109
|
+
try {
|
|
110
|
+
await scaffoldNewProject({
|
|
111
|
+
targetDir: temp,
|
|
112
|
+
name: "adopted-project",
|
|
113
|
+
flagship,
|
|
114
|
+
initGit: false,
|
|
115
|
+
});
|
|
116
|
+
async function collect(dir, prefix = "") {
|
|
117
|
+
const files = {};
|
|
118
|
+
for (const item of await readdir(dir, { withFileTypes: true })) {
|
|
119
|
+
const relative = prefix ? `${prefix}/${item.name}` : item.name;
|
|
120
|
+
if (item.isDirectory())
|
|
121
|
+
Object.assign(files, await collect(path.join(dir, item.name), relative));
|
|
122
|
+
else
|
|
123
|
+
files[relative] = await readFile(path.join(dir, item.name), "utf8");
|
|
124
|
+
}
|
|
125
|
+
return files;
|
|
126
|
+
}
|
|
127
|
+
const files = await collect(temp);
|
|
128
|
+
if (hasPackage) {
|
|
129
|
+
files["docs/repomap/routes.md"] =
|
|
130
|
+
"# Existing routes\n\nApplication routes are preserved. Index the existing route components here during adoption review.\n";
|
|
131
|
+
files["docs/repomap/architecture.md"] = files["docs/repomap/architecture.md"].replace("None (static frontend)", backend === "none" ? "None (static frontend)" : `${backend} (existing project backend)`);
|
|
132
|
+
if (!flagship && !framework)
|
|
133
|
+
files["docs/repomap/architecture.md"] = files["docs/repomap/architecture.md"].replace("React Router 7 (Framework Mode with Static Pre-rendering / SSG)", "Existing Vite React SPA; React Router library available for composition");
|
|
134
|
+
}
|
|
135
|
+
const { "package.json": _packageJson, ".mozole/project.json": _projectJson, ...filteredFiles } = files;
|
|
136
|
+
for (const [file, content] of Object.entries(filteredFiles)) {
|
|
137
|
+
if (file === "docs/design/design.md" && (await exists(path.join(targetDir, "design.md"))))
|
|
138
|
+
continue;
|
|
139
|
+
if (hasPackage &&
|
|
140
|
+
(file === "index.html" ||
|
|
141
|
+
file === "react-router.config.ts" ||
|
|
142
|
+
file === "src/main.tsx" ||
|
|
143
|
+
file === "src/App.tsx" ||
|
|
144
|
+
file === "src/root.tsx" ||
|
|
145
|
+
file === "src/routes.ts" ||
|
|
146
|
+
file.startsWith("src/routes/")))
|
|
147
|
+
continue;
|
|
148
|
+
if (hasPackage && file === "vite.config.ts")
|
|
149
|
+
continue;
|
|
150
|
+
if (await exists(path.join(targetDir, file))) {
|
|
151
|
+
if (file.startsWith("src/components/") ||
|
|
152
|
+
file.startsWith("src/behaviors/") ||
|
|
153
|
+
file === "src/library/index.ts") {
|
|
154
|
+
await writeFiles(targetDir, { [`.mozole/adoption-proposals/${file}`]: content });
|
|
155
|
+
}
|
|
156
|
+
if (file.endsWith("index.ts") ||
|
|
157
|
+
file === "tsconfig.json" ||
|
|
158
|
+
file === "src/styles/tokens.css")
|
|
159
|
+
report.push(`Preserved ${file}; review the project library exports and token/tooling integration.`);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const value = file.endsWith(".md") || file.endsWith(".mdc")
|
|
163
|
+
? content.replaceAll("adopted-project", name)
|
|
164
|
+
: content;
|
|
165
|
+
written.push(...(await writeFiles(targetDir, { [file]: value })));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await rm(temp, { recursive: true, force: true });
|
|
170
|
+
}
|
|
171
|
+
await linkWorkflowPolicies(targetDir);
|
|
172
|
+
if (hasPackage) {
|
|
173
|
+
let entry;
|
|
174
|
+
for (const candidate of framework
|
|
175
|
+
? ["src/root.tsx"]
|
|
176
|
+
: ["src/main.tsx", "src/main.jsx", "src/index.tsx", "src/index.jsx"]) {
|
|
177
|
+
if (await exists(path.join(targetDir, candidate))) {
|
|
178
|
+
entry = candidate;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (entry) {
|
|
183
|
+
const file = path.join(targetDir, entry);
|
|
184
|
+
const content = await readFile(file, "utf8");
|
|
185
|
+
if (!content.includes("./styles/tokens.css"))
|
|
186
|
+
await atomicWrite(file, `import "./styles/tokens.css";\n${content}`);
|
|
187
|
+
}
|
|
188
|
+
else
|
|
189
|
+
report.push("Import src/styles/tokens.css from your custom application entry.");
|
|
190
|
+
let config;
|
|
191
|
+
for (const candidate of [
|
|
192
|
+
"vite.config.ts",
|
|
193
|
+
"vite.config.mts",
|
|
194
|
+
"vite.config.js",
|
|
195
|
+
"vite.config.mjs",
|
|
196
|
+
]) {
|
|
197
|
+
if (await exists(path.join(targetDir, candidate))) {
|
|
198
|
+
config = candidate;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const configText = config ? await readFile(path.join(targetDir, config), "utf8") : "";
|
|
203
|
+
if (!configText.includes("@tailwindcss/vite")) {
|
|
204
|
+
const wrapper = "mozole.adopt.vite.config.mjs";
|
|
205
|
+
if (!(await exists(path.join(targetDir, wrapper)))) {
|
|
206
|
+
await writeFiles(targetDir, {
|
|
207
|
+
[wrapper]: `${config ? `import base from "./${config}";` : framework ? 'import { reactRouter } from "@react-router/dev/vite";\nconst base = { plugins: [reactRouter()] };' : 'import react from "@vitejs/plugin-react";\nconst base = { plugins: [react()] };'}
|
|
208
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
209
|
+
import { defineConfig, mergeConfig } from "vite";
|
|
210
|
+
|
|
211
|
+
export default defineConfig(async (env) => mergeConfig(
|
|
212
|
+
await (typeof base === "function" ? base(env) : base),
|
|
213
|
+
{ plugins: [tailwindcss()], server: { proxy: { "/api": "http://127.0.0.1:3001" } } },
|
|
214
|
+
));
|
|
215
|
+
`,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
for (const script of ["dev", "build", "preview"]) {
|
|
219
|
+
if (typeof pkg.scripts[script] === "string" &&
|
|
220
|
+
!pkg.scripts[script].includes("--config") &&
|
|
221
|
+
!/(?:^|\s)-c(?:\s|$)/.test(pkg.scripts[script]) &&
|
|
222
|
+
/\b(vite|react-router)\b/.test(pkg.scripts[script])) {
|
|
223
|
+
pkg.scripts[script] += ` --config ${wrapper}`;
|
|
224
|
+
}
|
|
225
|
+
else
|
|
226
|
+
report.push(`Review ${script} script: retained its existing config selection.`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
report.push("Existing pages and routing were preserved. Compose the local UI/layout modules into those pages; remove legacy duplicate styles after reviewing their appearance.");
|
|
230
|
+
if (flagship)
|
|
231
|
+
report.push("Mount useSmoothScroll and Reveal where desired; generated behavior and motion remain opt-in in existing pages.");
|
|
232
|
+
}
|
|
233
|
+
await atomicWrite(pkgPath, JSON.stringify(pkg, null, 2));
|
|
234
|
+
await atomicWrite(metadataPath, JSON.stringify({
|
|
235
|
+
...metadata,
|
|
236
|
+
version: 1,
|
|
237
|
+
name,
|
|
238
|
+
profile: flagship ? "flagship" : "standard",
|
|
239
|
+
backend,
|
|
240
|
+
library: "src/library/index.ts",
|
|
241
|
+
adoption: report.length ? "review-required" : "complete",
|
|
242
|
+
}, null, 2));
|
|
243
|
+
if (options.backend && options.backend !== "none" && backend === "none") {
|
|
244
|
+
await enableBackend({ targetDir, runtime: options.backend });
|
|
245
|
+
}
|
|
246
|
+
await atomicWrite(path.join(targetDir, ".mozole/adoption-report.md"), `# Adoption report\n\nAdded ${written.length} files. Existing application files were preserved.\n\n${report.length ? report.map((item) => `- ${item}`).join("\n") : "No manual integration items detected."}\n\nInstall dependencies at the prototype root (if applicable), otherwise here. Run mozole verify after completing the review.\n`);
|
|
247
|
+
console.log(pc.green(`✓ Adopted ${name}; added ${written.length} files.`));
|
|
248
|
+
console.log(`Review ${path.join(targetDir, ".mozole/adoption-report.md")} before claiming full conformance.`);
|
|
51
249
|
}
|
|
52
250
|
//# sourceMappingURL=adopt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/commands/adopt.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/commands/adopt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const IMAGE_WIDTHS: number[];
|
|
2
|
+
export interface AssetOptions {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
input?: string;
|
|
5
|
+
output?: string;
|
|
6
|
+
widths?: string;
|
|
7
|
+
quality?: number;
|
|
8
|
+
base?: string;
|
|
9
|
+
log?: (message: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface OptimizedImage {
|
|
12
|
+
src: string;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
sources: {
|
|
16
|
+
type: string;
|
|
17
|
+
srcSet: string;
|
|
18
|
+
}[];
|
|
19
|
+
variants: {
|
|
20
|
+
src: string;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
bytes: number;
|
|
24
|
+
format: string;
|
|
25
|
+
}[];
|
|
26
|
+
}
|
|
27
|
+
export declare function optimizeAssets(options?: AssetOptions): Promise<Record<string, OptimizedImage>>;
|
|
28
|
+
//# sourceMappingURL=assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/commands/assets.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,YAAY,UAA2D,CAAC;AACrF,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AACD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3F;AAED,wBAAsB,cAAc,CAClC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CA0LzC"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFile, stat } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { scaffoldToolsGuide } from "../scaffold/tools-guide.js";
|
|
5
|
+
import { atomicWrite, exists, writeFiles } from "../utils/fs.js";
|
|
6
|
+
import { run } from "../utils/process.js";
|
|
7
|
+
import { projectDirectory, projectPath, regularFiles } from "../utils/project-files.js";
|
|
8
|
+
export const IMAGE_WIDTHS = [320, 480, 640, 768, 1024, 1280, 1600, 1920, 2560, 3840];
|
|
9
|
+
export async function optimizeAssets(options = {}) {
|
|
10
|
+
const log = options.log ?? console.log;
|
|
11
|
+
const root = await projectDirectory(options.cwd);
|
|
12
|
+
const input = await projectPath(root, options.input ?? "assets/images");
|
|
13
|
+
const output = await projectPath(root, options.output ?? "public/media");
|
|
14
|
+
const publicRoot = path.join(root, "public");
|
|
15
|
+
if (!output.startsWith(publicRoot + path.sep))
|
|
16
|
+
throw new Error("Asset output must be a subdirectory of public/.");
|
|
17
|
+
if (output === input ||
|
|
18
|
+
output.startsWith(input + path.sep) ||
|
|
19
|
+
input.startsWith(output + path.sep))
|
|
20
|
+
throw new Error("Input and output directories must not overlap.");
|
|
21
|
+
const widths = options.widths
|
|
22
|
+
? [...new Set(options.widths.split(",").map(Number))].sort((a, b) => a - b)
|
|
23
|
+
: IMAGE_WIDTHS;
|
|
24
|
+
if (!widths.length ||
|
|
25
|
+
widths.length > 20 ||
|
|
26
|
+
widths.some((width) => !Number.isInteger(width) || width < 1 || width > 7680))
|
|
27
|
+
throw new Error("Widths must contain 1–20 integer sizes between 1 and 7680.");
|
|
28
|
+
const quality = options.quality ?? 78;
|
|
29
|
+
if (!Number.isInteger(quality) || quality < 1 || quality > 100)
|
|
30
|
+
throw new Error("Quality must be an integer from 1 to 100.");
|
|
31
|
+
const base = options.base ?? "/";
|
|
32
|
+
if (!base.startsWith("/") ||
|
|
33
|
+
base.startsWith("//") ||
|
|
34
|
+
/[?#\\\s]/.test(base) ||
|
|
35
|
+
base.split("/").includes(".."))
|
|
36
|
+
throw new Error("Base must be a site path such as / or /client/.");
|
|
37
|
+
const prefix = `${base.replace(/\/$/, "")}/${path.relative(publicRoot, output).split(path.sep).map(encodeURIComponent).join("/")}`;
|
|
38
|
+
for (const file of [
|
|
39
|
+
"src/assets/images.generated.ts",
|
|
40
|
+
"src/components/ui/ResponsiveImage.tsx",
|
|
41
|
+
"src/components/ui/index.ts",
|
|
42
|
+
"src/library/index.ts",
|
|
43
|
+
`${path.relative(root, output)}/manifest.json`,
|
|
44
|
+
])
|
|
45
|
+
await projectPath(root, file);
|
|
46
|
+
const candidates = (await regularFiles(input)).filter((file) => /\.(jpe?g|png|webp|avif|tiff?|gif)$/i.test(file));
|
|
47
|
+
if (!candidates.length)
|
|
48
|
+
throw new Error(`No supported raster images found in ${input}.`);
|
|
49
|
+
const { default: sharp } = await import("sharp");
|
|
50
|
+
const images = {};
|
|
51
|
+
const skipped = [];
|
|
52
|
+
for (const file of candidates) {
|
|
53
|
+
const source = path.join(input, file);
|
|
54
|
+
if ((await stat(source)).size > 50 * 1024 * 1024)
|
|
55
|
+
throw new Error(`Image exceeds 50 MB: ${file}`);
|
|
56
|
+
const buffer = await readFile(source);
|
|
57
|
+
const metadata = await sharp(buffer, { limitInputPixels: 100_000_000 }).metadata();
|
|
58
|
+
if ((metadata.pages ?? 1) > 1) {
|
|
59
|
+
skipped.push(`${file} (animated/multipage)`);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const swapped = [5, 6, 7, 8].includes(metadata.orientation ?? 1);
|
|
63
|
+
const width = (swapped ? metadata.height : metadata.width) ?? 0;
|
|
64
|
+
const height = (swapped ? metadata.width : metadata.height) ?? 0;
|
|
65
|
+
if (!width || !height)
|
|
66
|
+
throw new Error(`Missing image dimensions: ${file}`);
|
|
67
|
+
const sizes = [
|
|
68
|
+
...new Set([
|
|
69
|
+
...widths.filter((size) => size <= width),
|
|
70
|
+
Math.min(width, widths[widths.length - 1]),
|
|
71
|
+
]),
|
|
72
|
+
].sort((a, b) => a - b);
|
|
73
|
+
const id = createHash("sha256")
|
|
74
|
+
.update(buffer)
|
|
75
|
+
.update(JSON.stringify({
|
|
76
|
+
file,
|
|
77
|
+
sizes,
|
|
78
|
+
quality,
|
|
79
|
+
sharp: sharp.versions.sharp,
|
|
80
|
+
vips: sharp.versions.vips,
|
|
81
|
+
}))
|
|
82
|
+
.digest("hex")
|
|
83
|
+
.slice(0, 20);
|
|
84
|
+
const variants = [];
|
|
85
|
+
for (const size of sizes) {
|
|
86
|
+
for (const format of ["avif", "webp"]) {
|
|
87
|
+
const result = await sharp(buffer, { limitInputPixels: 100_000_000 })
|
|
88
|
+
.rotate()
|
|
89
|
+
.resize({ width: size, withoutEnlargement: true })[format]({ quality, effort: 4 })
|
|
90
|
+
.toBuffer({ resolveWithObject: true });
|
|
91
|
+
const name = `${id}-${result.info.width}.${format}`;
|
|
92
|
+
await atomicWrite(path.join(output, name), result.data);
|
|
93
|
+
variants.push({
|
|
94
|
+
src: `${prefix}/${name}`,
|
|
95
|
+
width: result.info.width,
|
|
96
|
+
height: result.info.height,
|
|
97
|
+
bytes: result.info.size,
|
|
98
|
+
format,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const fallbackSize = sizes.find((size) => size >= 1280) ?? sizes[sizes.length - 1];
|
|
103
|
+
const format = metadata.hasAlpha ? "png" : "jpeg";
|
|
104
|
+
const fallback = await sharp(buffer, { limitInputPixels: 100_000_000 })
|
|
105
|
+
.rotate()
|
|
106
|
+
.resize({ width: fallbackSize, withoutEnlargement: true })[format]({ quality })
|
|
107
|
+
.toBuffer({ resolveWithObject: true });
|
|
108
|
+
const name = `${id}-fallback.${format === "jpeg" ? "jpg" : "png"}`;
|
|
109
|
+
await atomicWrite(path.join(output, name), fallback.data);
|
|
110
|
+
images[file] = {
|
|
111
|
+
src: `${prefix}/${name}`,
|
|
112
|
+
width: fallback.info.width,
|
|
113
|
+
height: fallback.info.height,
|
|
114
|
+
sources: ["avif", "webp"].map((type) => ({
|
|
115
|
+
type: `image/${type}`,
|
|
116
|
+
srcSet: variants
|
|
117
|
+
.filter((item) => item.format === type)
|
|
118
|
+
.map((item) => `${item.src} ${item.width}w`)
|
|
119
|
+
.join(", "),
|
|
120
|
+
})),
|
|
121
|
+
variants,
|
|
122
|
+
};
|
|
123
|
+
log(`Optimized ${file}: ${sizes.join(", ")}px, AVIF + WebP`);
|
|
124
|
+
}
|
|
125
|
+
if (!Object.keys(images).length)
|
|
126
|
+
throw new Error(`No still images optimized. Skipped: ${skipped.join(", ")}`);
|
|
127
|
+
await atomicWrite(path.join(output, "manifest.json"), JSON.stringify({ images, skipped }, null, 2));
|
|
128
|
+
await atomicWrite(path.join(root, "src/assets/images.generated.ts"), `// Asset manifest; regenerate with mozole assets.\nexport const images = ${JSON.stringify(images, null, 2)} as const;\n`);
|
|
129
|
+
const component = "src/components/ui/ResponsiveImage.tsx";
|
|
130
|
+
const newComponent = !(await exists(path.join(root, component)));
|
|
131
|
+
await writeFiles(root, {
|
|
132
|
+
[component]: `import type { ImgHTMLAttributes } from "react";
|
|
133
|
+
|
|
134
|
+
export interface ResponsiveImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "srcSet" | "width" | "height" | "loading" | "fetchPriority" | "alt" | "sizes"> {
|
|
135
|
+
image: { src: string; width: number; height: number; sources: readonly { type: string; srcSet: string }[] };
|
|
136
|
+
alt: string;
|
|
137
|
+
sizes: string;
|
|
138
|
+
priority?: boolean;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function ResponsiveImage({ image, alt, sizes, priority = false, ...props }: ResponsiveImageProps) {
|
|
142
|
+
return <picture>
|
|
143
|
+
{image.sources.map(source => <source key={source.type} type={source.type} srcSet={source.srcSet} sizes={sizes} />)}
|
|
144
|
+
<img {...props} src={image.src} width={image.width} height={image.height} alt={alt} sizes={sizes} loading={priority ? "eager" : "lazy"} fetchPriority={priority ? "high" : "auto"} decoding="async" />
|
|
145
|
+
</picture>;
|
|
146
|
+
}
|
|
147
|
+
`,
|
|
148
|
+
});
|
|
149
|
+
if (newComponent) {
|
|
150
|
+
for (const [file, line] of [
|
|
151
|
+
["src/components/ui/index.ts", 'export * from "./ResponsiveImage";'],
|
|
152
|
+
["src/library/index.ts", 'export * from "../components/ui";'],
|
|
153
|
+
]) {
|
|
154
|
+
const target = path.join(root, file);
|
|
155
|
+
const content = (await exists(target)) ? await readFile(target, "utf8") : "";
|
|
156
|
+
if (!content.includes(line))
|
|
157
|
+
await atomicWrite(target, `${content}\n${line}\n`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
await scaffoldToolsGuide(root);
|
|
161
|
+
try {
|
|
162
|
+
await run("npx", [
|
|
163
|
+
"@biomejs/biome",
|
|
164
|
+
"format",
|
|
165
|
+
"--write",
|
|
166
|
+
"src/assets",
|
|
167
|
+
"src/components/ui/ResponsiveImage.tsx",
|
|
168
|
+
], { cwd: root });
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Non-fatal if biome is not yet available in the environment
|
|
172
|
+
}
|
|
173
|
+
log(`Wrote ${Object.keys(images).length} images to ${output}; skipped: ${skipped.join(", ") || "none"}. Originals preserved.`);
|
|
174
|
+
return images;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/commands/assets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/commands/backend.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EhB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { scaffoldBackend } from "../scaffold/backend.js";
|
|
4
|
+
import { atomicWrite, exists, findProjectRoot, writeFiles } from "../utils/fs.js";
|
|
5
|
+
export async function enableBackend(options) {
|
|
6
|
+
const { runtime } = options;
|
|
7
|
+
if (runtime !== "php" && runtime !== "node")
|
|
8
|
+
throw new Error("Choose backend runtime: php or node.");
|
|
9
|
+
const root = path.resolve(options.targetDir ?? (await findProjectRoot()) ?? process.cwd());
|
|
10
|
+
const manifestPath = path.join(root, ".mozole/project.json");
|
|
11
|
+
const project = (await exists(manifestPath))
|
|
12
|
+
? JSON.parse(await readFile(manifestPath, "utf8"))
|
|
13
|
+
: {};
|
|
14
|
+
if (project.backend && project.backend !== "none") {
|
|
15
|
+
if (project.backend !== runtime)
|
|
16
|
+
throw new Error(`Project already uses ${project.backend}. Migrate its data and API explicitly before switching.`);
|
|
17
|
+
console.log(`Backend ${runtime} already enabled. Run npm run dev:backend.`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const pkgPath = path.join(root, "package.json");
|
|
21
|
+
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
22
|
+
const dev = pkg.scripts?.dev;
|
|
23
|
+
if (typeof dev !== "string" || !/^(vite|react-router dev)(\s|$)/.test(dev)) {
|
|
24
|
+
throw new Error("Backend activation requires a Vite or React Router dev script. Adopt or configure the project first.");
|
|
25
|
+
}
|
|
26
|
+
const selected = dev.match(/(?:--config(?:=|\s+)|-c\s+)([a-zA-Z0-9_./-]+)/);
|
|
27
|
+
if ((dev.includes("--config") || /(?:^|\s)-c(?:\s|$)/.test(dev)) && !selected) {
|
|
28
|
+
throw new Error("Use an unquoted project-relative Vite config path before enabling backend.");
|
|
29
|
+
}
|
|
30
|
+
if (selected && (path.isAbsolute(selected[1]) || selected[1].split("/").includes(".."))) {
|
|
31
|
+
throw new Error("Vite config must be inside the project.");
|
|
32
|
+
}
|
|
33
|
+
const configs = ["vite.config.ts", "vite.config.mts", "vite.config.js", "vite.config.mjs"];
|
|
34
|
+
let config;
|
|
35
|
+
for (const candidate of configs)
|
|
36
|
+
if (await exists(path.join(root, candidate))) {
|
|
37
|
+
config = candidate;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
config = selected?.[1] ?? config;
|
|
41
|
+
if (config && !(await exists(path.join(root, config))))
|
|
42
|
+
throw new Error(`Vite config not found: ${config}`);
|
|
43
|
+
const wrapper = "mozole.backend.vite.config.mjs";
|
|
44
|
+
if (await exists(path.join(root, wrapper)))
|
|
45
|
+
throw new Error(`Preserving existing ${wrapper}; integrate the API proxy manually.`);
|
|
46
|
+
await scaffoldBackend(root, runtime);
|
|
47
|
+
await writeFiles(root, {
|
|
48
|
+
[wrapper]: `${config ? `import base from "./${config}";` : "const base = {};"}
|
|
49
|
+
import { defineConfig, mergeConfig } from "vite";
|
|
50
|
+
|
|
51
|
+
export default defineConfig(async (env) => mergeConfig(
|
|
52
|
+
await (typeof base === "function" ? base(env) : base),
|
|
53
|
+
{ server: { proxy: { "/api": "http://127.0.0.1:3001" } } },
|
|
54
|
+
));
|
|
55
|
+
`,
|
|
56
|
+
});
|
|
57
|
+
const updatedPkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
58
|
+
updatedPkg.scripts.dev = `${selected ? dev.replace(selected[0], "").trim() : dev} --config ${wrapper}`;
|
|
59
|
+
await atomicWrite(pkgPath, JSON.stringify(updatedPkg, null, 2));
|
|
60
|
+
await atomicWrite(manifestPath, JSON.stringify({ ...project, backend: runtime }, null, 2));
|
|
61
|
+
const architecturePath = path.join(root, "docs/repomap/architecture.md");
|
|
62
|
+
if (await exists(architecturePath)) {
|
|
63
|
+
const architecture = await readFile(architecturePath, "utf8");
|
|
64
|
+
await atomicWrite(architecturePath, architecture.replace(/^- \*\*Backend Architecture:\*\*.*$/m, `- **Backend Architecture:** ${runtime === "php" ? "PHP 8.1+ API in api/" : "Node.js HTTP API in server/"}`));
|
|
65
|
+
}
|
|
66
|
+
console.log(`Backend ${runtime} enabled. Run npm run dev:backend and npm run dev in separate terminals.`);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=backend.js.map
|