defuss-ssg 0.6.2 → 0.7.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 +126 -7
- package/dist/cli.mjs +461 -62
- package/dist/content.cjs +112 -0
- package/dist/content.d.cts +8 -0
- package/dist/content.d.mts +8 -0
- package/dist/content.mjs +110 -0
- package/dist/index.cjs +55 -35
- package/dist/index.d.cts +8 -6
- package/dist/index.d.mts +8 -6
- package/dist/index.mjs +8 -3
- package/dist/path-Br3DXScZ.cjs +179 -0
- package/dist/path-CjHWUK8o.mjs +171 -0
- package/dist/{serve-CTYzPwKQ.mjs → serve-BFMU8uCH.mjs} +50 -35
- package/dist/{vite-DtwFnDf2.d.mts → types-CZSWRdQS.d.cts} +56 -5
- package/dist/{vite-DtwFnDf2.d.cts → types-CZSWRdQS.d.mts} +56 -5
- package/dist/{vite-CkpguLfK.cjs → vite-BC7XxFTV.cjs} +311 -304
- package/dist/{vite-DdJcWQGP.mjs → vite-CSOGjlHB.mjs} +292 -285
- package/dist/vite.cjs +3 -2
- package/dist/vite.d.cts +6 -2
- package/dist/vite.d.mts +6 -2
- package/dist/vite.mjs +3 -2
- package/package.json +29 -7
package/dist/cli.mjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { v as validateProjectDir, b as build } from './vite-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
6
|
-
import {
|
|
2
|
+
import { r as readConfig, v as validateProjectDir, b as build } from './vite-CSOGjlHB.mjs';
|
|
3
|
+
import { spawnSync, spawn } from 'node:child_process';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
import { mkdtempSync, writeFileSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { resolve, join, basename, dirname } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { d as dev, s as serve } from './serve-BFMU8uCH.mjs';
|
|
7
10
|
import 'fast-glob';
|
|
8
11
|
import 'node:fs/promises';
|
|
9
12
|
import 'defuss/server';
|
|
10
|
-
import 'node:crypto';
|
|
11
13
|
import '@mdx-js/rollup';
|
|
12
14
|
import 'vite';
|
|
13
15
|
import 'defuss-vite';
|
|
14
16
|
import 'node:module';
|
|
15
|
-
import '
|
|
16
|
-
import 'node:os';
|
|
17
|
-
import 'esbuild';
|
|
17
|
+
import 'rolldown';
|
|
18
18
|
import 'rehype-katex';
|
|
19
19
|
import 'rehype-stringify';
|
|
20
20
|
import 'remark-frontmatter';
|
|
@@ -23,8 +23,243 @@ import 'remark-gfm';
|
|
|
23
23
|
import 'remark-parse';
|
|
24
24
|
import 'remark-rehype';
|
|
25
25
|
import 'remark-mdx-frontmatter';
|
|
26
|
+
import './path-CjHWUK8o.mjs';
|
|
27
|
+
import 'node:process';
|
|
26
28
|
import 'defuss-express';
|
|
27
29
|
|
|
30
|
+
const CONTAINER_IMAGE_TAG = "defuss-ssg";
|
|
31
|
+
const CONTAINER_WORKSPACE_DIR = "/workspace";
|
|
32
|
+
const CONTAINER_NODE_MODULES_DIR = `${CONTAINER_WORKSPACE_DIR}/node_modules`;
|
|
33
|
+
const DEFAULT_CONTAINER_PORT = 3e3;
|
|
34
|
+
const GENERATED_DOCKERFILE_NAME = "Dockerfile";
|
|
35
|
+
const createDockerfile = (packageTarballName) => `# syntax=docker/dockerfile:1.7
|
|
36
|
+
|
|
37
|
+
FROM oven/bun:1.3.9 AS bun
|
|
38
|
+
|
|
39
|
+
FROM node:24-trixie-slim
|
|
40
|
+
|
|
41
|
+
WORKDIR /app
|
|
42
|
+
|
|
43
|
+
ENV NODE_ENV=production
|
|
44
|
+
|
|
45
|
+
RUN apt-get update \\
|
|
46
|
+
&& apt-get install -y --no-install-recommends ca-certificates git \\
|
|
47
|
+
&& git config --global --add url."https://github.com/".insteadOf ssh://git@github.com/ \\
|
|
48
|
+
&& git config --global --add url."https://github.com/".insteadOf git+ssh://git@github.com/ \\
|
|
49
|
+
&& git config --global --add url."https://github.com/".insteadOf git@github.com: \\
|
|
50
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
51
|
+
|
|
52
|
+
COPY ${packageTarballName} /tmp/${packageTarballName}
|
|
53
|
+
COPY --from=bun /usr/local/bin/bun /usr/local/bin/bun
|
|
54
|
+
RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx \\
|
|
55
|
+
&& npm install -g /tmp/${packageTarballName} \\
|
|
56
|
+
&& rm -f /tmp/${packageTarballName} \\
|
|
57
|
+
&& npm cache clean --force
|
|
58
|
+
|
|
59
|
+
ENTRYPOINT ["defuss-ssg"]
|
|
60
|
+
CMD ["dev", "/workspace", "--host", "0.0.0.0", "--port", "3000"]
|
|
61
|
+
`;
|
|
62
|
+
const getPackageRootDir = () => fileURLToPath(new URL("../", import.meta.url));
|
|
63
|
+
const packCurrentPackage = (tempDir) => {
|
|
64
|
+
const packageRootDir = getPackageRootDir();
|
|
65
|
+
const result = spawnSync(
|
|
66
|
+
"npm",
|
|
67
|
+
["pack", "--json", "--pack-destination", tempDir],
|
|
68
|
+
{
|
|
69
|
+
cwd: packageRootDir,
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
shell: process.platform === "win32"
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
if (result.error) {
|
|
75
|
+
throw result.error;
|
|
76
|
+
}
|
|
77
|
+
if (result.status !== 0) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
result.stderr || "Failed to pack the current defuss-ssg package."
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
const output = JSON.parse(result.stdout);
|
|
83
|
+
const tarballName = output.at(0)?.filename;
|
|
84
|
+
if (!tarballName) {
|
|
85
|
+
throw new Error("npm pack did not return a package tarball name.");
|
|
86
|
+
}
|
|
87
|
+
return tarballName;
|
|
88
|
+
};
|
|
89
|
+
const getNodeModulesVolumeName = (projectDir) => {
|
|
90
|
+
const safeBaseName = basename(projectDir).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "project";
|
|
91
|
+
const hash = createHash("sha256").update(projectDir).digest("hex").slice(0, 12);
|
|
92
|
+
return `defuss-ssg-node-modules-${safeBaseName}-${hash}`;
|
|
93
|
+
};
|
|
94
|
+
const hasCommand = (command) => {
|
|
95
|
+
const result = spawnSync(command, ["--version"], {
|
|
96
|
+
stdio: "ignore",
|
|
97
|
+
shell: process.platform === "win32"
|
|
98
|
+
});
|
|
99
|
+
return !result.error && result.status === 0;
|
|
100
|
+
};
|
|
101
|
+
const resolveContainerRuntime = async (projectDir, debug) => {
|
|
102
|
+
const configuredRuntime = (await readConfig(projectDir, debug)).containerRuntime;
|
|
103
|
+
if (configuredRuntime) {
|
|
104
|
+
if (!hasCommand(configuredRuntime)) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Configured containerRuntime "${configuredRuntime}" is not available on PATH.`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return configuredRuntime;
|
|
110
|
+
}
|
|
111
|
+
if (hasCommand("docker")) {
|
|
112
|
+
return "docker";
|
|
113
|
+
}
|
|
114
|
+
if (hasCommand("podman")) {
|
|
115
|
+
return "podman";
|
|
116
|
+
}
|
|
117
|
+
throw new Error(
|
|
118
|
+
"Neither docker nor podman is available on PATH. Install one of them or set containerRuntime in config.ts."
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
const runContainerRuntime = (runtime, args, label, cwd) => {
|
|
122
|
+
const result = spawnSync(runtime, args, {
|
|
123
|
+
cwd,
|
|
124
|
+
stdio: "inherit",
|
|
125
|
+
shell: process.platform === "win32"
|
|
126
|
+
});
|
|
127
|
+
if (result.error) {
|
|
128
|
+
throw result.error;
|
|
129
|
+
}
|
|
130
|
+
if (result.status !== 0) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`${runtime} ${args.join(" ")} failed while ${label} with code ${result.status ?? "unknown"}`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const hasPublishArgs = (dockerArgs) => {
|
|
137
|
+
for (let index = 0; index < dockerArgs.length; index += 1) {
|
|
138
|
+
const arg = dockerArgs[index];
|
|
139
|
+
if (arg === "-p" || arg === "-P" || arg === "--publish" || arg === "--publish-all" || arg.startsWith("--publish=")) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
};
|
|
145
|
+
const extractHostNetworkArgs = (dockerArgs) => {
|
|
146
|
+
const remainingArgs = [];
|
|
147
|
+
let hostNetworkRequested = false;
|
|
148
|
+
for (let index = 0; index < dockerArgs.length; index += 1) {
|
|
149
|
+
const arg = dockerArgs[index];
|
|
150
|
+
if (arg === "--net=host" || arg === "--network=host") {
|
|
151
|
+
hostNetworkRequested = true;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if ((arg === "--net" || arg === "--network") && dockerArgs[index + 1] === "host") {
|
|
155
|
+
hostNetworkRequested = true;
|
|
156
|
+
index += 1;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
remainingArgs.push(arg);
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
remainingArgs,
|
|
163
|
+
hostNetworkRequested
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
const getInnerCommand = (command) => command.slice("docker-".length);
|
|
167
|
+
const createInnerArgs = ({
|
|
168
|
+
command,
|
|
169
|
+
debug,
|
|
170
|
+
host,
|
|
171
|
+
port,
|
|
172
|
+
multicore,
|
|
173
|
+
skipSetup
|
|
174
|
+
}) => {
|
|
175
|
+
const innerCommand = getInnerCommand(command);
|
|
176
|
+
const innerArgs = [innerCommand, CONTAINER_WORKSPACE_DIR];
|
|
177
|
+
if (debug) {
|
|
178
|
+
innerArgs.push("--debug");
|
|
179
|
+
}
|
|
180
|
+
if (innerCommand === "serve" && multicore) {
|
|
181
|
+
innerArgs.push("--multicore");
|
|
182
|
+
}
|
|
183
|
+
if (skipSetup) {
|
|
184
|
+
innerArgs.push("--skip-setup");
|
|
185
|
+
}
|
|
186
|
+
if (innerCommand === "dev" || innerCommand === "serve") {
|
|
187
|
+
const selectedHost = host ?? "0.0.0.0";
|
|
188
|
+
const selectedPort = port ?? DEFAULT_CONTAINER_PORT;
|
|
189
|
+
innerArgs.push("--host", selectedHost, "--port", String(selectedPort));
|
|
190
|
+
return { innerArgs, selectedPort };
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
innerArgs,
|
|
194
|
+
selectedPort: port
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
const runContainerCommand = async ({
|
|
198
|
+
command,
|
|
199
|
+
projectDir,
|
|
200
|
+
debug = false,
|
|
201
|
+
host,
|
|
202
|
+
port,
|
|
203
|
+
multicore = false,
|
|
204
|
+
skipSetup = false,
|
|
205
|
+
dockerArgs
|
|
206
|
+
}) => {
|
|
207
|
+
const resolvedProjectDir = resolve(projectDir);
|
|
208
|
+
const runtime = await resolveContainerRuntime(resolvedProjectDir, debug);
|
|
209
|
+
const { remainingArgs, hostNetworkRequested } = extractHostNetworkArgs(dockerArgs);
|
|
210
|
+
const useHostNetwork = hostNetworkRequested && process.platform === "linux";
|
|
211
|
+
const tempDir = mkdtempSync(join(tmpdir(), "defuss-ssg-container-"));
|
|
212
|
+
const volumeName = getNodeModulesVolumeName(resolvedProjectDir);
|
|
213
|
+
const dockerfilePath = join(tempDir, GENERATED_DOCKERFILE_NAME);
|
|
214
|
+
const { innerArgs, selectedPort } = createInnerArgs({
|
|
215
|
+
command,
|
|
216
|
+
debug,
|
|
217
|
+
host,
|
|
218
|
+
port,
|
|
219
|
+
multicore,
|
|
220
|
+
skipSetup
|
|
221
|
+
});
|
|
222
|
+
const packageTarballName = packCurrentPackage(tempDir);
|
|
223
|
+
writeFileSync(dockerfilePath, createDockerfile(packageTarballName), "utf8");
|
|
224
|
+
try {
|
|
225
|
+
console.log(`Using ${runtime} for containerized ${getInnerCommand(command)}.`);
|
|
226
|
+
if (hostNetworkRequested && !useHostNetwork) {
|
|
227
|
+
console.warn(
|
|
228
|
+
`Ignoring --network host on ${process.platform}; using published ports for localhost access instead.`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
runContainerRuntime(
|
|
232
|
+
runtime,
|
|
233
|
+
["build", "-t", CONTAINER_IMAGE_TAG, "-f", GENERATED_DOCKERFILE_NAME, tempDir],
|
|
234
|
+
"building the defuss-ssg container image",
|
|
235
|
+
tempDir
|
|
236
|
+
);
|
|
237
|
+
const runArgs = [
|
|
238
|
+
"run",
|
|
239
|
+
"--rm",
|
|
240
|
+
...remainingArgs,
|
|
241
|
+
"-v",
|
|
242
|
+
`${resolvedProjectDir}:${CONTAINER_WORKSPACE_DIR}`,
|
|
243
|
+
"-v",
|
|
244
|
+
`${volumeName}:${CONTAINER_NODE_MODULES_DIR}`
|
|
245
|
+
];
|
|
246
|
+
if (useHostNetwork) {
|
|
247
|
+
runArgs.push("--network", "host");
|
|
248
|
+
}
|
|
249
|
+
if ((selectedPort ?? 0) > 0 && (getInnerCommand(command) === "dev" || getInnerCommand(command) === "serve") && !hasPublishArgs(remainingArgs) && !useHostNetwork) {
|
|
250
|
+
runArgs.push("-p", `${selectedPort}:${selectedPort}`);
|
|
251
|
+
}
|
|
252
|
+
runArgs.push(CONTAINER_IMAGE_TAG, ...innerArgs);
|
|
253
|
+
runContainerRuntime(
|
|
254
|
+
runtime,
|
|
255
|
+
runArgs,
|
|
256
|
+
`running ${command} for ${resolvedProjectDir}`
|
|
257
|
+
);
|
|
258
|
+
} finally {
|
|
259
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
|
|
28
263
|
const canResolve = (dep, dir) => {
|
|
29
264
|
let current = dir;
|
|
30
265
|
while (true) {
|
|
@@ -38,7 +273,7 @@ const canResolve = (dep, dir) => {
|
|
|
38
273
|
const runInstall = (cmd, args, cwd, env) => new Promise((resolve, reject) => {
|
|
39
274
|
const child = spawn(cmd, args, {
|
|
40
275
|
cwd,
|
|
41
|
-
shell:
|
|
276
|
+
shell: process.platform === "win32",
|
|
42
277
|
stdio: ["inherit", "pipe", "pipe"],
|
|
43
278
|
env: env ?? process.env
|
|
44
279
|
});
|
|
@@ -48,11 +283,11 @@ const runInstall = (cmd, args, cwd, env) => new Promise((resolve, reject) => {
|
|
|
48
283
|
lastLines.push(line);
|
|
49
284
|
if (lastLines.length > 3) lastLines.shift();
|
|
50
285
|
if (process.stdout.isTTY) {
|
|
51
|
-
for (let
|
|
286
|
+
for (let index = 0; index < printedLines; index += 1) {
|
|
52
287
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
53
288
|
}
|
|
54
|
-
for (const
|
|
55
|
-
process.stdout.write(`${
|
|
289
|
+
for (const outputLine of lastLines) {
|
|
290
|
+
process.stdout.write(`${outputLine}
|
|
56
291
|
`);
|
|
57
292
|
}
|
|
58
293
|
printedLines = lastLines.length;
|
|
@@ -62,22 +297,49 @@ const runInstall = (cmd, args, cwd, env) => new Promise((resolve, reject) => {
|
|
|
62
297
|
}
|
|
63
298
|
};
|
|
64
299
|
const handleData = (chunk) => {
|
|
65
|
-
const lines = chunk.toString().split(/\r\n|\n|\r/).filter((
|
|
300
|
+
const lines = chunk.toString().split(/\r\n|\n|\r/).filter((line) => line.trim().length > 0);
|
|
66
301
|
for (const line of lines) pushLine(line);
|
|
67
302
|
};
|
|
68
303
|
child.stdout?.on("data", handleData);
|
|
69
304
|
child.stderr?.on("data", handleData);
|
|
70
305
|
child.on("error", reject);
|
|
71
306
|
child.on("close", (code) => {
|
|
72
|
-
if (code === 0)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
307
|
+
if (code === 0) {
|
|
308
|
+
resolve();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
reject(
|
|
312
|
+
new Error(
|
|
313
|
+
`${cmd} ${args.join(" ")} exited with code ${code ?? "unknown"}`
|
|
314
|
+
)
|
|
315
|
+
);
|
|
79
316
|
});
|
|
80
317
|
});
|
|
318
|
+
const getInstallCommand = (pm, projectDir) => {
|
|
319
|
+
if (pm === "bun") {
|
|
320
|
+
return {
|
|
321
|
+
cmd: "bun",
|
|
322
|
+
args: ["install", "--no-cache"],
|
|
323
|
+
env: { ...process.env, BUN_WORKSPACE_ROOT: projectDir }
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
if (pm === "yarn") {
|
|
327
|
+
return {
|
|
328
|
+
cmd: "corepack",
|
|
329
|
+
args: ["yarn", "install"]
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
if (pm === "pnpm") {
|
|
333
|
+
return {
|
|
334
|
+
cmd: "corepack",
|
|
335
|
+
args: ["pnpm", "install"]
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
cmd: "npm",
|
|
340
|
+
args: ["install"]
|
|
341
|
+
};
|
|
342
|
+
};
|
|
81
343
|
const setup = async (projectDir) => {
|
|
82
344
|
const projectDirStatus = validateProjectDir(projectDir);
|
|
83
345
|
if (projectDirStatus.code !== "OK") return projectDirStatus;
|
|
@@ -110,22 +372,19 @@ const setup = async (projectDir) => {
|
|
|
110
372
|
...packageJson.dependencies,
|
|
111
373
|
...packageJson.devDependencies
|
|
112
374
|
};
|
|
113
|
-
const depNames = Object.keys(allDeps)
|
|
114
|
-
|
|
115
|
-
// skip self-reference (we're already running)
|
|
116
|
-
);
|
|
117
|
-
const allResolvable = depNames.length === 0 || depNames.every((d) => canResolve(d, projectDir));
|
|
375
|
+
const depNames = Object.keys(allDeps);
|
|
376
|
+
const allResolvable = depNames.length === 0 || depNames.every((dependency) => canResolve(dependency, projectDir));
|
|
118
377
|
if (allResolvable) {
|
|
119
|
-
console.log(
|
|
378
|
+
console.log("All dependencies already available - skipping install.");
|
|
120
379
|
return { code: "OK", message: "Setup completed (deps already available)" };
|
|
121
380
|
}
|
|
122
381
|
console.log(`Setting up project in ${projectDir} using ${pm}...`);
|
|
123
382
|
if (pm === "bun") {
|
|
124
383
|
try {
|
|
125
384
|
await new Promise((resolve, reject) => {
|
|
126
|
-
const child = spawn(
|
|
385
|
+
const child = spawn("bun", ["pm", "trust", "esbuild"], {
|
|
127
386
|
cwd: projectDir,
|
|
128
|
-
shell:
|
|
387
|
+
shell: process.platform === "win32",
|
|
129
388
|
stdio: "ignore",
|
|
130
389
|
env: { ...process.env, BUN_WORKSPACE_ROOT: projectDir }
|
|
131
390
|
});
|
|
@@ -136,46 +395,142 @@ const setup = async (projectDir) => {
|
|
|
136
395
|
}
|
|
137
396
|
}
|
|
138
397
|
try {
|
|
139
|
-
const
|
|
398
|
+
const installCommand = getInstallCommand(pm, projectDir);
|
|
140
399
|
await runInstall(
|
|
141
|
-
|
|
142
|
-
|
|
400
|
+
installCommand.cmd,
|
|
401
|
+
installCommand.args,
|
|
143
402
|
projectDir,
|
|
144
|
-
|
|
403
|
+
installCommand.env
|
|
145
404
|
);
|
|
146
405
|
console.log("Dependencies installed successfully.");
|
|
406
|
+
return { code: "OK", message: "Setup completed successfully" };
|
|
147
407
|
} catch (error) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
408
|
+
return {
|
|
409
|
+
code: "INSTALL_FAILED",
|
|
410
|
+
message: `Failed to install dependencies with ${pm}: ${error.message}`
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const usage = `Usage: defuss-ssg [dev|build|serve|docker-dev|docker-build|docker-serve] [folder] [options]
|
|
416
|
+
No args => dev .
|
|
417
|
+
Single path => dev <path>
|
|
418
|
+
Single command => <command> .
|
|
419
|
+
Command + folder => <command> <folder>
|
|
420
|
+
Flags:
|
|
421
|
+
--debug, -d
|
|
422
|
+
--multicore
|
|
423
|
+
--port, -p <number>
|
|
424
|
+
--host, -H <host>
|
|
425
|
+
--skip-setup
|
|
426
|
+
--docker-args <args...>`;
|
|
427
|
+
const isTruthy = (value) => {
|
|
428
|
+
if (!value) return false;
|
|
429
|
+
return ["1", "true", "yes", "on"].includes(value.toLowerCase());
|
|
430
|
+
};
|
|
431
|
+
const isDefussWorkerProcess = () => typeof process.env.DEFUSS_WORKER_INDEX === "string";
|
|
432
|
+
const readFlagValue = (args, index, flag) => {
|
|
433
|
+
const next = args[index + 1];
|
|
434
|
+
if (!next || next.startsWith("-")) {
|
|
435
|
+
throw new Error(`Missing value for ${flag}`);
|
|
436
|
+
}
|
|
437
|
+
return next;
|
|
438
|
+
};
|
|
439
|
+
const parsePort = (value) => {
|
|
440
|
+
const port = Number(value);
|
|
441
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
442
|
+
throw new Error(`Invalid port: ${value}`);
|
|
443
|
+
}
|
|
444
|
+
return port;
|
|
445
|
+
};
|
|
446
|
+
const parseCliArgs = (args) => {
|
|
447
|
+
const dockerArgsIndex = args.indexOf("--docker-args");
|
|
448
|
+
const cliArgs = dockerArgsIndex === -1 ? args : args.slice(0, dockerArgsIndex);
|
|
449
|
+
const dockerArgs = dockerArgsIndex === -1 ? [] : args.slice(dockerArgsIndex + 1);
|
|
450
|
+
let debug = false;
|
|
451
|
+
let multicore = false;
|
|
452
|
+
let skipSetup = isTruthy(process.env.DEFUSS_SSG_SKIP_SETUP) || isDefussWorkerProcess();
|
|
453
|
+
let port;
|
|
454
|
+
let host;
|
|
455
|
+
const positional = [];
|
|
456
|
+
for (let index = 0; index < cliArgs.length; index += 1) {
|
|
457
|
+
const arg = cliArgs[index];
|
|
458
|
+
if (arg === "--debug" || arg === "-d") {
|
|
459
|
+
debug = true;
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
if (arg === "--multicore") {
|
|
463
|
+
multicore = true;
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (arg === "--skip-setup" || arg === "--no-setup") {
|
|
467
|
+
skipSetup = true;
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
if (arg === "--port" || arg === "-p") {
|
|
471
|
+
port = parsePort(readFlagValue(args, index, arg));
|
|
472
|
+
index += 1;
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if (arg.startsWith("--port=")) {
|
|
476
|
+
port = parsePort(arg.slice("--port=".length));
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (arg === "--host" || arg === "-H") {
|
|
480
|
+
host = readFlagValue(args, index, arg);
|
|
481
|
+
index += 1;
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (arg.startsWith("--host=")) {
|
|
485
|
+
host = arg.slice("--host=".length);
|
|
486
|
+
if (!host) {
|
|
487
|
+
throw new Error("Missing value for --host");
|
|
161
488
|
}
|
|
162
|
-
|
|
163
|
-
console.warn(
|
|
164
|
-
`Warning: ${error.message}
|
|
165
|
-
Continuing anyway - dependencies may already be available.`
|
|
166
|
-
);
|
|
489
|
+
continue;
|
|
167
490
|
}
|
|
491
|
+
positional.push(arg);
|
|
168
492
|
}
|
|
169
|
-
return {
|
|
493
|
+
return {
|
|
494
|
+
debug,
|
|
495
|
+
dockerArgs,
|
|
496
|
+
multicore,
|
|
497
|
+
skipSetup,
|
|
498
|
+
port,
|
|
499
|
+
host,
|
|
500
|
+
positional
|
|
501
|
+
};
|
|
170
502
|
};
|
|
171
|
-
|
|
172
503
|
(async () => {
|
|
173
504
|
const args = process.argv.slice(2);
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
505
|
+
const commands = /* @__PURE__ */ new Set([
|
|
506
|
+
"dev",
|
|
507
|
+
"build",
|
|
508
|
+
"serve",
|
|
509
|
+
"docker-dev",
|
|
510
|
+
"docker-build",
|
|
511
|
+
"docker-serve"
|
|
512
|
+
]);
|
|
513
|
+
const containerCommands = /* @__PURE__ */ new Set([
|
|
514
|
+
"docker-dev",
|
|
515
|
+
"docker-build",
|
|
516
|
+
"docker-serve"
|
|
517
|
+
]);
|
|
518
|
+
let debug;
|
|
519
|
+
let dockerArgs;
|
|
520
|
+
let multicore;
|
|
521
|
+
let skipSetup;
|
|
522
|
+
let port;
|
|
523
|
+
let host;
|
|
524
|
+
let positional;
|
|
525
|
+
try {
|
|
526
|
+
({ debug, dockerArgs, multicore, skipSetup, port, host, positional } = parseCliArgs(args));
|
|
527
|
+
} catch (error) {
|
|
528
|
+
console.error(
|
|
529
|
+
`${error instanceof Error ? error.message : "Invalid CLI arguments"}
|
|
530
|
+
${usage}`
|
|
531
|
+
);
|
|
532
|
+
process.exit(1);
|
|
533
|
+
}
|
|
179
534
|
let command;
|
|
180
535
|
let folder;
|
|
181
536
|
if (positional.length === 0) {
|
|
@@ -202,26 +557,70 @@ Continuing anyway - dependencies may already be available.`
|
|
|
202
557
|
process.exit(1);
|
|
203
558
|
}
|
|
204
559
|
const projectDir = resolve(folder);
|
|
205
|
-
|
|
560
|
+
const workerProcess = isDefussWorkerProcess();
|
|
561
|
+
const isContainerCommand = containerCommands.has(command);
|
|
562
|
+
if (!isContainerCommand && dockerArgs.length > 0) {
|
|
563
|
+
console.error(
|
|
564
|
+
`--docker-args can only be used with docker-dev, docker-build, or docker-serve.
|
|
565
|
+
${usage}`
|
|
566
|
+
);
|
|
567
|
+
process.exit(1);
|
|
568
|
+
}
|
|
569
|
+
if (isContainerCommand) {
|
|
570
|
+
await runContainerCommand({
|
|
571
|
+
command,
|
|
572
|
+
projectDir,
|
|
573
|
+
debug,
|
|
574
|
+
host,
|
|
575
|
+
port,
|
|
576
|
+
multicore,
|
|
577
|
+
skipSetup,
|
|
578
|
+
dockerArgs
|
|
579
|
+
});
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
if (skipSetup) {
|
|
583
|
+
if (!workerProcess) {
|
|
584
|
+
console.log(
|
|
585
|
+
`Skipping dependency setup for ${folder} (prepared environment).`
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
} else {
|
|
589
|
+
const setupStatus = await setup(projectDir);
|
|
590
|
+
if (setupStatus.code !== "OK") {
|
|
591
|
+
console.error(setupStatus.message);
|
|
592
|
+
process.exit(1);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
206
595
|
if (command === "dev") {
|
|
207
|
-
|
|
596
|
+
if (!workerProcess) {
|
|
597
|
+
console.log(`Starting Vite dev server for ${folder}...`);
|
|
598
|
+
}
|
|
208
599
|
await dev({
|
|
209
600
|
projectDir,
|
|
210
601
|
debug,
|
|
602
|
+
host,
|
|
603
|
+
port,
|
|
211
604
|
writeDevOutput: true
|
|
212
605
|
});
|
|
213
606
|
} else if (command === "build") {
|
|
214
|
-
|
|
607
|
+
if (!workerProcess) {
|
|
608
|
+
console.log(`Building ${folder}...`);
|
|
609
|
+
}
|
|
215
610
|
await build({
|
|
216
611
|
projectDir,
|
|
217
612
|
debug,
|
|
218
613
|
mode: "build"
|
|
219
614
|
});
|
|
220
615
|
} else if (command === "serve") {
|
|
221
|
-
|
|
616
|
+
if (!workerProcess) {
|
|
617
|
+
console.log(`Serving built output for ${folder}...`);
|
|
618
|
+
}
|
|
222
619
|
await serve({
|
|
223
620
|
projectDir,
|
|
224
621
|
debug,
|
|
622
|
+
host,
|
|
623
|
+
port,
|
|
225
624
|
workers: multicore ? "auto" : 1
|
|
226
625
|
});
|
|
227
626
|
} else {
|