@blinkk/root 3.1.1 → 3.1.3
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/dist/{chunk-X2C2MEJ2.js → chunk-HPRRG4EA.js} +2 -1
- package/dist/chunk-HPRRG4EA.js.map +7 -0
- package/dist/{chunk-E4F6CMO3.js → chunk-WGQNQPWG.js} +449 -139
- package/dist/chunk-WGQNQPWG.js.map +7 -0
- package/dist/cli/build-progress.d.ts +117 -0
- package/dist/cli/build.d.ts +8 -0
- package/dist/cli.js +1 -1
- package/dist/core/config.d.ts +41 -3
- package/dist/core.js.map +2 -2
- package/dist/functions.js +1 -1
- package/dist/jsx.js +1 -1
- package/dist/render.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-E4F6CMO3.js.map +0 -7
- package/dist/chunk-X2C2MEJ2.js.map +0 -7
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
} from "./chunk-TM6QRBGS.js";
|
|
48
48
|
|
|
49
49
|
// src/cli/cli.ts
|
|
50
|
-
import { Command, InvalidArgumentError } from "commander";
|
|
50
|
+
import { Command, InvalidArgumentError, Option } from "commander";
|
|
51
51
|
import { bgGreen, black } from "kleur/colors";
|
|
52
52
|
|
|
53
53
|
// src/cli/build.ts
|
|
@@ -55,7 +55,7 @@ import os from "node:os";
|
|
|
55
55
|
import path2 from "node:path";
|
|
56
56
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
57
57
|
import fsExtra from "fs-extra";
|
|
58
|
-
import { dim as
|
|
58
|
+
import { dim as dim3, cyan as cyan2 } from "kleur/colors";
|
|
59
59
|
import glob from "tiny-glob";
|
|
60
60
|
import { build as viteBuild } from "vite";
|
|
61
61
|
|
|
@@ -142,11 +142,253 @@ async function batchAsyncCalls(data, concurrency, asyncFunction) {
|
|
|
142
142
|
return result;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
// src/cli/build-progress.ts
|
|
146
|
+
import { cyan, dim as dim2, green } from "kleur/colors";
|
|
147
|
+
function parseBuildLogMode(value) {
|
|
148
|
+
if (value === void 0 || value === null || value === "") {
|
|
149
|
+
return "progress";
|
|
150
|
+
}
|
|
151
|
+
if (value === "progress" || value === "verbose" || value === "quiet") {
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
throw new Error(
|
|
155
|
+
`invalid --log value: "${value}" (expected "progress", "verbose", or "quiet")`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
function formatBytes(bytes) {
|
|
159
|
+
const k = 1024;
|
|
160
|
+
if (bytes < k) {
|
|
161
|
+
return (bytes / k).toFixed(2) + " kB";
|
|
162
|
+
}
|
|
163
|
+
const units = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
164
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
165
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + units[i];
|
|
166
|
+
}
|
|
167
|
+
function formatDuration(ms) {
|
|
168
|
+
const secs = ms / 1e3;
|
|
169
|
+
if (secs < 60) {
|
|
170
|
+
return `${secs.toFixed(1)}s`;
|
|
171
|
+
}
|
|
172
|
+
const mins = Math.floor(secs / 60);
|
|
173
|
+
const rem = Math.round(secs - mins * 60);
|
|
174
|
+
return `${mins}m${String(rem).padStart(2, "0")}s`;
|
|
175
|
+
}
|
|
176
|
+
var BAR_WIDTH = 20;
|
|
177
|
+
var BuildProgress = class {
|
|
178
|
+
total;
|
|
179
|
+
mode;
|
|
180
|
+
itemLabel;
|
|
181
|
+
outputDirLabel;
|
|
182
|
+
stream;
|
|
183
|
+
now;
|
|
184
|
+
intervalMs;
|
|
185
|
+
summaryTopN;
|
|
186
|
+
isTTY;
|
|
187
|
+
startedAt;
|
|
188
|
+
completed = 0;
|
|
189
|
+
totalBytes = 0;
|
|
190
|
+
files = [];
|
|
191
|
+
lastPrintAt = 0;
|
|
192
|
+
lastMilestone = 0;
|
|
193
|
+
ttyLineActive = false;
|
|
194
|
+
done = false;
|
|
195
|
+
/** Writes to `this.stream`, bypassing the log interceptor. */
|
|
196
|
+
streamWrite;
|
|
197
|
+
/** Restores the original `write` of each intercepted stream. */
|
|
198
|
+
restoreWrites = [];
|
|
199
|
+
/** True when intercepted output ended without a trailing newline. */
|
|
200
|
+
foreignLineOpen = false;
|
|
201
|
+
redrawTimer = null;
|
|
202
|
+
constructor(options) {
|
|
203
|
+
this.total = options.total;
|
|
204
|
+
this.mode = options.mode;
|
|
205
|
+
this.itemLabel = options.itemLabel ?? "pages";
|
|
206
|
+
this.outputDirLabel = options.outputDirLabel ?? "";
|
|
207
|
+
this.stream = options.stream ?? process.stdout;
|
|
208
|
+
this.now = options.now ?? Date.now;
|
|
209
|
+
this.isTTY = !!this.stream.isTTY;
|
|
210
|
+
this.intervalMs = options.intervalMs ?? (this.isTTY ? 80 : 5e3);
|
|
211
|
+
this.summaryTopN = options.summaryTopN ?? 5;
|
|
212
|
+
this.startedAt = this.now();
|
|
213
|
+
this.streamWrite = (str) => this.stream.write(str);
|
|
214
|
+
const interceptStreams = options.interceptStreams ?? (options.stream ? [] : [process.stdout, process.stderr]);
|
|
215
|
+
if (this.isTTY && this.mode === "progress") {
|
|
216
|
+
this.interceptLogs(interceptStreams);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/** Records a completed output file. */
|
|
220
|
+
add(outputFile, sizeBytes) {
|
|
221
|
+
this.completed += 1;
|
|
222
|
+
this.totalBytes += sizeBytes;
|
|
223
|
+
this.files.push({ path: outputFile, size: sizeBytes });
|
|
224
|
+
if (this.mode === "verbose") {
|
|
225
|
+
const paddedSize = formatBytes(sizeBytes).padStart(9, " ");
|
|
226
|
+
this.println(
|
|
227
|
+
` ${dim2(paddedSize)} ${dim2(this.outputDirLabel)}${cyan(outputFile)}`
|
|
228
|
+
);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (this.mode === "progress") {
|
|
232
|
+
this.maybePrintProgress();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** Clears any in-place progress line (call before printing errors). */
|
|
236
|
+
abort() {
|
|
237
|
+
this.clearTtyLine();
|
|
238
|
+
this.done = true;
|
|
239
|
+
this.restoreLogs();
|
|
240
|
+
}
|
|
241
|
+
/** Prints the final summary. */
|
|
242
|
+
finish() {
|
|
243
|
+
if (this.done) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
this.done = true;
|
|
247
|
+
this.restoreLogs();
|
|
248
|
+
this.clearTtyLine();
|
|
249
|
+
const elapsed = formatDuration(this.now() - this.startedAt);
|
|
250
|
+
const summary = `${this.completed} ${this.itemLabel} (${formatBytes(
|
|
251
|
+
this.totalBytes
|
|
252
|
+
)}) in ${elapsed}`;
|
|
253
|
+
this.println(` ${green("\u2713")} ${summary}`);
|
|
254
|
+
if (this.mode === "progress" && this.summaryTopN > 0) {
|
|
255
|
+
const largest = [...this.files].sort((a, b) => b.size - a.size).slice(0, this.summaryTopN);
|
|
256
|
+
if (largest.length > 0) {
|
|
257
|
+
this.println(` ${dim2(`largest ${this.itemLabel}:`)}`);
|
|
258
|
+
for (const file of largest) {
|
|
259
|
+
const paddedSize = formatBytes(file.size).padStart(9, " ");
|
|
260
|
+
this.println(
|
|
261
|
+
` ${dim2(paddedSize)} ${dim2(this.outputDirLabel)}${cyan(
|
|
262
|
+
file.path
|
|
263
|
+
)}`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
maybePrintProgress() {
|
|
270
|
+
const now = this.now();
|
|
271
|
+
if (this.isTTY) {
|
|
272
|
+
if (now - this.lastPrintAt < this.intervalMs) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
this.lastPrintAt = now;
|
|
276
|
+
this.renderTtyLine(now);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const milestone = Math.floor(this.completed / this.total * 10);
|
|
280
|
+
if (milestone <= this.lastMilestone || this.completed === this.total) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (now - this.lastPrintAt < this.intervalMs) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
this.lastMilestone = milestone;
|
|
287
|
+
this.lastPrintAt = now;
|
|
288
|
+
const pct = Math.floor(this.completed / this.total * 100);
|
|
289
|
+
this.println(
|
|
290
|
+
` ${this.completed}/${this.total} ${this.itemLabel} (${pct}%) \xB7 ${formatBytes(this.totalBytes)} \xB7 ${formatDuration(now - this.startedAt)}${this.eta(now)}`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
renderTtyLine(now) {
|
|
294
|
+
this.closeForeignLine();
|
|
295
|
+
const ratio = this.total > 0 ? this.completed / this.total : 0;
|
|
296
|
+
const filled = Math.round(ratio * BAR_WIDTH);
|
|
297
|
+
const bar = "\u2595" + "\u2588".repeat(filled) + "\u2591".repeat(BAR_WIDTH - filled) + "\u258F";
|
|
298
|
+
const pct = String(Math.floor(ratio * 100)).padStart(3, " ");
|
|
299
|
+
const line = ` ${bar} ${pct}% \xB7 ${this.completed}/${this.total} ${this.itemLabel} \xB7 ${formatBytes(this.totalBytes)} \xB7 ${formatDuration(now - this.startedAt)}${this.eta(now)}`;
|
|
300
|
+
this.streamWrite(`\r\x1B[2K${line}`);
|
|
301
|
+
this.ttyLineActive = true;
|
|
302
|
+
}
|
|
303
|
+
/** Returns an " · eta 12.3s" suffix once enough progress exists to estimate. */
|
|
304
|
+
eta(now) {
|
|
305
|
+
if (this.completed < 10 || this.completed / this.total < 0.05) {
|
|
306
|
+
return "";
|
|
307
|
+
}
|
|
308
|
+
const elapsed = now - this.startedAt;
|
|
309
|
+
const remaining = elapsed / this.completed * (this.total - this.completed);
|
|
310
|
+
return ` \xB7 eta ${formatDuration(remaining)}`;
|
|
311
|
+
}
|
|
312
|
+
clearTtyLine() {
|
|
313
|
+
if (this.ttyLineActive) {
|
|
314
|
+
this.streamWrite("\r\x1B[2K");
|
|
315
|
+
this.ttyLineActive = false;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
println(line) {
|
|
319
|
+
this.clearTtyLine();
|
|
320
|
+
this.closeForeignLine();
|
|
321
|
+
this.streamWrite(line + "\n");
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Patches `write` on each stream so foreign output (user logs) clears the
|
|
325
|
+
* progress bar line before printing and schedules a redraw after. The
|
|
326
|
+
* progress bar's own writes go through `streamWrite` and bypass the patch.
|
|
327
|
+
*/
|
|
328
|
+
interceptLogs(streams) {
|
|
329
|
+
const self = this;
|
|
330
|
+
for (const stream of streams) {
|
|
331
|
+
const original = stream.write;
|
|
332
|
+
if (stream === this.stream) {
|
|
333
|
+
this.streamWrite = (str) => original.call(stream, str);
|
|
334
|
+
}
|
|
335
|
+
stream.write = function(...args) {
|
|
336
|
+
self.clearTtyLine();
|
|
337
|
+
const chunk = args[0];
|
|
338
|
+
const text = typeof chunk === "string" ? chunk : String(chunk ?? "");
|
|
339
|
+
self.foreignLineOpen = text.length > 0 && !text.endsWith("\n");
|
|
340
|
+
const result = original.apply(stream, args);
|
|
341
|
+
self.scheduleRedraw();
|
|
342
|
+
return result;
|
|
343
|
+
};
|
|
344
|
+
this.restoreWrites.push(() => {
|
|
345
|
+
stream.write = original;
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/** Redraws the progress bar shortly after foreign output interrupts it. */
|
|
350
|
+
scheduleRedraw() {
|
|
351
|
+
if (this.done || this.redrawTimer !== null || this.completed === 0) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
this.redrawTimer = setTimeout(() => {
|
|
355
|
+
this.redrawTimer = null;
|
|
356
|
+
if (!this.done) {
|
|
357
|
+
this.renderTtyLine(this.now());
|
|
358
|
+
}
|
|
359
|
+
}, 0);
|
|
360
|
+
this.redrawTimer.unref?.();
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* If intercepted output left a partial (unterminated) line, terminate it
|
|
364
|
+
* so the next progress bar render doesn't overwrite it with `\r`.
|
|
365
|
+
*/
|
|
366
|
+
closeForeignLine() {
|
|
367
|
+
if (this.foreignLineOpen) {
|
|
368
|
+
this.streamWrite("\n");
|
|
369
|
+
this.foreignLineOpen = false;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
restoreLogs() {
|
|
373
|
+
if (this.redrawTimer) {
|
|
374
|
+
clearTimeout(this.redrawTimer);
|
|
375
|
+
this.redrawTimer = null;
|
|
376
|
+
}
|
|
377
|
+
while (this.restoreWrites.length > 0) {
|
|
378
|
+
this.restoreWrites.pop()();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
145
383
|
// src/cli/build-worker-pool.ts
|
|
146
384
|
import path from "node:path";
|
|
147
385
|
import { fileURLToPath } from "node:url";
|
|
386
|
+
import v8 from "node:v8";
|
|
148
387
|
import { Worker } from "node:worker_threads";
|
|
149
388
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
389
|
+
var WORKER_HEAP_LIMIT_MB = Math.ceil(
|
|
390
|
+
v8.getHeapStatistics().heap_size_limit / (1024 * 1024)
|
|
391
|
+
);
|
|
150
392
|
var BuildPageError = class extends Error {
|
|
151
393
|
urlPath;
|
|
152
394
|
params;
|
|
@@ -173,7 +415,8 @@ var BuildWorker = class {
|
|
|
173
415
|
this.pool = pool;
|
|
174
416
|
this.concurrency = options.workerConcurrency;
|
|
175
417
|
this.worker = new Worker(path.resolve(__dirname, "./build-worker.js"), {
|
|
176
|
-
workerData: { rootDir: options.rootDir, mode: options.mode }
|
|
418
|
+
workerData: { rootDir: options.rootDir, mode: options.mode },
|
|
419
|
+
resourceLimits: { maxOldGenerationSizeMb: WORKER_HEAP_LIMIT_MB }
|
|
177
420
|
});
|
|
178
421
|
let onReady;
|
|
179
422
|
let onFailed;
|
|
@@ -216,10 +459,30 @@ var BuildWorker = class {
|
|
|
216
459
|
}
|
|
217
460
|
});
|
|
218
461
|
}
|
|
462
|
+
/**
|
|
463
|
+
* Rejects all in-flight tasks after a worker-level failure (fatal error,
|
|
464
|
+
* crash, or non-zero exit — e.g. an OOM kill).
|
|
465
|
+
*
|
|
466
|
+
* Each task is rejected with its own `BuildPageError` so the build log
|
|
467
|
+
* names every page that was in flight when the worker died. Without this,
|
|
468
|
+
* worker deaths surface as a single generic error with no route context,
|
|
469
|
+
* making OOM crashes impossible to trace back to pages. Note the in-flight
|
|
470
|
+
* pages are the OOM *suspects*, not necessarily the cause (memory pressure
|
|
471
|
+
* is cumulative), which is why the message says "while rendering".
|
|
472
|
+
*/
|
|
219
473
|
failAll(err) {
|
|
220
474
|
const pendingTasks = Array.from(this.inFlight.values());
|
|
221
475
|
this.inFlight.clear();
|
|
222
|
-
pendingTasks.forEach(
|
|
476
|
+
pendingTasks.forEach(
|
|
477
|
+
(pending) => pending.reject(
|
|
478
|
+
new BuildPageError(
|
|
479
|
+
pending.task.urlPath,
|
|
480
|
+
pending.task.params,
|
|
481
|
+
pending.task.routeSrc,
|
|
482
|
+
`worker thread died while rendering this page (${pendingTasks.length} page(s) were in flight): ` + String(err.message || err)
|
|
483
|
+
)
|
|
484
|
+
)
|
|
485
|
+
);
|
|
223
486
|
}
|
|
224
487
|
/** Pulls tasks off the pool's queue until at max concurrency. */
|
|
225
488
|
next() {
|
|
@@ -274,18 +537,22 @@ var BuildWorkerPool = class {
|
|
|
274
537
|
|
|
275
538
|
// src/cli/build.ts
|
|
276
539
|
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
540
|
+
var activeLogMode = "progress";
|
|
277
541
|
async function build(rootProjectDir, options) {
|
|
278
542
|
const mode = options?.mode || "production";
|
|
279
543
|
process.env.NODE_ENV = mode;
|
|
544
|
+
activeLogMode = options?.quiet ? "quiet" : parseBuildLogMode(options?.log);
|
|
280
545
|
const rootDir = path2.resolve(rootProjectDir || process.cwd());
|
|
281
546
|
const rootConfig = await loadRootConfig(rootDir, { command: "build" });
|
|
282
547
|
const distDir = path2.join(rootDir, "dist");
|
|
283
548
|
const ssrOnly = options?.ssrOnly || false;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
549
|
+
if (activeLogMode !== "quiet") {
|
|
550
|
+
console.log();
|
|
551
|
+
console.log(`${dim3("\u2503")} project: ${rootDir}`);
|
|
552
|
+
console.log(`${dim3("\u2503")} output: ${distDir}/html`);
|
|
553
|
+
console.log(`${dim3("\u2503")} mode: ${mode}`);
|
|
554
|
+
console.log();
|
|
555
|
+
}
|
|
289
556
|
await rmDir(distDir);
|
|
290
557
|
await makeDir(distDir);
|
|
291
558
|
const pods = await collectPods(rootConfig);
|
|
@@ -341,7 +608,9 @@ async function build(rootProjectDir, options) {
|
|
|
341
608
|
...viteConfig,
|
|
342
609
|
root: rootDir,
|
|
343
610
|
mode,
|
|
344
|
-
plugins: vitePlugins
|
|
611
|
+
plugins: vitePlugins,
|
|
612
|
+
// In quiet mode, only surface vite warnings and errors.
|
|
613
|
+
logLevel: activeLogMode === "quiet" ? "warn" : viteConfig.logLevel
|
|
345
614
|
};
|
|
346
615
|
const ssrInput = {
|
|
347
616
|
render: path2.resolve(__dirname2, "./render.js")
|
|
@@ -540,7 +809,9 @@ async function build(rootProjectDir, options) {
|
|
|
540
809
|
await fsExtra.copy(assetFrom, assetTo);
|
|
541
810
|
printFileOutput(fileSize(assetTo), "dist/html/", assetRelPath);
|
|
542
811
|
}
|
|
543
|
-
|
|
812
|
+
if (activeLogMode !== "quiet") {
|
|
813
|
+
console.log("\njs/css output:");
|
|
814
|
+
}
|
|
544
815
|
await Promise.all(
|
|
545
816
|
Object.keys(rootManifest).map(async (src) => {
|
|
546
817
|
const assetData = rootManifest[src];
|
|
@@ -609,10 +880,9 @@ async function build(rootProjectDir, options) {
|
|
|
609
880
|
if (!result.staticContent) {
|
|
610
881
|
addSitemapXmlItem(result.urlPath, sitemapItem, result.outFilePath);
|
|
611
882
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
result.outFilePath
|
|
883
|
+
progress.add(
|
|
884
|
+
result.outFilePath,
|
|
885
|
+
fileSizeBytes(path2.join(buildDir, result.outFilePath))
|
|
616
886
|
);
|
|
617
887
|
};
|
|
618
888
|
const sitemapEntries = Object.entries(sitemap).filter(([, sitemapItem]) => {
|
|
@@ -624,76 +894,100 @@ async function build(rootProjectDir, options) {
|
|
|
624
894
|
}
|
|
625
895
|
return true;
|
|
626
896
|
});
|
|
627
|
-
|
|
897
|
+
if (activeLogMode !== "quiet") {
|
|
898
|
+
console.log("\nhtml output:");
|
|
899
|
+
}
|
|
628
900
|
const concurrency = Number(options?.concurrency || 10);
|
|
629
|
-
const
|
|
901
|
+
const resolvedThreads = resolveNumThreads(
|
|
630
902
|
options?.threads,
|
|
631
903
|
sitemapEntries.length
|
|
632
904
|
);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
905
|
+
const numThreads = resolvedThreads.count;
|
|
906
|
+
const workerConcurrency = numThreads > 0 ? Math.max(Math.ceil(concurrency / numThreads), 1) : 0;
|
|
907
|
+
if (activeLogMode !== "quiet") {
|
|
908
|
+
const threadsDesc = numThreads > 0 ? `${numThreads} workers x ${workerConcurrency} pages/worker` : `in-process, ${concurrency} concurrent pages`;
|
|
909
|
+
console.log(
|
|
910
|
+
` ${dim3(`threads: ${threadsDesc} (${resolvedThreads.source})`)}`
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
const progress = new BuildProgress({
|
|
914
|
+
total: sitemapEntries.length,
|
|
915
|
+
mode: activeLogMode,
|
|
916
|
+
itemLabel: "pages",
|
|
917
|
+
outputDirLabel: "dist/html/"
|
|
918
|
+
});
|
|
919
|
+
try {
|
|
920
|
+
if (numThreads > 0) {
|
|
921
|
+
const pool = new BuildWorkerPool({
|
|
922
|
+
numWorkers: numThreads,
|
|
923
|
+
workerConcurrency,
|
|
924
|
+
rootDir,
|
|
925
|
+
mode
|
|
926
|
+
});
|
|
927
|
+
try {
|
|
928
|
+
await pool.ready();
|
|
929
|
+
await Promise.all(
|
|
930
|
+
sitemapEntries.map(async ([urlPath, sitemapItem]) => {
|
|
931
|
+
try {
|
|
932
|
+
const result = await pool.run({
|
|
933
|
+
urlPath,
|
|
934
|
+
params: sitemapItem.params,
|
|
935
|
+
routeSrc: sitemapItem.route.src,
|
|
936
|
+
locale: sitemapItem.locale
|
|
937
|
+
});
|
|
938
|
+
onPageResult(sitemapItem, result);
|
|
939
|
+
} catch (e) {
|
|
940
|
+
if (e instanceof BuildPageError) {
|
|
941
|
+
progress.abort();
|
|
942
|
+
logBuildError(
|
|
943
|
+
{
|
|
944
|
+
route: sitemapItem.route,
|
|
945
|
+
params: sitemapItem.params,
|
|
946
|
+
urlPath
|
|
947
|
+
},
|
|
948
|
+
new Error(e.workerError)
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
throw e;
|
|
952
|
+
}
|
|
953
|
+
})
|
|
954
|
+
);
|
|
955
|
+
} finally {
|
|
956
|
+
await pool.terminate();
|
|
957
|
+
}
|
|
958
|
+
} else {
|
|
959
|
+
await batchAsyncCalls(
|
|
960
|
+
sitemapEntries,
|
|
961
|
+
concurrency,
|
|
962
|
+
async ([urlPath, sitemapItem]) => {
|
|
644
963
|
try {
|
|
645
|
-
const result = await
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
964
|
+
const result = await buildPage(
|
|
965
|
+
renderer,
|
|
966
|
+
rootConfig,
|
|
967
|
+
buildDir,
|
|
968
|
+
sitemapItem.route,
|
|
969
|
+
{ urlPath, params: sitemapItem.params }
|
|
970
|
+
);
|
|
651
971
|
onPageResult(sitemapItem, result);
|
|
652
972
|
} catch (e) {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
}
|
|
663
|
-
throw e;
|
|
973
|
+
progress.abort();
|
|
974
|
+
logBuildError(
|
|
975
|
+
{ route: sitemapItem.route, params: sitemapItem.params, urlPath },
|
|
976
|
+
e
|
|
977
|
+
);
|
|
978
|
+
throw new Error(
|
|
979
|
+
`BuildError: ${urlPath} (${sitemapItem.route.src}) failed to build.`,
|
|
980
|
+
{ cause: e }
|
|
981
|
+
);
|
|
664
982
|
}
|
|
665
|
-
}
|
|
983
|
+
}
|
|
666
984
|
);
|
|
667
|
-
} finally {
|
|
668
|
-
await pool.terminate();
|
|
669
985
|
}
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
concurrency,
|
|
674
|
-
async ([urlPath, sitemapItem]) => {
|
|
675
|
-
try {
|
|
676
|
-
const result = await buildPage(
|
|
677
|
-
renderer,
|
|
678
|
-
rootConfig,
|
|
679
|
-
buildDir,
|
|
680
|
-
sitemapItem.route,
|
|
681
|
-
{ urlPath, params: sitemapItem.params }
|
|
682
|
-
);
|
|
683
|
-
onPageResult(sitemapItem, result);
|
|
684
|
-
} catch (e) {
|
|
685
|
-
logBuildError(
|
|
686
|
-
{ route: sitemapItem.route, params: sitemapItem.params, urlPath },
|
|
687
|
-
e
|
|
688
|
-
);
|
|
689
|
-
throw new Error(
|
|
690
|
-
`BuildError: ${urlPath} (${sitemapItem.route.src}) failed to build.`,
|
|
691
|
-
{ cause: e }
|
|
692
|
-
);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
);
|
|
986
|
+
} catch (e) {
|
|
987
|
+
progress.abort();
|
|
988
|
+
throw e;
|
|
696
989
|
}
|
|
990
|
+
progress.finish();
|
|
697
991
|
if (rootConfig.sitemap) {
|
|
698
992
|
const sitemapXmlBuilder = [];
|
|
699
993
|
sitemapXmlItems.sort((a, b) => a.url.localeCompare(b.url));
|
|
@@ -734,42 +1028,51 @@ function isRouteFile(filepath) {
|
|
|
734
1028
|
return filepath.startsWith("routes") && isJsFile(filepath);
|
|
735
1029
|
}
|
|
736
1030
|
var MIN_PAGES_PER_THREAD = 10;
|
|
1031
|
+
var MEMORY_PER_THREAD = 1024 * 1024 * 1024;
|
|
1032
|
+
function availableMemory() {
|
|
1033
|
+
if (typeof process.availableMemory === "function") {
|
|
1034
|
+
return process.availableMemory();
|
|
1035
|
+
}
|
|
1036
|
+
return os.freemem();
|
|
1037
|
+
}
|
|
737
1038
|
function resolveNumThreads(threads, numPages) {
|
|
738
1039
|
if (threads === void 0 || threads === false) {
|
|
739
|
-
return 0;
|
|
1040
|
+
return { count: 0, source: "--threads not set" };
|
|
740
1041
|
}
|
|
741
1042
|
if (threads === true || threads === "auto") {
|
|
742
1043
|
const maxByCpu = Math.max(os.availableParallelism() - 1, 1);
|
|
743
1044
|
const maxByPages = Math.floor(numPages / MIN_PAGES_PER_THREAD);
|
|
744
|
-
const
|
|
1045
|
+
const maxByMemory = Math.max(
|
|
1046
|
+
Math.floor(availableMemory() / MEMORY_PER_THREAD) - 1,
|
|
1047
|
+
1
|
|
1048
|
+
);
|
|
1049
|
+
const numThreads = Math.min(maxByCpu, maxByPages, maxByMemory);
|
|
1050
|
+
const source = `auto = min(cpu ${maxByCpu}, pages ${maxByPages}, memory ${maxByMemory})`;
|
|
745
1051
|
if (numThreads <= 1) {
|
|
746
|
-
return 0;
|
|
1052
|
+
return { count: 0, source };
|
|
747
1053
|
}
|
|
748
|
-
|
|
749
|
-
return numThreads;
|
|
1054
|
+
return { count: numThreads, source };
|
|
750
1055
|
}
|
|
751
1056
|
const num = parseInt(threads);
|
|
752
1057
|
if (isNaN(num) || num < 0) {
|
|
753
1058
|
throw new Error(`invalid --threads value: ${threads}`);
|
|
754
1059
|
}
|
|
755
|
-
return num;
|
|
1060
|
+
return { count: num, source: `--threads=${num}` };
|
|
1061
|
+
}
|
|
1062
|
+
function fileSizeBytes(filepath) {
|
|
1063
|
+
return fsExtra.statSync(filepath).size;
|
|
756
1064
|
}
|
|
757
1065
|
function fileSize(filepath) {
|
|
758
|
-
|
|
759
|
-
const bytes = stats.size;
|
|
760
|
-
const k = 1024;
|
|
761
|
-
if (bytes < k) {
|
|
762
|
-
return (bytes / k).toFixed(2) + " kB";
|
|
763
|
-
}
|
|
764
|
-
const units = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
765
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
766
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + units[i];
|
|
1066
|
+
return formatBytes(fileSizeBytes(filepath));
|
|
767
1067
|
}
|
|
768
1068
|
function printFileOutput(fileSize2, outputDir, outputFile) {
|
|
1069
|
+
if (activeLogMode === "quiet") {
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
769
1072
|
const indent = " ".repeat(2);
|
|
770
1073
|
const paddedSize = fileSize2.padStart(9, " ");
|
|
771
1074
|
console.log(
|
|
772
|
-
`${indent}${
|
|
1075
|
+
`${indent}${dim3(paddedSize)} ${dim3(outputDir)}${cyan2(outputFile)}`
|
|
773
1076
|
);
|
|
774
1077
|
}
|
|
775
1078
|
function sanitizeFileName(name) {
|
|
@@ -1021,7 +1324,7 @@ import path11 from "node:path";
|
|
|
1021
1324
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
1022
1325
|
import cookieParser from "cookie-parser";
|
|
1023
1326
|
import { default as express } from "express";
|
|
1024
|
-
import { dim as
|
|
1327
|
+
import { dim as dim6 } from "kleur/colors";
|
|
1025
1328
|
import sirv from "sirv";
|
|
1026
1329
|
import glob3 from "tiny-glob";
|
|
1027
1330
|
|
|
@@ -1306,7 +1609,7 @@ import { spawn as spawn3 } from "node:child_process";
|
|
|
1306
1609
|
import fs6 from "node:fs";
|
|
1307
1610
|
import path9 from "node:path";
|
|
1308
1611
|
import * as readline from "node:readline";
|
|
1309
|
-
import { dim as
|
|
1612
|
+
import { dim as dim4, green as green2, red, yellow } from "kleur/colors";
|
|
1310
1613
|
|
|
1311
1614
|
// src/secrets/manifest.ts
|
|
1312
1615
|
import fs3 from "node:fs";
|
|
@@ -2079,7 +2382,7 @@ function getGitEmail() {
|
|
|
2079
2382
|
}
|
|
2080
2383
|
|
|
2081
2384
|
// src/cli/secrets.ts
|
|
2082
|
-
var BAR =
|
|
2385
|
+
var BAR = dim4("\u2503");
|
|
2083
2386
|
var DEV_SYNC_TIMEOUT_MS = 1e4;
|
|
2084
2387
|
function registerSecretsCommands(program) {
|
|
2085
2388
|
const secrets = program.command("secrets").description(
|
|
@@ -2140,13 +2443,13 @@ async function secretsInit(opts) {
|
|
|
2140
2443
|
await writeManifest(target, manifest);
|
|
2141
2444
|
const addedGitignore = await ensureRootGitignored(rootDir);
|
|
2142
2445
|
console.log();
|
|
2143
|
-
console.log(`${BAR} ${
|
|
2446
|
+
console.log(`${BAR} ${green2("secrets:")} created ${rel(rootDir, target)}`);
|
|
2144
2447
|
if (addedGitignore) {
|
|
2145
|
-
console.log(`${BAR} added ${
|
|
2448
|
+
console.log(`${BAR} added ${dim4(".root/")} to .gitignore`);
|
|
2146
2449
|
}
|
|
2147
2450
|
await warnIfEnvNotIgnored(rootDir);
|
|
2148
2451
|
console.log(
|
|
2149
|
-
`${BAR} ${
|
|
2452
|
+
`${BAR} ${dim4("next: `root secrets set <NAME>` to store a value")}`
|
|
2150
2453
|
);
|
|
2151
2454
|
console.log();
|
|
2152
2455
|
}
|
|
@@ -2158,18 +2461,18 @@ async function secretsSet(name, opts) {
|
|
|
2158
2461
|
throw new Error("no value provided on stdin");
|
|
2159
2462
|
}
|
|
2160
2463
|
await setSecret({ rootDir, manifestFilePath, name, value: secretValue });
|
|
2161
|
-
console.log(`${BAR} ${
|
|
2464
|
+
console.log(`${BAR} ${green2("secrets:")} set ${name}`);
|
|
2162
2465
|
console.log(
|
|
2163
|
-
`${BAR} ${
|
|
2466
|
+
`${BAR} ${dim4(`commit ${rel(rootDir, manifestFilePath)} to share this change`)}`
|
|
2164
2467
|
);
|
|
2165
2468
|
}
|
|
2166
2469
|
async function secretsRm(name, opts) {
|
|
2167
2470
|
const rootDir = process.cwd();
|
|
2168
2471
|
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2169
2472
|
await removeSecret({ rootDir, manifestFilePath, name });
|
|
2170
|
-
console.log(`${BAR} ${
|
|
2473
|
+
console.log(`${BAR} ${green2("secrets:")} removed ${name}`);
|
|
2171
2474
|
console.log(
|
|
2172
|
-
`${BAR} ${
|
|
2475
|
+
`${BAR} ${dim4(`commit ${rel(rootDir, manifestFilePath)} to share this change`)}`
|
|
2173
2476
|
);
|
|
2174
2477
|
}
|
|
2175
2478
|
async function secretsPush(opts) {
|
|
@@ -2184,7 +2487,7 @@ async function secretsPush(opts) {
|
|
|
2184
2487
|
}
|
|
2185
2488
|
console.log();
|
|
2186
2489
|
console.log(
|
|
2187
|
-
`${BAR} ${
|
|
2490
|
+
`${BAR} ${green2("secrets:")} push ${names.length} value(s) from .env to "${gsmKey}":`
|
|
2188
2491
|
);
|
|
2189
2492
|
for (const name of names) {
|
|
2190
2493
|
console.log(`${BAR} ${name}`);
|
|
@@ -2227,13 +2530,13 @@ async function secretsStatus() {
|
|
|
2227
2530
|
}
|
|
2228
2531
|
console.log();
|
|
2229
2532
|
console.log(
|
|
2230
|
-
`${BAR} ${
|
|
2533
|
+
`${BAR} ${green2("secrets:")} ${resolved.site.gsmKey} ${dim4(`(${resolved.site.gcpProjectId})`)}`
|
|
2231
2534
|
);
|
|
2232
2535
|
if (resolved.shared) {
|
|
2233
|
-
console.log(`${BAR} imports ${
|
|
2536
|
+
console.log(`${BAR} imports ${dim4(resolved.shared.gsmKey)}`);
|
|
2234
2537
|
}
|
|
2235
2538
|
if (keys.length === 0) {
|
|
2236
|
-
console.log(`${BAR} ${
|
|
2539
|
+
console.log(`${BAR} ${dim4("no managed keys yet")}`);
|
|
2237
2540
|
}
|
|
2238
2541
|
for (const key of keys) {
|
|
2239
2542
|
console.log(`${BAR} ${formatStatus(key)}`);
|
|
@@ -2261,15 +2564,15 @@ async function syncSecretsOnDev(rootDir) {
|
|
|
2261
2564
|
function formatStatus(key) {
|
|
2262
2565
|
switch (key.kind) {
|
|
2263
2566
|
case "in-sync":
|
|
2264
|
-
return `${
|
|
2567
|
+
return `${green2("\u2713")} ${key.name}`;
|
|
2265
2568
|
case "remote-newer":
|
|
2266
|
-
return `${yellow("\u2193")} ${key.name} ${
|
|
2569
|
+
return `${yellow("\u2193")} ${key.name} ${dim4("(update available \u2014 run `root secrets sync`)")}`;
|
|
2267
2570
|
case "locally-edited":
|
|
2268
|
-
return `${
|
|
2571
|
+
return `${dim4("\u2022")} ${key.name} ${dim4("(locally edited)")}`;
|
|
2269
2572
|
case "conflict":
|
|
2270
|
-
return `${yellow("!")} ${key.name} ${
|
|
2573
|
+
return `${yellow("!")} ${key.name} ${dim4("(changed locally & remotely)")}`;
|
|
2271
2574
|
case "not-pulled":
|
|
2272
|
-
return `${yellow("\u2193")} ${key.name} ${
|
|
2575
|
+
return `${yellow("\u2193")} ${key.name} ${dim4("(not pulled yet)")}`;
|
|
2273
2576
|
default:
|
|
2274
2577
|
return key.name;
|
|
2275
2578
|
}
|
|
@@ -2281,13 +2584,13 @@ function printSyncSummary(result, opts = {}) {
|
|
|
2281
2584
|
}
|
|
2282
2585
|
const parts = [];
|
|
2283
2586
|
if (result.changed.length) {
|
|
2284
|
-
parts.push(
|
|
2587
|
+
parts.push(green2(`${result.changed.length} updated`));
|
|
2285
2588
|
}
|
|
2286
2589
|
if (result.removed.length) {
|
|
2287
2590
|
parts.push(`${result.removed.length} removed`);
|
|
2288
2591
|
}
|
|
2289
2592
|
if (result.kept.length) {
|
|
2290
|
-
parts.push(
|
|
2593
|
+
parts.push(dim4(`${result.kept.length} local`));
|
|
2291
2594
|
}
|
|
2292
2595
|
if (result.conflicts.length) {
|
|
2293
2596
|
parts.push(yellow(`${result.conflicts.length} conflict`));
|
|
@@ -2297,22 +2600,22 @@ function printSyncSummary(result, opts = {}) {
|
|
|
2297
2600
|
}
|
|
2298
2601
|
console.log();
|
|
2299
2602
|
console.log(
|
|
2300
|
-
`${BAR} ${
|
|
2603
|
+
`${BAR} ${green2("secrets:")} ${parts.length ? parts.join(", ") : "up to date"}`
|
|
2301
2604
|
);
|
|
2302
2605
|
for (const name of result.changed) {
|
|
2303
|
-
console.log(`${BAR} ${
|
|
2606
|
+
console.log(`${BAR} ${green2("+")} ${name}`);
|
|
2304
2607
|
}
|
|
2305
2608
|
for (const name of result.removed) {
|
|
2306
|
-
console.log(`${BAR} ${
|
|
2609
|
+
console.log(`${BAR} ${dim4("-")} ${name} ${dim4("(removed)")}`);
|
|
2307
2610
|
}
|
|
2308
2611
|
for (const name of result.overwritten) {
|
|
2309
2612
|
console.log(
|
|
2310
|
-
`${BAR} ${yellow("!")} ${name} ${
|
|
2613
|
+
`${BAR} ${yellow("!")} ${name} ${dim4("(local value replaced)")}`
|
|
2311
2614
|
);
|
|
2312
2615
|
}
|
|
2313
2616
|
for (const name of result.conflicts) {
|
|
2314
2617
|
console.log(
|
|
2315
|
-
`${BAR} ${yellow("!")} ${name} ${
|
|
2618
|
+
`${BAR} ${yellow("!")} ${name} ${dim4(
|
|
2316
2619
|
"(changed locally & remotely; keeping yours \u2014 `root secrets pull` to take remote)"
|
|
2317
2620
|
)}`
|
|
2318
2621
|
);
|
|
@@ -2334,18 +2637,18 @@ function printPushResult(result, rootDir, manifestFilePath) {
|
|
|
2334
2637
|
console.log(`${BAR} ${yellow("secrets:")} nothing to push`);
|
|
2335
2638
|
} else {
|
|
2336
2639
|
console.log(
|
|
2337
|
-
`${BAR} ${
|
|
2640
|
+
`${BAR} ${green2("secrets:")} pushed ${result.pushed.length} value(s) to "${result.gsmKey}"`
|
|
2338
2641
|
);
|
|
2339
2642
|
for (const name of result.pushed) {
|
|
2340
|
-
console.log(`${BAR} ${
|
|
2643
|
+
console.log(`${BAR} ${green2("+")} ${name}`);
|
|
2341
2644
|
}
|
|
2342
2645
|
}
|
|
2343
2646
|
for (const skip of result.skipped) {
|
|
2344
|
-
console.log(`${BAR} ${
|
|
2647
|
+
console.log(`${BAR} ${dim4("-")} ${skip.name} ${dim4(`(${skip.reason})`)}`);
|
|
2345
2648
|
}
|
|
2346
2649
|
if (result.pushed.length > 0) {
|
|
2347
2650
|
console.log(
|
|
2348
|
-
`${BAR} ${
|
|
2651
|
+
`${BAR} ${dim4(`commit ${rel(rootDir, manifestFilePath)} to share`)}`
|
|
2349
2652
|
);
|
|
2350
2653
|
}
|
|
2351
2654
|
console.log();
|
|
@@ -2371,7 +2674,7 @@ async function warnIfEnvNotIgnored(rootDir) {
|
|
|
2371
2674
|
const ignored = await isPathGitIgnored(rootDir, ".env");
|
|
2372
2675
|
if (ignored === false) {
|
|
2373
2676
|
console.log(
|
|
2374
|
-
`${BAR} ${yellow("warning:")} ${
|
|
2677
|
+
`${BAR} ${yellow("warning:")} ${dim4(".env is not git-ignored \u2014 add it to .gitignore")}`
|
|
2375
2678
|
);
|
|
2376
2679
|
}
|
|
2377
2680
|
}
|
|
@@ -2512,7 +2815,7 @@ import os2 from "node:os";
|
|
|
2512
2815
|
import path10 from "node:path";
|
|
2513
2816
|
|
|
2514
2817
|
// src/cli/startup/check-version.ts
|
|
2515
|
-
import { dim as
|
|
2818
|
+
import { dim as dim5, green as green3, yellow as yellow2 } from "kleur/colors";
|
|
2516
2819
|
var PACKAGE_NAME = "@blinkk/root";
|
|
2517
2820
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
2518
2821
|
var REGISTRY_TIMEOUT_MS = 3e3;
|
|
@@ -2583,10 +2886,10 @@ function parseVersion(version) {
|
|
|
2583
2886
|
return [toInt(parts[0]), toInt(parts[1]), toInt(parts[2])];
|
|
2584
2887
|
}
|
|
2585
2888
|
function printUpdateNotice(current, latest) {
|
|
2586
|
-
const bar =
|
|
2889
|
+
const bar = dim5("\u2503");
|
|
2587
2890
|
const label = yellow2(`Update available for ${PACKAGE_NAME}:`);
|
|
2588
2891
|
console.log();
|
|
2589
|
-
console.log(`${bar} ${label} ${
|
|
2892
|
+
console.log(`${bar} ${label} ${dim5(current)} \u2192 ${green3(latest)}`);
|
|
2590
2893
|
console.log();
|
|
2591
2894
|
}
|
|
2592
2895
|
|
|
@@ -2665,12 +2968,12 @@ async function dev(rootProjectDir, options) {
|
|
|
2665
2968
|
const basePath = rootConfig.base || "";
|
|
2666
2969
|
const homePagePath = rootConfig.server?.homePagePath || basePath;
|
|
2667
2970
|
console.log();
|
|
2668
|
-
console.log(`${
|
|
2669
|
-
console.log(`${
|
|
2971
|
+
console.log(`${dim6("\u2503")} project: ${rootDir}`);
|
|
2972
|
+
console.log(`${dim6("\u2503")} server: http://${host}:${port}${homePagePath}`);
|
|
2670
2973
|
if (testCmsEnabled(rootConfig)) {
|
|
2671
|
-
console.log(`${
|
|
2974
|
+
console.log(`${dim6("\u2503")} cms: http://${host}:${port}/cms/`);
|
|
2672
2975
|
}
|
|
2673
|
-
console.log(`${
|
|
2976
|
+
console.log(`${dim6("\u2503")} mode: development`);
|
|
2674
2977
|
console.log();
|
|
2675
2978
|
currentServer = server.listen(port, host);
|
|
2676
2979
|
const rootConfigDependencies = server.get(
|
|
@@ -2685,7 +2988,7 @@ async function dev(rootProjectDir, options) {
|
|
|
2685
2988
|
if (dependencies.includes(file)) {
|
|
2686
2989
|
console.log(
|
|
2687
2990
|
`
|
|
2688
|
-
${
|
|
2991
|
+
${dim6("\u2503")} root.config.ts changed. restarting server...`
|
|
2689
2992
|
);
|
|
2690
2993
|
await restart();
|
|
2691
2994
|
}
|
|
@@ -3080,7 +3383,7 @@ function testManagedVersion(service, appInfo, prefix) {
|
|
|
3080
3383
|
import path12 from "node:path";
|
|
3081
3384
|
import cookieParser2 from "cookie-parser";
|
|
3082
3385
|
import { default as express2 } from "express";
|
|
3083
|
-
import { dim as
|
|
3386
|
+
import { dim as dim7 } from "kleur/colors";
|
|
3084
3387
|
import sirv2 from "sirv";
|
|
3085
3388
|
async function preview(rootProjectDir, options) {
|
|
3086
3389
|
process.env.NODE_ENV = "development";
|
|
@@ -3089,9 +3392,9 @@ async function preview(rootProjectDir, options) {
|
|
|
3089
3392
|
const port = parseInt(process.env.PORT || "4007");
|
|
3090
3393
|
const host = options?.host || "localhost";
|
|
3091
3394
|
console.log();
|
|
3092
|
-
console.log(`${
|
|
3093
|
-
console.log(`${
|
|
3094
|
-
console.log(`${
|
|
3395
|
+
console.log(`${dim7("\u2503")} project: ${rootDir}`);
|
|
3396
|
+
console.log(`${dim7("\u2503")} server: http://${host}:${port}`);
|
|
3397
|
+
console.log(`${dim7("\u2503")} mode: preview`);
|
|
3095
3398
|
console.log();
|
|
3096
3399
|
server.listen(port, host);
|
|
3097
3400
|
}
|
|
@@ -3226,7 +3529,7 @@ function rootPreviewServer500Middleware() {
|
|
|
3226
3529
|
import path13 from "node:path";
|
|
3227
3530
|
import cookieParser3 from "cookie-parser";
|
|
3228
3531
|
import { default as express3 } from "express";
|
|
3229
|
-
import { dim as
|
|
3532
|
+
import { dim as dim8 } from "kleur/colors";
|
|
3230
3533
|
import sirv3 from "sirv";
|
|
3231
3534
|
async function start(rootProjectDir, options) {
|
|
3232
3535
|
process.env.NODE_ENV = "production";
|
|
@@ -3235,9 +3538,9 @@ async function start(rootProjectDir, options) {
|
|
|
3235
3538
|
const port = parseInt(process.env.PORT || "4007");
|
|
3236
3539
|
const host = options?.host || "localhost";
|
|
3237
3540
|
console.log();
|
|
3238
|
-
console.log(`${
|
|
3239
|
-
console.log(`${
|
|
3240
|
-
console.log(`${
|
|
3541
|
+
console.log(`${dim8("\u2503")} project: ${rootDir}`);
|
|
3542
|
+
console.log(`${dim8("\u2503")} server: http://${host}:${port}`);
|
|
3543
|
+
console.log(`${dim8("\u2503")} mode: production`);
|
|
3241
3544
|
console.log();
|
|
3242
3545
|
server.listen(port, host);
|
|
3243
3546
|
}
|
|
@@ -3403,7 +3706,14 @@ var CliRunner = class {
|
|
|
3403
3706
|
"--filter <urlPathRegex>",
|
|
3404
3707
|
'builds the url paths that match the given regex, e.g. "/products/.*"',
|
|
3405
3708
|
""
|
|
3406
|
-
).
|
|
3709
|
+
).addOption(
|
|
3710
|
+
new Option(
|
|
3711
|
+
"--log <mode>",
|
|
3712
|
+
'build log output: "progress" (default) shows a progress indicator and a final summary, "verbose" prints one line per output file, "quiet" prints only the final summary'
|
|
3713
|
+
).choices(["progress", "verbose", "quiet"])
|
|
3714
|
+
).action(
|
|
3715
|
+
(rootProjectDir, options, cmd) => build(rootProjectDir, cmd.optsWithGlobals())
|
|
3716
|
+
);
|
|
3407
3717
|
program.command("codegen [type] [name]").description("generates boilerplate code").option("--out <outdir>", "output dir").action(codegen);
|
|
3408
3718
|
program.command("create-package [path]").alias("package").description(
|
|
3409
3719
|
"creates a standalone npm package for deployment to various hosting services"
|
|
@@ -3465,4 +3775,4 @@ export {
|
|
|
3465
3775
|
createProdServer,
|
|
3466
3776
|
CliRunner
|
|
3467
3777
|
};
|
|
3468
|
-
//# sourceMappingURL=chunk-
|
|
3778
|
+
//# sourceMappingURL=chunk-WGQNQPWG.js.map
|