@blinkk/root 3.0.6 → 3.1.1
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/build-worker.js +108 -0
- package/dist/build-worker.js.map +7 -0
- package/dist/chunk-3PWR4F2R.js +77 -0
- package/dist/chunk-3PWR4F2R.js.map +7 -0
- package/dist/{chunk-3EFECH2D.js → chunk-E4F6CMO3.js} +439 -553
- package/dist/chunk-E4F6CMO3.js.map +7 -0
- package/dist/{chunk-7HK6F5RQ.js → chunk-I3RCAIW7.js} +1 -75
- package/dist/chunk-I3RCAIW7.js.map +7 -0
- package/dist/chunk-KHO3HMX6.js +291 -0
- package/dist/chunk-KHO3HMX6.js.map +7 -0
- package/dist/chunk-M3E4RKS7.js +374 -0
- package/dist/chunk-M3E4RKS7.js.map +7 -0
- package/dist/{chunk-6NBKAR5Y.js → chunk-TM6QRBGS.js} +31 -1
- package/dist/chunk-TM6QRBGS.js.map +7 -0
- package/dist/chunk-WX62JK5E.js +81 -0
- package/dist/chunk-WX62JK5E.js.map +7 -0
- package/dist/{chunk-7PSEEE6C.js → chunk-YU22SAIG.js} +31 -317
- package/dist/chunk-YU22SAIG.js.map +7 -0
- package/dist/cli/build-page.d.ts +57 -0
- package/dist/cli/build-worker-pool.d.ts +46 -0
- package/dist/cli/build-worker.d.ts +4 -0
- package/dist/cli/build.d.ts +6 -0
- package/dist/cli.js +8 -4
- package/dist/core/security.d.ts +14 -0
- package/dist/functions.js +8 -4
- package/dist/functions.js.map +1 -1
- package/dist/middleware/common.d.ts +18 -0
- package/dist/middleware/compression.d.ts +12 -0
- package/dist/middleware/middleware.d.ts +1 -0
- package/dist/middleware.js +6 -1
- package/dist/node.js +7 -5
- package/dist/render/render.d.ts +15 -9
- package/dist/render.js +42 -95
- package/dist/render.js.map +2 -2
- package/package.json +2 -2
- package/dist/chunk-3EFECH2D.js.map +0 -7
- package/dist/chunk-6NBKAR5Y.js.map +0 -7
- package/dist/chunk-7HK6F5RQ.js.map +0 -7
- package/dist/chunk-7PSEEE6C.js.map +0 -7
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "./chunk-
|
|
2
|
+
collectPods,
|
|
3
|
+
createViteServer,
|
|
4
|
+
preactToRootJsxPlugin,
|
|
5
|
+
rootPodsVitePlugin
|
|
6
|
+
} from "./chunk-YU22SAIG.js";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
RouteTrie
|
|
9
|
+
} from "./chunk-I3RCAIW7.js";
|
|
10
|
+
import {
|
|
11
|
+
BuildAssetMap,
|
|
12
|
+
ElementGraph,
|
|
13
|
+
buildPage,
|
|
14
|
+
getElements,
|
|
15
|
+
getElementsDirs
|
|
16
|
+
} from "./chunk-M3E4RKS7.js";
|
|
13
17
|
import {
|
|
14
18
|
bundleRootConfig,
|
|
15
|
-
collectPods,
|
|
16
19
|
copyDir,
|
|
17
20
|
copyGlob,
|
|
18
|
-
createViteServer,
|
|
19
21
|
dirExists,
|
|
20
22
|
directoryContains,
|
|
21
23
|
fileExists,
|
|
@@ -27,144 +29,35 @@ import {
|
|
|
27
29
|
loadRootConfig,
|
|
28
30
|
loadRootConfigWithDeps,
|
|
29
31
|
makeDir,
|
|
30
|
-
preactToRootJsxPlugin,
|
|
31
32
|
rmDir,
|
|
32
|
-
rootPodsVitePlugin,
|
|
33
33
|
writeFile,
|
|
34
34
|
writeJson
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-KHO3HMX6.js";
|
|
36
36
|
import {
|
|
37
37
|
configureServerPlugins,
|
|
38
38
|
getVitePlugins
|
|
39
39
|
} from "./chunk-XSNCF7WU.js";
|
|
40
|
+
import {
|
|
41
|
+
compressionMiddleware,
|
|
42
|
+
headersMiddleware,
|
|
43
|
+
rootProjectMiddleware,
|
|
44
|
+
securityHeadersMiddleware,
|
|
45
|
+
sessionMiddleware,
|
|
46
|
+
trailingSlashMiddleware
|
|
47
|
+
} from "./chunk-TM6QRBGS.js";
|
|
40
48
|
|
|
41
49
|
// src/cli/cli.ts
|
|
42
50
|
import { Command, InvalidArgumentError } from "commander";
|
|
43
51
|
import { bgGreen, black } from "kleur/colors";
|
|
44
52
|
|
|
45
53
|
// src/cli/build.ts
|
|
46
|
-
import
|
|
47
|
-
import
|
|
54
|
+
import os from "node:os";
|
|
55
|
+
import path2 from "node:path";
|
|
56
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
48
57
|
import fsExtra from "fs-extra";
|
|
49
58
|
import { dim as dim2, cyan } from "kleur/colors";
|
|
50
|
-
import glob2 from "tiny-glob";
|
|
51
|
-
import { build as viteBuild } from "vite";
|
|
52
|
-
|
|
53
|
-
// src/node/element-graph.ts
|
|
54
|
-
import fs from "node:fs";
|
|
55
|
-
import path from "node:path";
|
|
56
59
|
import glob from "tiny-glob";
|
|
57
|
-
import {
|
|
58
|
-
var ElementGraph = class _ElementGraph {
|
|
59
|
-
/**
|
|
60
|
-
* Element tagName => sourceFile.
|
|
61
|
-
*/
|
|
62
|
-
sourceFiles = {};
|
|
63
|
-
/**
|
|
64
|
-
* Element tagName => set of element tagName dependencies.
|
|
65
|
-
*/
|
|
66
|
-
deps = {};
|
|
67
|
-
constructor(sourceFiles) {
|
|
68
|
-
this.sourceFiles = sourceFiles;
|
|
69
|
-
}
|
|
70
|
-
toJson() {
|
|
71
|
-
for (const tagName in this.sourceFiles) {
|
|
72
|
-
this.deps[tagName] ??= this.parseDepsFromSource(tagName);
|
|
73
|
-
}
|
|
74
|
-
return {
|
|
75
|
-
sourceFiles: this.sourceFiles,
|
|
76
|
-
deps: this.deps
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
static fromJson(data) {
|
|
80
|
-
const graph = new _ElementGraph(data.sourceFiles);
|
|
81
|
-
graph.deps = data.deps;
|
|
82
|
-
return graph;
|
|
83
|
-
}
|
|
84
|
-
getDeps(tagName, visited) {
|
|
85
|
-
visited ??= /* @__PURE__ */ new Set();
|
|
86
|
-
if (visited.has(tagName)) {
|
|
87
|
-
return [];
|
|
88
|
-
}
|
|
89
|
-
visited.add(tagName);
|
|
90
|
-
this.deps[tagName] ??= this.parseDepsFromSource(tagName);
|
|
91
|
-
const deps = new Set(this.deps[tagName]);
|
|
92
|
-
for (const depTagName of this.deps[tagName]) {
|
|
93
|
-
for (const childDep of this.getDeps(depTagName, visited)) {
|
|
94
|
-
deps.add(childDep);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return Array.from(deps);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Parses an element's source file for usage of other custom elements.
|
|
101
|
-
*/
|
|
102
|
-
parseDepsFromSource(tagName) {
|
|
103
|
-
const srcFile = this.sourceFiles[tagName];
|
|
104
|
-
if (!srcFile) {
|
|
105
|
-
throw new Error(`could not find file path for tagName <${tagName}>`);
|
|
106
|
-
}
|
|
107
|
-
const src = fs.readFileSync(srcFile.filePath, "utf-8");
|
|
108
|
-
const tagNames = parseTagNames(src);
|
|
109
|
-
const deps = /* @__PURE__ */ new Set();
|
|
110
|
-
for (const depTagName of tagNames) {
|
|
111
|
-
if (depTagName !== tagName && depTagName in this.sourceFiles) {
|
|
112
|
-
deps.add(depTagName);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return Array.from(deps);
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
async function getElements(rootConfig, pods) {
|
|
119
|
-
const rootDir = rootConfig.rootDir;
|
|
120
|
-
const elementsDirs = getElementsDirs(rootConfig, pods);
|
|
121
|
-
const excludePatterns = rootConfig.elements?.exclude || [];
|
|
122
|
-
const excludeElement = (moduleId) => {
|
|
123
|
-
return excludePatterns.some((pattern) => Boolean(moduleId.match(pattern)));
|
|
124
|
-
};
|
|
125
|
-
const elementFilePaths = {};
|
|
126
|
-
for (const dirPath of elementsDirs) {
|
|
127
|
-
if (await isDirectory(dirPath)) {
|
|
128
|
-
const files = await glob("**/*", { cwd: dirPath });
|
|
129
|
-
files.forEach((file) => {
|
|
130
|
-
const parts = path.parse(file);
|
|
131
|
-
if (isJsFile(parts.base) && isValidTagName(parts.name)) {
|
|
132
|
-
const tagName = parts.name;
|
|
133
|
-
const filePath = path.join(dirPath, file);
|
|
134
|
-
const relPath = path.relative(rootDir, filePath);
|
|
135
|
-
if (!excludeElement(relPath)) {
|
|
136
|
-
elementFilePaths[tagName] = { filePath, relPath };
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
const graph = new ElementGraph(elementFilePaths);
|
|
143
|
-
return graph;
|
|
144
|
-
}
|
|
145
|
-
function getElementsDirs(rootConfig, pods) {
|
|
146
|
-
const rootDir = rootConfig.rootDir;
|
|
147
|
-
const workspaceRoot = searchForWorkspaceRoot(rootDir);
|
|
148
|
-
const elementsDirs = [path.join(rootDir, "elements")];
|
|
149
|
-
const elementsInclude = rootConfig.elements?.include || [];
|
|
150
|
-
for (const dirPath of elementsInclude) {
|
|
151
|
-
const elementsDir = path.resolve(rootDir, dirPath);
|
|
152
|
-
if (!directoryContains(rootDir, elementsDir)) {
|
|
153
|
-
throw new Error(
|
|
154
|
-
`the elements dir (${dirPath}) should be within the project's workspace (${workspaceRoot})`
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
elementsDirs.push(elementsDir);
|
|
158
|
-
}
|
|
159
|
-
if (pods) {
|
|
160
|
-
for (const pod of pods) {
|
|
161
|
-
for (const dir of pod.elementsDirs) {
|
|
162
|
-
elementsDirs.push(dir);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return elementsDirs;
|
|
167
|
-
}
|
|
60
|
+
import { build as viteBuild } from "vite";
|
|
168
61
|
|
|
169
62
|
// src/node/vite-plugin-prune-empty-chunks.ts
|
|
170
63
|
import { dim } from "kleur/colors";
|
|
@@ -231,191 +124,6 @@ function removeSideEffectImport(code, fileName) {
|
|
|
231
124
|
return code.replace(re, "");
|
|
232
125
|
}
|
|
233
126
|
|
|
234
|
-
// src/render/asset-map/build-asset-map.ts
|
|
235
|
-
import fs2 from "node:fs";
|
|
236
|
-
import path2 from "node:path";
|
|
237
|
-
var BuildAssetMap = class _BuildAssetMap {
|
|
238
|
-
rootConfig;
|
|
239
|
-
srcToAsset;
|
|
240
|
-
constructor(rootConfig) {
|
|
241
|
-
this.rootConfig = rootConfig;
|
|
242
|
-
this.srcToAsset = /* @__PURE__ */ new Map();
|
|
243
|
-
}
|
|
244
|
-
async get(src) {
|
|
245
|
-
const asset = this.srcToAsset.get(src);
|
|
246
|
-
if (asset) {
|
|
247
|
-
return asset;
|
|
248
|
-
}
|
|
249
|
-
const realSrc = realPathRelativeTo(this.rootConfig.rootDir, src);
|
|
250
|
-
if (realSrc !== src) {
|
|
251
|
-
const asset2 = this.srcToAsset.get(realSrc);
|
|
252
|
-
if (asset2) {
|
|
253
|
-
return asset2;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
console.log(`could not find build asset: ${src}`);
|
|
257
|
-
return null;
|
|
258
|
-
}
|
|
259
|
-
add(asset) {
|
|
260
|
-
this.srcToAsset.set(asset.src, asset);
|
|
261
|
-
}
|
|
262
|
-
toJson() {
|
|
263
|
-
const result = {};
|
|
264
|
-
for (const src of this.srcToAsset.keys()) {
|
|
265
|
-
result[src] = this.srcToAsset.get(src).toJson();
|
|
266
|
-
}
|
|
267
|
-
return result;
|
|
268
|
-
}
|
|
269
|
-
static fromViteManifest(rootConfig, clientManifest, elementsGraph, podRoutes = []) {
|
|
270
|
-
const assetMap = new _BuildAssetMap(rootConfig);
|
|
271
|
-
const elementFiles = /* @__PURE__ */ new Set();
|
|
272
|
-
Object.values(elementsGraph.sourceFiles).forEach((elementSource) => {
|
|
273
|
-
elementFiles.add(elementSource.relPath);
|
|
274
|
-
const realSrc = realPathRelativeTo(
|
|
275
|
-
rootConfig.rootDir,
|
|
276
|
-
elementSource.relPath
|
|
277
|
-
);
|
|
278
|
-
if (realSrc !== elementSource.filePath) {
|
|
279
|
-
elementFiles.add(realSrc);
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
Object.keys(clientManifest).forEach((manifestKey) => {
|
|
283
|
-
const src = manifestKey;
|
|
284
|
-
const manifestChunk = clientManifest[manifestKey];
|
|
285
|
-
const isElement = elementFiles.has(src);
|
|
286
|
-
const assetUrl = src.startsWith("routes/") && isJsFile(src) ? "" : `/${manifestChunk.file}`;
|
|
287
|
-
const assetData = {
|
|
288
|
-
src,
|
|
289
|
-
assetUrl,
|
|
290
|
-
importedModules: manifestChunk.imports || [],
|
|
291
|
-
importedCss: (manifestChunk.css || []).map((relPath) => `/${relPath}`),
|
|
292
|
-
isElement
|
|
293
|
-
};
|
|
294
|
-
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
295
|
-
});
|
|
296
|
-
podRoutes.forEach((podRoute) => {
|
|
297
|
-
if (assetMap.srcToAsset.has(podRoute.src)) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
const relPath = path2.relative(rootConfig.rootDir, podRoute.filePath).replace(/\\/g, "/");
|
|
301
|
-
const realPath = realPathRelativeTo(rootConfig.rootDir, relPath).replace(
|
|
302
|
-
/\\/g,
|
|
303
|
-
"/"
|
|
304
|
-
);
|
|
305
|
-
const candidateKeys = [relPath, realPath];
|
|
306
|
-
for (const key of candidateKeys) {
|
|
307
|
-
const asset = assetMap.srcToAsset.get(key);
|
|
308
|
-
if (asset) {
|
|
309
|
-
assetMap.add(
|
|
310
|
-
new BuildAsset(assetMap, {
|
|
311
|
-
...asset.toJson(),
|
|
312
|
-
src: podRoute.src,
|
|
313
|
-
assetUrl: ""
|
|
314
|
-
})
|
|
315
|
-
);
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
return assetMap;
|
|
321
|
-
}
|
|
322
|
-
static fromRootManifest(rootConfig, rootManifest) {
|
|
323
|
-
const assetMap = new _BuildAssetMap(rootConfig);
|
|
324
|
-
Object.keys(rootManifest).forEach((moduleId) => {
|
|
325
|
-
const assetData = rootManifest[moduleId];
|
|
326
|
-
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
327
|
-
});
|
|
328
|
-
return assetMap;
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
function realPathRelativeTo(rootDir, src) {
|
|
332
|
-
const fullPath = path2.resolve(rootDir, src);
|
|
333
|
-
if (!fs2.existsSync(fullPath)) {
|
|
334
|
-
return src;
|
|
335
|
-
}
|
|
336
|
-
const realpath = fs2.realpathSync(path2.resolve(rootDir, src));
|
|
337
|
-
return path2.relative(rootDir, realpath);
|
|
338
|
-
}
|
|
339
|
-
var BuildAsset = class {
|
|
340
|
-
src;
|
|
341
|
-
assetUrl;
|
|
342
|
-
assetMap;
|
|
343
|
-
importedModules;
|
|
344
|
-
importedCss;
|
|
345
|
-
isElement;
|
|
346
|
-
constructor(assetMap, assetData) {
|
|
347
|
-
this.assetMap = assetMap;
|
|
348
|
-
this.src = assetData.src;
|
|
349
|
-
this.assetUrl = assetData.assetUrl;
|
|
350
|
-
this.importedModules = assetData.importedModules;
|
|
351
|
-
this.importedCss = assetData.importedCss;
|
|
352
|
-
this.isElement = assetData.isElement;
|
|
353
|
-
}
|
|
354
|
-
async getCssDeps() {
|
|
355
|
-
const visited = /* @__PURE__ */ new Set();
|
|
356
|
-
const deps = /* @__PURE__ */ new Set();
|
|
357
|
-
await this.collectCss(this, deps, visited);
|
|
358
|
-
return Array.from(deps);
|
|
359
|
-
}
|
|
360
|
-
async getJsDeps() {
|
|
361
|
-
const visited = /* @__PURE__ */ new Set();
|
|
362
|
-
const deps = /* @__PURE__ */ new Set();
|
|
363
|
-
await this.collectJs(this, deps, visited);
|
|
364
|
-
return Array.from(deps);
|
|
365
|
-
}
|
|
366
|
-
async collectJs(asset, urls, visited) {
|
|
367
|
-
if (!asset) {
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
if (!asset.src) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
if (visited.has(asset.src)) {
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
visited.add(asset.src);
|
|
377
|
-
if (asset.isElement) {
|
|
378
|
-
urls.add(asset.assetUrl);
|
|
379
|
-
}
|
|
380
|
-
await Promise.all(
|
|
381
|
-
asset.importedModules.map(async (src) => {
|
|
382
|
-
const importedAsset = await this.assetMap.get(src);
|
|
383
|
-
this.collectJs(importedAsset, urls, visited);
|
|
384
|
-
})
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
async collectCss(asset, urls, visited) {
|
|
388
|
-
if (!asset) {
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
if (!asset.src) {
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
if (visited.has(asset.src)) {
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
visited.add(asset.src);
|
|
398
|
-
if (asset.importedCss) {
|
|
399
|
-
asset.importedCss.forEach((cssUrl) => urls.add(cssUrl));
|
|
400
|
-
}
|
|
401
|
-
await Promise.all(
|
|
402
|
-
asset.importedModules.map(async (moduleId) => {
|
|
403
|
-
const importedAsset = await this.assetMap.get(moduleId);
|
|
404
|
-
this.collectCss(importedAsset, urls, visited);
|
|
405
|
-
})
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
toJson() {
|
|
409
|
-
return {
|
|
410
|
-
src: this.src,
|
|
411
|
-
assetUrl: this.assetUrl,
|
|
412
|
-
importedModules: this.importedModules,
|
|
413
|
-
importedCss: this.importedCss,
|
|
414
|
-
isElement: this.isElement
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
|
|
419
127
|
// src/utils/batch.ts
|
|
420
128
|
async function batchAsyncCalls(data, concurrency, asyncFunction) {
|
|
421
129
|
const result = new Array(data.length);
|
|
@@ -434,14 +142,144 @@ async function batchAsyncCalls(data, concurrency, asyncFunction) {
|
|
|
434
142
|
return result;
|
|
435
143
|
}
|
|
436
144
|
|
|
145
|
+
// src/cli/build-worker-pool.ts
|
|
146
|
+
import path from "node:path";
|
|
147
|
+
import { fileURLToPath } from "node:url";
|
|
148
|
+
import { Worker } from "node:worker_threads";
|
|
149
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
150
|
+
var BuildPageError = class extends Error {
|
|
151
|
+
urlPath;
|
|
152
|
+
params;
|
|
153
|
+
routeSrc;
|
|
154
|
+
workerError;
|
|
155
|
+
constructor(urlPath, params, routeSrc, workerError) {
|
|
156
|
+
super(
|
|
157
|
+
`BuildError: ${urlPath} (${routeSrc || "unknown route"}) failed to build.`
|
|
158
|
+
);
|
|
159
|
+
this.urlPath = urlPath;
|
|
160
|
+
this.params = params;
|
|
161
|
+
this.routeSrc = routeSrc;
|
|
162
|
+
this.workerError = workerError;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
var BuildWorker = class {
|
|
166
|
+
worker;
|
|
167
|
+
pool;
|
|
168
|
+
concurrency;
|
|
169
|
+
inFlight = /* @__PURE__ */ new Map();
|
|
170
|
+
isReady = false;
|
|
171
|
+
ready;
|
|
172
|
+
constructor(pool, options) {
|
|
173
|
+
this.pool = pool;
|
|
174
|
+
this.concurrency = options.workerConcurrency;
|
|
175
|
+
this.worker = new Worker(path.resolve(__dirname, "./build-worker.js"), {
|
|
176
|
+
workerData: { rootDir: options.rootDir, mode: options.mode }
|
|
177
|
+
});
|
|
178
|
+
let onReady;
|
|
179
|
+
let onFailed;
|
|
180
|
+
this.ready = new Promise((resolve, reject) => {
|
|
181
|
+
onReady = resolve;
|
|
182
|
+
onFailed = reject;
|
|
183
|
+
});
|
|
184
|
+
this.worker.on("message", (msg) => {
|
|
185
|
+
if (msg.type === "ready") {
|
|
186
|
+
this.isReady = true;
|
|
187
|
+
onReady();
|
|
188
|
+
this.next();
|
|
189
|
+
} else if (msg.type === "result") {
|
|
190
|
+
const pending = this.inFlight.get(msg.id);
|
|
191
|
+
this.inFlight.delete(msg.id);
|
|
192
|
+
pending?.resolve(msg.result);
|
|
193
|
+
this.next();
|
|
194
|
+
} else if (msg.type === "error") {
|
|
195
|
+
const pending = this.inFlight.get(msg.id);
|
|
196
|
+
this.inFlight.delete(msg.id);
|
|
197
|
+
pending?.reject(
|
|
198
|
+
new BuildPageError(msg.urlPath, msg.params, msg.routeSrc, msg.error)
|
|
199
|
+
);
|
|
200
|
+
this.next();
|
|
201
|
+
} else if (msg.type === "fatal") {
|
|
202
|
+
const err = new Error(`build worker failed: ${msg.error}`);
|
|
203
|
+
onFailed(err);
|
|
204
|
+
this.failAll(err);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
this.worker.on("error", (err) => {
|
|
208
|
+
onFailed(err);
|
|
209
|
+
this.failAll(err);
|
|
210
|
+
});
|
|
211
|
+
this.worker.on("exit", (code) => {
|
|
212
|
+
if (code !== 0) {
|
|
213
|
+
const err = new Error(`build worker exited with code ${code}`);
|
|
214
|
+
onFailed(err);
|
|
215
|
+
this.failAll(err);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
failAll(err) {
|
|
220
|
+
const pendingTasks = Array.from(this.inFlight.values());
|
|
221
|
+
this.inFlight.clear();
|
|
222
|
+
pendingTasks.forEach((pending) => pending.reject(err));
|
|
223
|
+
}
|
|
224
|
+
/** Pulls tasks off the pool's queue until at max concurrency. */
|
|
225
|
+
next() {
|
|
226
|
+
if (!this.isReady) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
while (this.inFlight.size < this.concurrency) {
|
|
230
|
+
const pending = this.pool.dequeue();
|
|
231
|
+
if (!pending) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
this.inFlight.set(pending.id, pending);
|
|
235
|
+
const req = {
|
|
236
|
+
type: "render",
|
|
237
|
+
id: pending.id,
|
|
238
|
+
task: pending.task
|
|
239
|
+
};
|
|
240
|
+
this.worker.postMessage(req);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async terminate() {
|
|
244
|
+
await this.worker.terminate();
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
var BuildWorkerPool = class {
|
|
248
|
+
workers = [];
|
|
249
|
+
queue = [];
|
|
250
|
+
nextTaskId = 0;
|
|
251
|
+
constructor(options) {
|
|
252
|
+
for (let i = 0; i < options.numWorkers; i++) {
|
|
253
|
+
this.workers.push(new BuildWorker(this, options));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/** Waits for all workers to finish initializing. */
|
|
257
|
+
async ready() {
|
|
258
|
+
await Promise.all(this.workers.map((worker) => worker.ready));
|
|
259
|
+
}
|
|
260
|
+
/** Schedules a page build and resolves when the page finishes. */
|
|
261
|
+
run(task) {
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
|
+
this.queue.push({ id: this.nextTaskId++, task, resolve, reject });
|
|
264
|
+
this.workers.forEach((worker) => worker.next());
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
dequeue() {
|
|
268
|
+
return this.queue.shift();
|
|
269
|
+
}
|
|
270
|
+
async terminate() {
|
|
271
|
+
await Promise.all(this.workers.map((worker) => worker.terminate()));
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
437
275
|
// src/cli/build.ts
|
|
438
|
-
var
|
|
276
|
+
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
439
277
|
async function build(rootProjectDir, options) {
|
|
440
278
|
const mode = options?.mode || "production";
|
|
441
279
|
process.env.NODE_ENV = mode;
|
|
442
|
-
const rootDir =
|
|
280
|
+
const rootDir = path2.resolve(rootProjectDir || process.cwd());
|
|
443
281
|
const rootConfig = await loadRootConfig(rootDir, { command: "build" });
|
|
444
|
-
const distDir =
|
|
282
|
+
const distDir = path2.join(rootDir, "dist");
|
|
445
283
|
const ssrOnly = options?.ssrOnly || false;
|
|
446
284
|
console.log();
|
|
447
285
|
console.log(`${dim2("\u2503")} project: ${rootDir}`);
|
|
@@ -452,12 +290,12 @@ async function build(rootProjectDir, options) {
|
|
|
452
290
|
await makeDir(distDir);
|
|
453
291
|
const pods = await collectPods(rootConfig);
|
|
454
292
|
const routeFiles = [];
|
|
455
|
-
if (await isDirectory(
|
|
456
|
-
const pageFiles = await
|
|
293
|
+
if (await isDirectory(path2.join(rootDir, "routes"))) {
|
|
294
|
+
const pageFiles = await glob("routes/**/*", { cwd: rootDir });
|
|
457
295
|
pageFiles.forEach((file) => {
|
|
458
|
-
const parts =
|
|
296
|
+
const parts = path2.parse(file);
|
|
459
297
|
if (!parts.name.startsWith("_") && isJsFile(parts.base)) {
|
|
460
|
-
routeFiles.push(
|
|
298
|
+
routeFiles.push(path2.resolve(rootDir, file));
|
|
461
299
|
}
|
|
462
300
|
});
|
|
463
301
|
}
|
|
@@ -471,12 +309,12 @@ async function build(rootProjectDir, options) {
|
|
|
471
309
|
return sourceFile.filePath;
|
|
472
310
|
});
|
|
473
311
|
const bundleScripts = [];
|
|
474
|
-
if (await isDirectory(
|
|
475
|
-
const bundleFiles = await
|
|
312
|
+
if (await isDirectory(path2.join(rootDir, "bundles"))) {
|
|
313
|
+
const bundleFiles = await glob("bundles/*", { cwd: rootDir });
|
|
476
314
|
bundleFiles.forEach((file) => {
|
|
477
|
-
const parts =
|
|
315
|
+
const parts = path2.parse(file);
|
|
478
316
|
if (isJsFile(parts.base)) {
|
|
479
|
-
bundleScripts.push(
|
|
317
|
+
bundleScripts.push(path2.resolve(rootDir, file));
|
|
480
318
|
}
|
|
481
319
|
});
|
|
482
320
|
}
|
|
@@ -506,7 +344,7 @@ async function build(rootProjectDir, options) {
|
|
|
506
344
|
plugins: vitePlugins
|
|
507
345
|
};
|
|
508
346
|
const ssrInput = {
|
|
509
|
-
render:
|
|
347
|
+
render: path2.resolve(__dirname2, "./render.js")
|
|
510
348
|
};
|
|
511
349
|
rootPlugins.forEach((plugin) => {
|
|
512
350
|
if (plugin.ssrInput) {
|
|
@@ -537,7 +375,7 @@ async function build(rootProjectDir, options) {
|
|
|
537
375
|
sanitizeFileName
|
|
538
376
|
}
|
|
539
377
|
},
|
|
540
|
-
outDir:
|
|
378
|
+
outDir: path2.join(distDir, "server"),
|
|
541
379
|
ssr: true,
|
|
542
380
|
ssrManifest: false,
|
|
543
381
|
cssCodeSplit: true,
|
|
@@ -570,7 +408,7 @@ async function build(rootProjectDir, options) {
|
|
|
570
408
|
...viteConfig?.build?.rolldownOptions?.output
|
|
571
409
|
}
|
|
572
410
|
},
|
|
573
|
-
outDir:
|
|
411
|
+
outDir: path2.join(distDir, ".build/routes"),
|
|
574
412
|
ssr: true,
|
|
575
413
|
ssrManifest: false,
|
|
576
414
|
ssrEmitAssets: true,
|
|
@@ -601,7 +439,7 @@ async function build(rootProjectDir, options) {
|
|
|
601
439
|
...viteConfig?.build?.rolldownOptions?.output
|
|
602
440
|
}
|
|
603
441
|
},
|
|
604
|
-
outDir:
|
|
442
|
+
outDir: path2.join(distDir, ".build/client"),
|
|
605
443
|
ssr: false,
|
|
606
444
|
ssrManifest: false,
|
|
607
445
|
manifest: true,
|
|
@@ -614,21 +452,21 @@ async function build(rootProjectDir, options) {
|
|
|
614
452
|
});
|
|
615
453
|
} else {
|
|
616
454
|
await writeFile(
|
|
617
|
-
|
|
455
|
+
path2.join(distDir, ".build/client/.vite/manifest.json"),
|
|
618
456
|
"{}"
|
|
619
457
|
);
|
|
620
458
|
}
|
|
621
|
-
await bundleRootConfig(rootDir,
|
|
459
|
+
await bundleRootConfig(rootDir, path2.join(distDir, "root.config.js"));
|
|
622
460
|
await copyGlob(
|
|
623
461
|
"**/*.css",
|
|
624
|
-
|
|
625
|
-
|
|
462
|
+
path2.join(distDir, ".build/routes"),
|
|
463
|
+
path2.join(distDir, ".build/client")
|
|
626
464
|
);
|
|
627
465
|
const routesManifest = await loadJson(
|
|
628
|
-
|
|
466
|
+
path2.join(distDir, ".build/routes/.vite/manifest.json")
|
|
629
467
|
);
|
|
630
468
|
const clientManifest = await loadJson(
|
|
631
|
-
|
|
469
|
+
path2.join(distDir, ".build/client/.vite/manifest.json")
|
|
632
470
|
);
|
|
633
471
|
function collectRouteCss(asset, cssDeps, visited) {
|
|
634
472
|
if (!asset || !asset.file || visited.has(asset.file)) {
|
|
@@ -671,17 +509,17 @@ async function build(rootProjectDir, options) {
|
|
|
671
509
|
);
|
|
672
510
|
const rootManifest = assetMap.toJson();
|
|
673
511
|
await writeFile(
|
|
674
|
-
|
|
512
|
+
path2.join(distDir, ".root/manifest.json"),
|
|
675
513
|
JSON.stringify(rootManifest, null, 2)
|
|
676
514
|
);
|
|
677
515
|
const elementGraphJson = elementGraph.toJson();
|
|
678
516
|
await writeFile(
|
|
679
|
-
|
|
517
|
+
path2.join(distDir, ".root/elements.json"),
|
|
680
518
|
JSON.stringify(elementGraphJson, null, 2)
|
|
681
519
|
);
|
|
682
|
-
const buildDir =
|
|
683
|
-
const publicDir =
|
|
684
|
-
if (fsExtra.existsSync(
|
|
520
|
+
const buildDir = path2.join(distDir, "html");
|
|
521
|
+
const publicDir = path2.join(rootDir, "public");
|
|
522
|
+
if (fsExtra.existsSync(path2.join(rootDir, "public"))) {
|
|
685
523
|
fsExtra.copySync(publicDir, buildDir, { dereference: true });
|
|
686
524
|
} else {
|
|
687
525
|
await makeDir(buildDir);
|
|
@@ -693,8 +531,8 @@ async function build(rootProjectDir, options) {
|
|
|
693
531
|
}
|
|
694
532
|
seenAssets.add(assetUrl);
|
|
695
533
|
const assetRelPath = assetUrl.slice(1);
|
|
696
|
-
const assetFrom =
|
|
697
|
-
const assetTo =
|
|
534
|
+
const assetFrom = path2.join(distDir, ".build/client", assetRelPath);
|
|
535
|
+
const assetTo = path2.join(buildDir, assetRelPath);
|
|
698
536
|
if (!await fileExists(assetFrom)) {
|
|
699
537
|
console.log(`${assetFrom} does not exist`);
|
|
700
538
|
return;
|
|
@@ -724,7 +562,7 @@ async function build(rootProjectDir, options) {
|
|
|
724
562
|
})
|
|
725
563
|
);
|
|
726
564
|
if (!ssrOnly) {
|
|
727
|
-
const render = await import(
|
|
565
|
+
const render = await import(path2.join(distDir, "server/render.js"));
|
|
728
566
|
const renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
729
567
|
let sitemap = await renderer.getSitemap();
|
|
730
568
|
if (options?.filter) {
|
|
@@ -744,92 +582,118 @@ async function build(rootProjectDir, options) {
|
|
|
744
582
|
);
|
|
745
583
|
}
|
|
746
584
|
const domain = rootConfig.domain;
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
585
|
+
const addSitemapXmlItem = (urlPath, sitemapItem, outFilePath) => {
|
|
586
|
+
if (!rootConfig.sitemap || !outFilePath.endsWith("index.html")) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
const sitemapXmlItem = {
|
|
590
|
+
url: `${domain}${urlPath}`,
|
|
591
|
+
locale: sitemapItem.locale,
|
|
592
|
+
alts: []
|
|
593
|
+
};
|
|
594
|
+
sitemapXmlItems.push(sitemapXmlItem);
|
|
595
|
+
if (sitemapItem.alts) {
|
|
596
|
+
Object.entries(sitemapItem.alts).forEach(([altLocale, item]) => {
|
|
597
|
+
sitemapXmlItem.alts.push({
|
|
598
|
+
url: `${domain}${item.urlPath}`,
|
|
599
|
+
locale: altLocale,
|
|
600
|
+
hreflang: item.hrefLang
|
|
601
|
+
});
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
const onPageResult = (sitemapItem, result) => {
|
|
606
|
+
if (result.notFound || !result.outFilePath) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (!result.staticContent) {
|
|
610
|
+
addSitemapXmlItem(result.urlPath, sitemapItem, result.outFilePath);
|
|
611
|
+
}
|
|
612
|
+
printFileOutput(
|
|
613
|
+
fileSize(path2.join(buildDir, result.outFilePath)),
|
|
614
|
+
"dist/html/",
|
|
615
|
+
result.outFilePath
|
|
616
|
+
);
|
|
617
|
+
};
|
|
618
|
+
const sitemapEntries = Object.entries(sitemap).filter(([, sitemapItem]) => {
|
|
619
|
+
if (rootConfig.build?.excludeDefaultLocaleFromIntlPaths) {
|
|
620
|
+
const defaultLocale = rootConfig.i18n?.defaultLocale || "en";
|
|
621
|
+
if (sitemapItem.locale === defaultLocale) {
|
|
622
|
+
return false;
|
|
758
623
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
624
|
+
}
|
|
625
|
+
return true;
|
|
626
|
+
});
|
|
627
|
+
console.log("\nhtml output:");
|
|
628
|
+
const concurrency = Number(options?.concurrency || 10);
|
|
629
|
+
const numThreads = resolveNumThreads(
|
|
630
|
+
options?.threads,
|
|
631
|
+
sitemapEntries.length
|
|
632
|
+
);
|
|
633
|
+
if (numThreads > 0) {
|
|
634
|
+
const pool = new BuildWorkerPool({
|
|
635
|
+
numWorkers: numThreads,
|
|
636
|
+
workerConcurrency: Math.max(Math.ceil(concurrency / numThreads), 1),
|
|
637
|
+
rootDir,
|
|
638
|
+
mode
|
|
639
|
+
});
|
|
640
|
+
try {
|
|
641
|
+
await pool.ready();
|
|
642
|
+
await Promise.all(
|
|
643
|
+
sitemapEntries.map(async ([urlPath, sitemapItem]) => {
|
|
644
|
+
try {
|
|
645
|
+
const result = await pool.run({
|
|
646
|
+
urlPath,
|
|
647
|
+
params: sitemapItem.params,
|
|
648
|
+
routeSrc: sitemapItem.route.src,
|
|
649
|
+
locale: sitemapItem.locale
|
|
767
650
|
});
|
|
768
|
-
|
|
769
|
-
|
|
651
|
+
onPageResult(sitemapItem, result);
|
|
652
|
+
} catch (e) {
|
|
653
|
+
if (e instanceof BuildPageError) {
|
|
654
|
+
logBuildError(
|
|
655
|
+
{
|
|
656
|
+
route: sitemapItem.route,
|
|
657
|
+
params: sitemapItem.params,
|
|
658
|
+
urlPath
|
|
659
|
+
},
|
|
660
|
+
new Error(e.workerError)
|
|
661
|
+
);
|
|
770
662
|
}
|
|
771
|
-
|
|
772
|
-
props = { rootConfig, params: sitemapItem.params };
|
|
773
|
-
}
|
|
774
|
-
const result = await routeModule.getStaticContent(props);
|
|
775
|
-
let body;
|
|
776
|
-
if (typeof result === "string") {
|
|
777
|
-
body = result;
|
|
778
|
-
} else if (result && typeof result === "object") {
|
|
779
|
-
body = result.body;
|
|
780
|
-
} else {
|
|
781
|
-
body = "";
|
|
782
|
-
}
|
|
783
|
-
const outFilePath2 = urlPath.slice(1);
|
|
784
|
-
const outPath2 = path3.join(buildDir, outFilePath2);
|
|
785
|
-
await makeDir(path3.dirname(outPath2));
|
|
786
|
-
await writeFile(outPath2, normalizeLineEndings(body));
|
|
787
|
-
printFileOutput(fileSize(outPath2), "dist/html/", outFilePath2);
|
|
788
|
-
return;
|
|
789
|
-
}
|
|
790
|
-
const data = await renderer.renderRoute(sitemapItem.route, {
|
|
791
|
-
routeParams: sitemapItem.params
|
|
792
|
-
});
|
|
793
|
-
if (data.notFound) {
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
796
|
-
let outFilePath = path3.join(urlPath.slice(1), "index.html");
|
|
797
|
-
if (outFilePath.endsWith("404/index.html")) {
|
|
798
|
-
outFilePath = outFilePath.replace("404/index.html", "404.html");
|
|
799
|
-
}
|
|
800
|
-
const outPath = path3.join(buildDir, outFilePath);
|
|
801
|
-
if (rootConfig.sitemap && outFilePath.endsWith("index.html")) {
|
|
802
|
-
const sitemapXmlItem = {
|
|
803
|
-
url: `${domain}${urlPath}`,
|
|
804
|
-
locale: sitemapItem.locale,
|
|
805
|
-
alts: []
|
|
806
|
-
};
|
|
807
|
-
sitemapXmlItems.push(sitemapXmlItem);
|
|
808
|
-
if (sitemapItem.alts) {
|
|
809
|
-
Object.entries(sitemapItem.alts).forEach(([altLocale, item]) => {
|
|
810
|
-
sitemapXmlItem.alts.push({
|
|
811
|
-
url: `${domain}${item.urlPath}`,
|
|
812
|
-
locale: altLocale,
|
|
813
|
-
hreflang: item.hrefLang
|
|
814
|
-
});
|
|
815
|
-
});
|
|
663
|
+
throw e;
|
|
816
664
|
}
|
|
665
|
+
})
|
|
666
|
+
);
|
|
667
|
+
} finally {
|
|
668
|
+
await pool.terminate();
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
await batchAsyncCalls(
|
|
672
|
+
sitemapEntries,
|
|
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
|
+
);
|
|
817
693
|
}
|
|
818
|
-
const html = await transformHtml(data.html || "", rootConfig);
|
|
819
|
-
await writeFile(outPath, normalizeLineEndings(html));
|
|
820
|
-
printFileOutput(fileSize(outPath), "dist/html/", outFilePath);
|
|
821
|
-
} catch (e) {
|
|
822
|
-
logBuildError(
|
|
823
|
-
{ route: sitemapItem.route, params: sitemapItem.params, urlPath },
|
|
824
|
-
e
|
|
825
|
-
);
|
|
826
|
-
throw new Error(
|
|
827
|
-
`BuildError: ${urlPath} (${sitemapItem.route.src}) failed to build.`,
|
|
828
|
-
{ cause: e }
|
|
829
|
-
);
|
|
830
694
|
}
|
|
831
|
-
|
|
832
|
-
|
|
695
|
+
);
|
|
696
|
+
}
|
|
833
697
|
if (rootConfig.sitemap) {
|
|
834
698
|
const sitemapXmlBuilder = [];
|
|
835
699
|
sitemapXmlItems.sort((a, b) => a.url.localeCompare(b.url));
|
|
@@ -855,7 +719,7 @@ async function build(rootProjectDir, options) {
|
|
|
855
719
|
"</urlset>"
|
|
856
720
|
];
|
|
857
721
|
const sitemapXml = sitemapXmlLines.join("\n");
|
|
858
|
-
const outPath =
|
|
722
|
+
const outPath = path2.join(buildDir, "sitemap.xml");
|
|
859
723
|
await writeFile(outPath, sitemapXml);
|
|
860
724
|
printFileOutput(fileSize(outPath), "dist/html/", "sitemap.xml");
|
|
861
725
|
}
|
|
@@ -869,6 +733,27 @@ async function build(rootProjectDir, options) {
|
|
|
869
733
|
function isRouteFile(filepath) {
|
|
870
734
|
return filepath.startsWith("routes") && isJsFile(filepath);
|
|
871
735
|
}
|
|
736
|
+
var MIN_PAGES_PER_THREAD = 10;
|
|
737
|
+
function resolveNumThreads(threads, numPages) {
|
|
738
|
+
if (threads === void 0 || threads === false) {
|
|
739
|
+
return 0;
|
|
740
|
+
}
|
|
741
|
+
if (threads === true || threads === "auto") {
|
|
742
|
+
const maxByCpu = Math.max(os.availableParallelism() - 1, 1);
|
|
743
|
+
const maxByPages = Math.floor(numPages / MIN_PAGES_PER_THREAD);
|
|
744
|
+
const numThreads = Math.min(maxByCpu, maxByPages);
|
|
745
|
+
if (numThreads <= 1) {
|
|
746
|
+
return 0;
|
|
747
|
+
}
|
|
748
|
+
console.log(`rendering with ${numThreads} worker threads`);
|
|
749
|
+
return numThreads;
|
|
750
|
+
}
|
|
751
|
+
const num = parseInt(threads);
|
|
752
|
+
if (isNaN(num) || num < 0) {
|
|
753
|
+
throw new Error(`invalid --threads value: ${threads}`);
|
|
754
|
+
}
|
|
755
|
+
return num;
|
|
756
|
+
}
|
|
872
757
|
function fileSize(filepath) {
|
|
873
758
|
const stats = fsExtra.statSync(filepath);
|
|
874
759
|
const bytes = stats.size;
|
|
@@ -917,18 +802,15 @@ function formatParams(params) {
|
|
|
917
802
|
return ` ${key}: ${value}`;
|
|
918
803
|
}).join("\n");
|
|
919
804
|
}
|
|
920
|
-
function normalizeLineEndings(str) {
|
|
921
|
-
return str.replace(/\r\n?/g, "\n");
|
|
922
|
-
}
|
|
923
805
|
|
|
924
806
|
// src/cli/codegen.ts
|
|
925
|
-
import { promises as
|
|
926
|
-
import
|
|
927
|
-
import { fileURLToPath as
|
|
928
|
-
import
|
|
929
|
-
var
|
|
807
|
+
import { promises as fs } from "node:fs";
|
|
808
|
+
import path3 from "node:path";
|
|
809
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
810
|
+
import glob2 from "tiny-glob";
|
|
811
|
+
var __dirname3 = path3.dirname(fileURLToPath3(import.meta.url));
|
|
930
812
|
async function codegen(type, name, options) {
|
|
931
|
-
const rootDir =
|
|
813
|
+
const rootDir = path3.resolve(process.cwd());
|
|
932
814
|
const project = new Project(rootDir);
|
|
933
815
|
await project.generateCode(type, name, options);
|
|
934
816
|
}
|
|
@@ -938,8 +820,8 @@ var Project = class {
|
|
|
938
820
|
constructor(rootDir) {
|
|
939
821
|
this.rootDir = rootDir;
|
|
940
822
|
this.tplDirs = [
|
|
941
|
-
|
|
942
|
-
|
|
823
|
+
path3.join(rootDir, "codegen"),
|
|
824
|
+
path3.join(__dirname3, "../codegen")
|
|
943
825
|
];
|
|
944
826
|
}
|
|
945
827
|
async generateCode(type, name, options) {
|
|
@@ -949,7 +831,7 @@ var Project = class {
|
|
|
949
831
|
return;
|
|
950
832
|
}
|
|
951
833
|
const outname = options?.out || `${type}s`;
|
|
952
|
-
const outdir =
|
|
834
|
+
const outdir = path3.join(this.rootDir, outname, name);
|
|
953
835
|
if (await dirExists(outdir)) {
|
|
954
836
|
await rmDir(outdir);
|
|
955
837
|
}
|
|
@@ -958,7 +840,7 @@ var Project = class {
|
|
|
958
840
|
const tpl = await files[tplName].read();
|
|
959
841
|
const content = tpl.replaceAll("[[name]]", name).replaceAll("[[name:camel_upper]]", toCamelCaseUpper(name));
|
|
960
842
|
const filename = tplName.replace("[name]", name);
|
|
961
|
-
const filepath =
|
|
843
|
+
const filepath = path3.join(outdir, filename);
|
|
962
844
|
await writeFile(filepath, content);
|
|
963
845
|
console.log(`saved ${filepath}`);
|
|
964
846
|
}
|
|
@@ -969,7 +851,7 @@ var Project = class {
|
|
|
969
851
|
*/
|
|
970
852
|
async loadFiles(type) {
|
|
971
853
|
for (const tplDir of this.tplDirs) {
|
|
972
|
-
const typeDir =
|
|
854
|
+
const typeDir = path3.join(tplDir, type);
|
|
973
855
|
if (await dirExists(typeDir)) {
|
|
974
856
|
return this.loadTplFiles(typeDir);
|
|
975
857
|
}
|
|
@@ -981,12 +863,12 @@ var Project = class {
|
|
|
981
863
|
*/
|
|
982
864
|
async loadTplFiles(dirpath) {
|
|
983
865
|
const tplFiles = {};
|
|
984
|
-
const files = await
|
|
866
|
+
const files = await glob2("*.tpl", { cwd: dirpath });
|
|
985
867
|
for (const filename of files) {
|
|
986
|
-
const filepath =
|
|
868
|
+
const filepath = path3.join(dirpath, filename);
|
|
987
869
|
const name = filename.slice(0, -4);
|
|
988
870
|
tplFiles[name] = {
|
|
989
|
-
read: () =>
|
|
871
|
+
read: () => fs.readFile(filepath, "utf-8")
|
|
990
872
|
};
|
|
991
873
|
}
|
|
992
874
|
return tplFiles;
|
|
@@ -1002,23 +884,23 @@ function toTitleCase(str) {
|
|
|
1002
884
|
}
|
|
1003
885
|
|
|
1004
886
|
// src/cli/create-package.ts
|
|
1005
|
-
import { promises as
|
|
1006
|
-
import
|
|
887
|
+
import { promises as fs2 } from "node:fs";
|
|
888
|
+
import path4 from "node:path";
|
|
1007
889
|
import { build as esbuild } from "esbuild";
|
|
1008
890
|
async function createPackage(rootProjectDir, options) {
|
|
1009
891
|
const mode = options?.mode || "production";
|
|
1010
892
|
process.env.NODE_ENV = mode;
|
|
1011
|
-
const rootDir =
|
|
1012
|
-
const distDir =
|
|
893
|
+
const rootDir = path4.resolve(rootProjectDir || process.cwd());
|
|
894
|
+
const distDir = path4.join(rootDir, "dist");
|
|
1013
895
|
const target = options?.target || await getDefaultTarget(rootDir);
|
|
1014
|
-
const outDir =
|
|
896
|
+
const outDir = path4.resolve(options?.out || target || "out");
|
|
1015
897
|
await build(rootProjectDir, { ssrOnly: true, mode });
|
|
1016
898
|
await rmDir(outDir);
|
|
1017
899
|
await makeDir(outDir);
|
|
1018
|
-
await copyDir(distDir,
|
|
1019
|
-
const collectionsDir =
|
|
900
|
+
await copyDir(distDir, path4.resolve(outDir, "dist"));
|
|
901
|
+
const collectionsDir = path4.resolve(rootDir, "collections");
|
|
1020
902
|
if (await dirExists(collectionsDir)) {
|
|
1021
|
-
await copyDir(collectionsDir,
|
|
903
|
+
await copyDir(collectionsDir, path4.join(outDir, "collections"));
|
|
1022
904
|
}
|
|
1023
905
|
const packageJson = await generatePackageJson(rootDir, options);
|
|
1024
906
|
if (options?.version && packageJson.dependencies) {
|
|
@@ -1033,21 +915,21 @@ async function createPackage(rootProjectDir, options) {
|
|
|
1033
915
|
}
|
|
1034
916
|
}
|
|
1035
917
|
if (target === "appengine") {
|
|
1036
|
-
const appYamlPath = options?.appYaml ||
|
|
918
|
+
const appYamlPath = options?.appYaml || path4.join(rootDir, "app.yaml");
|
|
1037
919
|
await onAppEngine({ packageJson, outDir, appYamlPath });
|
|
1038
920
|
} else if (target === "firebase") {
|
|
1039
921
|
await onFirebase({ rootDir, packageJson, outDir });
|
|
1040
922
|
}
|
|
1041
|
-
await writeJson(
|
|
923
|
+
await writeJson(path4.resolve(outDir, "package.json"), packageJson);
|
|
1042
924
|
console.log("done!");
|
|
1043
925
|
console.log(`saved package to ${outDir}`);
|
|
1044
926
|
}
|
|
1045
927
|
async function getDefaultTarget(rootDir) {
|
|
1046
|
-
const firebaseConfigPath =
|
|
928
|
+
const firebaseConfigPath = path4.resolve(rootDir, "firebase.json");
|
|
1047
929
|
if (await fileExists(firebaseConfigPath)) {
|
|
1048
930
|
return "firebase";
|
|
1049
931
|
}
|
|
1050
|
-
const appEngineConfigPath =
|
|
932
|
+
const appEngineConfigPath = path4.resolve(rootDir, "app.yaml");
|
|
1051
933
|
if (await fileExists(appEngineConfigPath)) {
|
|
1052
934
|
return "appengine";
|
|
1053
935
|
}
|
|
@@ -1055,7 +937,7 @@ async function getDefaultTarget(rootDir) {
|
|
|
1055
937
|
}
|
|
1056
938
|
async function generatePackageJson(rootDir, options) {
|
|
1057
939
|
const packageJson = await loadJson(
|
|
1058
|
-
|
|
940
|
+
path4.resolve(rootDir, "package.json")
|
|
1059
941
|
);
|
|
1060
942
|
const allDeps = flattenPackageDepsFromMonorepo(rootDir);
|
|
1061
943
|
packageJson.dependencies ??= {};
|
|
@@ -1082,7 +964,7 @@ async function generatePackageJson(rootDir, options) {
|
|
|
1082
964
|
async function onAppEngine(options) {
|
|
1083
965
|
const { outDir, packageJson, appYamlPath } = options;
|
|
1084
966
|
if (await fileExists(appYamlPath)) {
|
|
1085
|
-
await
|
|
967
|
+
await fs2.copyFile(appYamlPath, path4.resolve(outDir, "app.yaml"));
|
|
1086
968
|
}
|
|
1087
969
|
if (packageJson.scripts?.start) {
|
|
1088
970
|
packageJson.scripts = { start: packageJson.scripts.start };
|
|
@@ -1092,11 +974,11 @@ async function onAppEngine(options) {
|
|
|
1092
974
|
}
|
|
1093
975
|
async function onFirebase(options) {
|
|
1094
976
|
const { rootDir, outDir, packageJson } = options;
|
|
1095
|
-
const outBasename =
|
|
977
|
+
const outBasename = path4.basename(outDir);
|
|
1096
978
|
if (outBasename === "functions") {
|
|
1097
|
-
const indexTsFile =
|
|
979
|
+
const indexTsFile = path4.resolve(rootDir, "index.ts");
|
|
1098
980
|
if (await fileExists(indexTsFile)) {
|
|
1099
|
-
await bundleTsFile(indexTsFile,
|
|
981
|
+
await bundleTsFile(indexTsFile, path4.resolve(outDir, "index.js"));
|
|
1100
982
|
}
|
|
1101
983
|
}
|
|
1102
984
|
if (packageJson.scripts?.start) {
|
|
@@ -1121,7 +1003,7 @@ async function bundleTsFile(srcPath, outPath) {
|
|
|
1121
1003
|
setup(build2) {
|
|
1122
1004
|
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
1123
1005
|
const id = args.path;
|
|
1124
|
-
if (id[0] !== "." && !
|
|
1006
|
+
if (id[0] !== "." && !path4.isAbsolute(id)) {
|
|
1125
1007
|
return {
|
|
1126
1008
|
external: true
|
|
1127
1009
|
};
|
|
@@ -1135,13 +1017,13 @@ async function bundleTsFile(srcPath, outPath) {
|
|
|
1135
1017
|
}
|
|
1136
1018
|
|
|
1137
1019
|
// src/cli/dev.ts
|
|
1138
|
-
import
|
|
1139
|
-
import { fileURLToPath as
|
|
1020
|
+
import path11 from "node:path";
|
|
1021
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
1140
1022
|
import cookieParser from "cookie-parser";
|
|
1141
1023
|
import { default as express } from "express";
|
|
1142
1024
|
import { dim as dim5 } from "kleur/colors";
|
|
1143
1025
|
import sirv from "sirv";
|
|
1144
|
-
import
|
|
1026
|
+
import glob3 from "tiny-glob";
|
|
1145
1027
|
|
|
1146
1028
|
// src/middleware/hooks.ts
|
|
1147
1029
|
function hooksMiddleware() {
|
|
@@ -1229,8 +1111,8 @@ function testIsRedirectValid(url) {
|
|
|
1229
1111
|
}
|
|
1230
1112
|
|
|
1231
1113
|
// src/render/asset-map/dev-asset-map.ts
|
|
1232
|
-
import
|
|
1233
|
-
import { searchForWorkspaceRoot
|
|
1114
|
+
import path5 from "node:path";
|
|
1115
|
+
import { searchForWorkspaceRoot } from "vite";
|
|
1234
1116
|
var DevServerAssetMap = class {
|
|
1235
1117
|
rootConfig;
|
|
1236
1118
|
moduleGraph;
|
|
@@ -1239,7 +1121,7 @@ var DevServerAssetMap = class {
|
|
|
1239
1121
|
this.moduleGraph = moduleGraph;
|
|
1240
1122
|
}
|
|
1241
1123
|
async get(src) {
|
|
1242
|
-
const file =
|
|
1124
|
+
const file = path5.resolve(this.rootConfig.rootDir, src);
|
|
1243
1125
|
const viteModules = this.moduleGraph.getModulesByFile(file);
|
|
1244
1126
|
if (viteModules && viteModules.size > 0) {
|
|
1245
1127
|
const [viteModule] = viteModules;
|
|
@@ -1257,7 +1139,7 @@ var DevServerAssetMap = class {
|
|
|
1257
1139
|
getJsDeps: async () => [assetUrl]
|
|
1258
1140
|
};
|
|
1259
1141
|
}
|
|
1260
|
-
const workspaceRoot =
|
|
1142
|
+
const workspaceRoot = searchForWorkspaceRoot(this.rootConfig.rootDir);
|
|
1261
1143
|
if (await directoryContains(workspaceRoot, file)) {
|
|
1262
1144
|
const assetUrl = `/@fs/${file}`;
|
|
1263
1145
|
return {
|
|
@@ -1271,7 +1153,7 @@ var DevServerAssetMap = class {
|
|
|
1271
1153
|
return null;
|
|
1272
1154
|
}
|
|
1273
1155
|
filePathToSrc(file) {
|
|
1274
|
-
return
|
|
1156
|
+
return path5.relative(this.rootConfig.rootDir, file);
|
|
1275
1157
|
}
|
|
1276
1158
|
};
|
|
1277
1159
|
var DevServerAsset = class _DevServerAsset {
|
|
@@ -1313,7 +1195,7 @@ var DevServerAsset = class _DevServerAsset {
|
|
|
1313
1195
|
return;
|
|
1314
1196
|
}
|
|
1315
1197
|
visited.add(asset.moduleId);
|
|
1316
|
-
const parts =
|
|
1198
|
+
const parts = path5.parse(asset.assetUrl);
|
|
1317
1199
|
if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && asset.moduleId.includes("/elements/")) {
|
|
1318
1200
|
urls.add(asset.assetUrl);
|
|
1319
1201
|
}
|
|
@@ -1340,7 +1222,7 @@ var DevServerAsset = class _DevServerAsset {
|
|
|
1340
1222
|
}
|
|
1341
1223
|
visited.add(asset.assetUrl);
|
|
1342
1224
|
if (asset.src.endsWith(".scss")) {
|
|
1343
|
-
const parts =
|
|
1225
|
+
const parts = path5.parse(asset.src);
|
|
1344
1226
|
if (!parts.name.startsWith("_")) {
|
|
1345
1227
|
urls.add(asset.assetUrl);
|
|
1346
1228
|
}
|
|
@@ -1421,19 +1303,19 @@ function getSessionCookieSecret(rootConfig, rootDir) {
|
|
|
1421
1303
|
|
|
1422
1304
|
// src/cli/secrets.ts
|
|
1423
1305
|
import { spawn as spawn3 } from "node:child_process";
|
|
1424
|
-
import
|
|
1425
|
-
import
|
|
1306
|
+
import fs6 from "node:fs";
|
|
1307
|
+
import path9 from "node:path";
|
|
1426
1308
|
import * as readline from "node:readline";
|
|
1427
1309
|
import { dim as dim3, green, red, yellow } from "kleur/colors";
|
|
1428
1310
|
|
|
1429
1311
|
// src/secrets/manifest.ts
|
|
1430
|
-
import
|
|
1431
|
-
import
|
|
1312
|
+
import fs3 from "node:fs";
|
|
1313
|
+
import path6 from "node:path";
|
|
1432
1314
|
var MANIFEST_FILENAME = ".root.secrets.json";
|
|
1433
1315
|
var GSM_KEY_RE = /^[A-Za-z0-9_-]{1,255}$/;
|
|
1434
1316
|
var ENV_NAME_RE = /^[A-Za-z0-9_]+$/;
|
|
1435
1317
|
function manifestPath(dir) {
|
|
1436
|
-
return
|
|
1318
|
+
return path6.join(dir, MANIFEST_FILENAME);
|
|
1437
1319
|
}
|
|
1438
1320
|
function isValidEnvName(name) {
|
|
1439
1321
|
return ENV_NAME_RE.test(name);
|
|
@@ -1441,7 +1323,7 @@ function isValidEnvName(name) {
|
|
|
1441
1323
|
async function readManifest(filePath) {
|
|
1442
1324
|
let raw;
|
|
1443
1325
|
try {
|
|
1444
|
-
raw = await
|
|
1326
|
+
raw = await fs3.promises.readFile(filePath, "utf8");
|
|
1445
1327
|
} catch (err) {
|
|
1446
1328
|
if (err.code === "ENOENT") {
|
|
1447
1329
|
return null;
|
|
@@ -1468,8 +1350,8 @@ async function writeManifest(filePath, manifest) {
|
|
|
1468
1350
|
...manifest.import ? { import: manifest.import } : {},
|
|
1469
1351
|
secrets: sortedSecrets
|
|
1470
1352
|
};
|
|
1471
|
-
await
|
|
1472
|
-
await
|
|
1353
|
+
await fs3.promises.mkdir(path6.dirname(filePath), { recursive: true });
|
|
1354
|
+
await fs3.promises.writeFile(
|
|
1473
1355
|
filePath,
|
|
1474
1356
|
JSON.stringify(ordered, null, 2) + "\n",
|
|
1475
1357
|
"utf8"
|
|
@@ -1497,7 +1379,7 @@ async function resolveManagedKeys(rootDir) {
|
|
|
1497
1379
|
}
|
|
1498
1380
|
let shared;
|
|
1499
1381
|
if (site.import) {
|
|
1500
|
-
const sharedPath =
|
|
1382
|
+
const sharedPath = path6.resolve(rootDir, site.import.manifest);
|
|
1501
1383
|
const loaded = await readManifest(sharedPath);
|
|
1502
1384
|
if (!loaded) {
|
|
1503
1385
|
throw new Error(`imported manifest not found: ${sharedPath}`);
|
|
@@ -1624,16 +1506,16 @@ function validateManifest(value, filePath) {
|
|
|
1624
1506
|
|
|
1625
1507
|
// src/secrets/secrets.ts
|
|
1626
1508
|
import { spawn as spawn2 } from "node:child_process";
|
|
1627
|
-
import
|
|
1628
|
-
import
|
|
1509
|
+
import fs5 from "node:fs";
|
|
1510
|
+
import path8 from "node:path";
|
|
1629
1511
|
|
|
1630
1512
|
// src/secrets/env-file.ts
|
|
1631
|
-
import
|
|
1632
|
-
import
|
|
1513
|
+
import fs4 from "node:fs";
|
|
1514
|
+
import path7 from "node:path";
|
|
1633
1515
|
import dotenv from "dotenv";
|
|
1634
1516
|
async function readEnvFile(envPath2) {
|
|
1635
1517
|
try {
|
|
1636
|
-
return await
|
|
1518
|
+
return await fs4.promises.readFile(envPath2, "utf8");
|
|
1637
1519
|
} catch (err) {
|
|
1638
1520
|
if (err.code === "ENOENT") {
|
|
1639
1521
|
return "";
|
|
@@ -1642,11 +1524,11 @@ async function readEnvFile(envPath2) {
|
|
|
1642
1524
|
}
|
|
1643
1525
|
}
|
|
1644
1526
|
async function writeEnvFile(envPath2, content) {
|
|
1645
|
-
const dir =
|
|
1646
|
-
await
|
|
1647
|
-
const tmp =
|
|
1648
|
-
await
|
|
1649
|
-
await
|
|
1527
|
+
const dir = path7.dirname(envPath2);
|
|
1528
|
+
await fs4.promises.mkdir(dir, { recursive: true });
|
|
1529
|
+
const tmp = path7.join(dir, `.env.tmp-${process.pid}-${Date.now()}`);
|
|
1530
|
+
await fs4.promises.writeFile(tmp, content, "utf8");
|
|
1531
|
+
await fs4.promises.rename(tmp, envPath2);
|
|
1650
1532
|
}
|
|
1651
1533
|
function parseEnv(content) {
|
|
1652
1534
|
return dotenv.parse(content);
|
|
@@ -1864,10 +1746,10 @@ function hashValue(salt, value) {
|
|
|
1864
1746
|
// src/secrets/secrets.ts
|
|
1865
1747
|
var STATE_FILENAME = "secrets-sync.json";
|
|
1866
1748
|
function localStatePath(rootDir) {
|
|
1867
|
-
return
|
|
1749
|
+
return path8.join(rootDir, ".root", STATE_FILENAME);
|
|
1868
1750
|
}
|
|
1869
1751
|
function envPath(rootDir) {
|
|
1870
|
-
return
|
|
1752
|
+
return path8.join(rootDir, ".env");
|
|
1871
1753
|
}
|
|
1872
1754
|
var inFlight = /* @__PURE__ */ new Map();
|
|
1873
1755
|
function syncSecrets(options) {
|
|
@@ -2093,7 +1975,7 @@ async function pushEnvToSecrets(options) {
|
|
|
2093
1975
|
};
|
|
2094
1976
|
}
|
|
2095
1977
|
async function sharedImportedNames(rootDir, manifestFilePath) {
|
|
2096
|
-
if (
|
|
1978
|
+
if (path8.resolve(manifestFilePath) !== path8.resolve(manifestPath(rootDir))) {
|
|
2097
1979
|
return /* @__PURE__ */ new Set();
|
|
2098
1980
|
}
|
|
2099
1981
|
try {
|
|
@@ -2156,7 +2038,7 @@ function isSyncDisabledByEnv() {
|
|
|
2156
2038
|
}
|
|
2157
2039
|
async function readLocalState(rootDir) {
|
|
2158
2040
|
try {
|
|
2159
|
-
const raw = await
|
|
2041
|
+
const raw = await fs5.promises.readFile(localStatePath(rootDir), "utf8");
|
|
2160
2042
|
const parsed = JSON.parse(raw);
|
|
2161
2043
|
if (parsed && typeof parsed === "object" && typeof parsed.salt === "string" && parsed.secrets && typeof parsed.secrets === "object") {
|
|
2162
2044
|
return {
|
|
@@ -2170,8 +2052,8 @@ async function readLocalState(rootDir) {
|
|
|
2170
2052
|
}
|
|
2171
2053
|
async function writeLocalState(rootDir, state) {
|
|
2172
2054
|
const file = localStatePath(rootDir);
|
|
2173
|
-
await
|
|
2174
|
-
await
|
|
2055
|
+
await fs5.promises.mkdir(path8.dirname(file), { recursive: true });
|
|
2056
|
+
await fs5.promises.writeFile(
|
|
2175
2057
|
file,
|
|
2176
2058
|
JSON.stringify(state, null, 2) + "\n",
|
|
2177
2059
|
"utf8"
|
|
@@ -2237,7 +2119,7 @@ function registerSecretsCommands(program) {
|
|
|
2237
2119
|
}
|
|
2238
2120
|
async function secretsInit(opts) {
|
|
2239
2121
|
const rootDir = process.cwd();
|
|
2240
|
-
const target = opts.manifest ?
|
|
2122
|
+
const target = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2241
2123
|
if (await readManifest(target)) {
|
|
2242
2124
|
console.log(
|
|
2243
2125
|
`${BAR} ${yellow("secrets:")} manifest already exists at ${rel(rootDir, target)}`
|
|
@@ -2270,7 +2152,7 @@ async function secretsInit(opts) {
|
|
|
2270
2152
|
}
|
|
2271
2153
|
async function secretsSet(name, opts) {
|
|
2272
2154
|
const rootDir = process.cwd();
|
|
2273
|
-
const manifestFilePath = opts.manifest ?
|
|
2155
|
+
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2274
2156
|
const secretValue = await readSecretValue(name);
|
|
2275
2157
|
if (!secretValue) {
|
|
2276
2158
|
throw new Error("no value provided on stdin");
|
|
@@ -2283,7 +2165,7 @@ async function secretsSet(name, opts) {
|
|
|
2283
2165
|
}
|
|
2284
2166
|
async function secretsRm(name, opts) {
|
|
2285
2167
|
const rootDir = process.cwd();
|
|
2286
|
-
const manifestFilePath = opts.manifest ?
|
|
2168
|
+
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2287
2169
|
await removeSecret({ rootDir, manifestFilePath, name });
|
|
2288
2170
|
console.log(`${BAR} ${green("secrets:")} removed ${name}`);
|
|
2289
2171
|
console.log(
|
|
@@ -2292,7 +2174,7 @@ async function secretsRm(name, opts) {
|
|
|
2292
2174
|
}
|
|
2293
2175
|
async function secretsPush(opts) {
|
|
2294
2176
|
const rootDir = process.cwd();
|
|
2295
|
-
const manifestFilePath = opts.manifest ?
|
|
2177
|
+
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2296
2178
|
const only = opts.keys ? opts.keys.split(",").map((k) => k.trim()).filter(Boolean) : void 0;
|
|
2297
2179
|
const confirm = opts.yes ? void 0 : async (names, gsmKey) => {
|
|
2298
2180
|
if (!process.stdin.isTTY) {
|
|
@@ -2470,10 +2352,10 @@ function printPushResult(result, rootDir, manifestFilePath) {
|
|
|
2470
2352
|
}
|
|
2471
2353
|
async function ensureRootGitignored(rootDir) {
|
|
2472
2354
|
const gitRoot = await gitToplevel(rootDir) ?? rootDir;
|
|
2473
|
-
const gitignore =
|
|
2355
|
+
const gitignore = path9.join(gitRoot, ".gitignore");
|
|
2474
2356
|
let content = "";
|
|
2475
2357
|
try {
|
|
2476
|
-
content = await
|
|
2358
|
+
content = await fs6.promises.readFile(gitignore, "utf8");
|
|
2477
2359
|
} catch {
|
|
2478
2360
|
}
|
|
2479
2361
|
const lines = content.split(/\r?\n/).map((line) => line.trim());
|
|
@@ -2481,7 +2363,7 @@ async function ensureRootGitignored(rootDir) {
|
|
|
2481
2363
|
return false;
|
|
2482
2364
|
}
|
|
2483
2365
|
const prefix = content && !content.endsWith("\n") ? "\n" : "";
|
|
2484
|
-
await
|
|
2366
|
+
await fs6.promises.writeFile(gitignore, `${content}${prefix}.root/
|
|
2485
2367
|
`, "utf8");
|
|
2486
2368
|
return true;
|
|
2487
2369
|
}
|
|
@@ -2609,7 +2491,7 @@ function withTimeout(promise, ms) {
|
|
|
2609
2491
|
});
|
|
2610
2492
|
}
|
|
2611
2493
|
function rel(rootDir, filePath) {
|
|
2612
|
-
return
|
|
2494
|
+
return path9.relative(rootDir, filePath) || path9.basename(filePath);
|
|
2613
2495
|
}
|
|
2614
2496
|
function firstLine(text) {
|
|
2615
2497
|
return String(text).split("\n")[0];
|
|
@@ -2626,8 +2508,8 @@ function action(fn) {
|
|
|
2626
2508
|
}
|
|
2627
2509
|
|
|
2628
2510
|
// src/cli/startup/startup-tasks.ts
|
|
2629
|
-
import
|
|
2630
|
-
import
|
|
2511
|
+
import os2 from "node:os";
|
|
2512
|
+
import path10 from "node:path";
|
|
2631
2513
|
|
|
2632
2514
|
// src/cli/startup/check-version.ts
|
|
2633
2515
|
import { dim as dim4, green as green2, yellow as yellow2 } from "kleur/colors";
|
|
@@ -2710,7 +2592,7 @@ function printUpdateNotice(current, latest) {
|
|
|
2710
2592
|
|
|
2711
2593
|
// src/cli/startup/startup-tasks.ts
|
|
2712
2594
|
var STARTUP_TASKS = [checkVersionTask];
|
|
2713
|
-
var STATE_FILE =
|
|
2595
|
+
var STATE_FILE = path10.join(os2.homedir(), ".root", "startup-tasks.json");
|
|
2714
2596
|
async function runStartupTasks(ctx) {
|
|
2715
2597
|
try {
|
|
2716
2598
|
const state = await readState();
|
|
@@ -2761,13 +2643,13 @@ async function writeState(state) {
|
|
|
2761
2643
|
}
|
|
2762
2644
|
|
|
2763
2645
|
// src/cli/dev.ts
|
|
2764
|
-
var
|
|
2646
|
+
var __dirname4 = path11.dirname(fileURLToPath4(import.meta.url));
|
|
2765
2647
|
var DEV_SERVER_404_LOG_IGNORE_PATHS = /* @__PURE__ */ new Set([
|
|
2766
2648
|
"/.well-known/appspecific/com.chrome.devtools.json"
|
|
2767
2649
|
]);
|
|
2768
2650
|
async function dev(rootProjectDir, options) {
|
|
2769
2651
|
process.env.NODE_ENV = "development";
|
|
2770
|
-
const rootDir =
|
|
2652
|
+
const rootDir = path11.resolve(rootProjectDir || process.cwd());
|
|
2771
2653
|
const defaultPort = parseInt(process.env.PORT || "4007");
|
|
2772
2654
|
const host = options?.host || "localhost";
|
|
2773
2655
|
const port = await findOpenPort(defaultPort, defaultPort + 10);
|
|
@@ -2795,7 +2677,7 @@ async function dev(rootProjectDir, options) {
|
|
|
2795
2677
|
"rootConfigDependencies"
|
|
2796
2678
|
);
|
|
2797
2679
|
const dependencies = [
|
|
2798
|
-
|
|
2680
|
+
path11.resolve(rootDir, "root.config.ts"),
|
|
2799
2681
|
...rootConfigDependencies
|
|
2800
2682
|
];
|
|
2801
2683
|
viteServer.watcher.add(dependencies);
|
|
@@ -2823,7 +2705,7 @@ ${dim5("\u2503")} root.config.ts changed. restarting server...`
|
|
|
2823
2705
|
await start2();
|
|
2824
2706
|
}
|
|
2825
2707
|
async function createDevServer(options) {
|
|
2826
|
-
const rootDir =
|
|
2708
|
+
const rootDir = path11.resolve(options?.rootDir || process.cwd());
|
|
2827
2709
|
const { rootConfig, dependencies } = await loadRootConfigWithDeps(rootDir, {
|
|
2828
2710
|
command: "dev"
|
|
2829
2711
|
});
|
|
@@ -2838,6 +2720,7 @@ async function createDevServer(options) {
|
|
|
2838
2720
|
});
|
|
2839
2721
|
server.set("viteServer", viteServer);
|
|
2840
2722
|
server.use(rootProjectMiddleware({ rootConfig }));
|
|
2723
|
+
server.use(securityHeadersMiddleware({ rootConfig }));
|
|
2841
2724
|
server.use(viteMiddleware);
|
|
2842
2725
|
server.use(hooksMiddleware());
|
|
2843
2726
|
const sessionCookieSecret = getSessionCookieSecret(rootConfig, rootDir);
|
|
@@ -2859,7 +2742,7 @@ async function createDevServer(options) {
|
|
|
2859
2742
|
if (rootConfig.server?.headers) {
|
|
2860
2743
|
server.use(headersMiddleware({ rootConfig }));
|
|
2861
2744
|
}
|
|
2862
|
-
const publicDir =
|
|
2745
|
+
const publicDir = path11.join(rootDir, "public");
|
|
2863
2746
|
if (await dirExists(publicDir)) {
|
|
2864
2747
|
server.use(rootPublicDirMiddleware({ publicDir, viteServer }));
|
|
2865
2748
|
}
|
|
@@ -2887,10 +2770,10 @@ async function createViteMiddleware(options) {
|
|
|
2887
2770
|
return sourceFile.relPath;
|
|
2888
2771
|
});
|
|
2889
2772
|
const bundleScripts = [];
|
|
2890
|
-
if (await isDirectory(
|
|
2891
|
-
const bundleFiles = await
|
|
2773
|
+
if (await isDirectory(path11.join(rootDir, "bundles"))) {
|
|
2774
|
+
const bundleFiles = await glob3("bundles/*", { cwd: rootDir });
|
|
2892
2775
|
bundleFiles.forEach((file) => {
|
|
2893
|
-
const parts =
|
|
2776
|
+
const parts = path11.parse(file);
|
|
2894
2777
|
if (isJsFile(parts.base)) {
|
|
2895
2778
|
bundleScripts.push(file);
|
|
2896
2779
|
}
|
|
@@ -2907,7 +2790,7 @@ async function createViteMiddleware(options) {
|
|
|
2907
2790
|
optimizeDeps
|
|
2908
2791
|
});
|
|
2909
2792
|
function isInElementsDir(changedFilePath) {
|
|
2910
|
-
const filePath =
|
|
2793
|
+
const filePath = path11.resolve(changedFilePath);
|
|
2911
2794
|
const elementsDirs = getElementsDirs(rootConfig, pods);
|
|
2912
2795
|
return elementsDirs.some((dirPath) => filePath.startsWith(dirPath));
|
|
2913
2796
|
}
|
|
@@ -2926,7 +2809,7 @@ async function createViteMiddleware(options) {
|
|
|
2926
2809
|
const viteMiddleware = async (req, res, next) => {
|
|
2927
2810
|
try {
|
|
2928
2811
|
req.viteServer = viteServer;
|
|
2929
|
-
const renderModulePath =
|
|
2812
|
+
const renderModulePath = path11.resolve(__dirname4, "./render.js");
|
|
2930
2813
|
const render = await viteServer.ssrLoadModule(
|
|
2931
2814
|
renderModulePath
|
|
2932
2815
|
);
|
|
@@ -2950,7 +2833,7 @@ function rootPublicDirMiddleware(options) {
|
|
|
2950
2833
|
handler = sirv(publicDir, sirvOptions);
|
|
2951
2834
|
}, 1e3);
|
|
2952
2835
|
function isInPublicDir(changedFilePath) {
|
|
2953
|
-
const filePath =
|
|
2836
|
+
const filePath = path11.resolve(changedFilePath);
|
|
2954
2837
|
return filePath.startsWith(publicDir);
|
|
2955
2838
|
}
|
|
2956
2839
|
const watcher = options.viteServer.watcher;
|
|
@@ -2982,7 +2865,7 @@ function rootDevServer404Middleware() {
|
|
|
2982
2865
|
}
|
|
2983
2866
|
if (req.renderer) {
|
|
2984
2867
|
const url = req.path;
|
|
2985
|
-
const ext =
|
|
2868
|
+
const ext = path11.extname(url);
|
|
2986
2869
|
if (!ext) {
|
|
2987
2870
|
const renderer = req.renderer;
|
|
2988
2871
|
const data = await renderer.renderDevServer404(req);
|
|
@@ -3000,7 +2883,7 @@ function rootDevServer500Middleware() {
|
|
|
3000
2883
|
console.error(String(err.stack || err));
|
|
3001
2884
|
if (req.renderer) {
|
|
3002
2885
|
const url = req.path;
|
|
3003
|
-
const ext =
|
|
2886
|
+
const ext = path11.extname(url);
|
|
3004
2887
|
if (!ext) {
|
|
3005
2888
|
const renderer = req.renderer;
|
|
3006
2889
|
const data = await renderer.renderDevServer500(req, err);
|
|
@@ -3026,7 +2909,7 @@ function debounce(fn, timeout) {
|
|
|
3026
2909
|
|
|
3027
2910
|
// src/cli/gae-deploy.ts
|
|
3028
2911
|
import { execSync } from "node:child_process";
|
|
3029
|
-
import
|
|
2912
|
+
import fs7 from "node:fs";
|
|
3030
2913
|
import yaml from "js-yaml";
|
|
3031
2914
|
async function gaeDeploy(appDir, options) {
|
|
3032
2915
|
if (!appDir) {
|
|
@@ -3040,10 +2923,10 @@ async function gaeDeploy(appDir, options) {
|
|
|
3040
2923
|
}
|
|
3041
2924
|
process.chdir(appDir);
|
|
3042
2925
|
const appYamlPath = "app.yaml";
|
|
3043
|
-
if (!
|
|
2926
|
+
if (!fs7.existsSync(appYamlPath)) {
|
|
3044
2927
|
throw new Error(`[gae-deplopy] Missing: ${appYamlPath}`);
|
|
3045
2928
|
}
|
|
3046
|
-
const appYaml = yaml.load(
|
|
2929
|
+
const appYaml = yaml.load(fs7.readFileSync(appYamlPath, "utf8"));
|
|
3047
2930
|
const service = appYaml.service;
|
|
3048
2931
|
if (!service) {
|
|
3049
2932
|
throw new Error(
|
|
@@ -3069,7 +2952,7 @@ async function gaeDeploy(appDir, options) {
|
|
|
3069
2952
|
{ stdio: "inherit" }
|
|
3070
2953
|
);
|
|
3071
2954
|
if (backupAppYaml) {
|
|
3072
|
-
|
|
2955
|
+
fs7.copyFileSync(backupAppYaml, "app.yaml");
|
|
3073
2956
|
}
|
|
3074
2957
|
if (options?.healthcheckUrl) {
|
|
3075
2958
|
const healthcheckPassed = await testHealth(
|
|
@@ -3156,8 +3039,8 @@ function testIsEnvPlaceholder(envValue) {
|
|
|
3156
3039
|
}
|
|
3157
3040
|
function updateAppYamlEnv(appYamlPath, appYaml) {
|
|
3158
3041
|
const backupAppYaml = `${appYamlPath}.bak`;
|
|
3159
|
-
|
|
3160
|
-
let content =
|
|
3042
|
+
fs7.copyFileSync(appYamlPath, backupAppYaml);
|
|
3043
|
+
let content = fs7.readFileSync(appYamlPath, "utf8");
|
|
3161
3044
|
const envVars = appYaml.env_variables;
|
|
3162
3045
|
Object.entries(envVars).forEach(([envVar, envValue]) => {
|
|
3163
3046
|
if (testIsEnvPlaceholder(envValue)) {
|
|
@@ -3170,7 +3053,7 @@ function updateAppYamlEnv(appYamlPath, appYaml) {
|
|
|
3170
3053
|
}
|
|
3171
3054
|
}
|
|
3172
3055
|
});
|
|
3173
|
-
|
|
3056
|
+
fs7.writeFileSync(appYamlPath, content, "utf8");
|
|
3174
3057
|
return backupAppYaml;
|
|
3175
3058
|
}
|
|
3176
3059
|
function getTimestamp() {
|
|
@@ -3194,15 +3077,14 @@ function testManagedVersion(service, appInfo, prefix) {
|
|
|
3194
3077
|
}
|
|
3195
3078
|
|
|
3196
3079
|
// src/cli/preview.ts
|
|
3197
|
-
import
|
|
3198
|
-
import compression from "compression";
|
|
3080
|
+
import path12 from "node:path";
|
|
3199
3081
|
import cookieParser2 from "cookie-parser";
|
|
3200
3082
|
import { default as express2 } from "express";
|
|
3201
3083
|
import { dim as dim6 } from "kleur/colors";
|
|
3202
3084
|
import sirv2 from "sirv";
|
|
3203
3085
|
async function preview(rootProjectDir, options) {
|
|
3204
3086
|
process.env.NODE_ENV = "development";
|
|
3205
|
-
const rootDir =
|
|
3087
|
+
const rootDir = path12.resolve(rootProjectDir || process.cwd());
|
|
3206
3088
|
const server = await createPreviewServer({ rootDir });
|
|
3207
3089
|
const port = parseInt(process.env.PORT || "4007");
|
|
3208
3090
|
const host = options?.host || "localhost";
|
|
@@ -3216,11 +3098,12 @@ async function preview(rootProjectDir, options) {
|
|
|
3216
3098
|
async function createPreviewServer(options) {
|
|
3217
3099
|
const rootDir = options.rootDir;
|
|
3218
3100
|
const rootConfig = await loadBundledConfig(rootDir, { command: "preview" });
|
|
3219
|
-
const distDir =
|
|
3101
|
+
const distDir = path12.join(rootDir, "dist");
|
|
3220
3102
|
const server = express2();
|
|
3221
3103
|
server.disable("x-powered-by");
|
|
3222
|
-
server.use(
|
|
3104
|
+
server.use(compressionMiddleware());
|
|
3223
3105
|
server.use(rootProjectMiddleware({ rootConfig }));
|
|
3106
|
+
server.use(securityHeadersMiddleware({ rootConfig }));
|
|
3224
3107
|
server.use(await rootPreviewRendererMiddleware({ rootConfig, distDir }));
|
|
3225
3108
|
server.use(hooksMiddleware());
|
|
3226
3109
|
const sessionCookieSecret = getSessionCookieSecret(rootConfig, rootDir);
|
|
@@ -3242,7 +3125,7 @@ async function createPreviewServer(options) {
|
|
|
3242
3125
|
if (rootConfig.server?.headers) {
|
|
3243
3126
|
server.use(headersMiddleware({ rootConfig }));
|
|
3244
3127
|
}
|
|
3245
|
-
const publicDir =
|
|
3128
|
+
const publicDir = path12.join(distDir, "html");
|
|
3246
3129
|
server.use(sirv2(publicDir, { dev: false }));
|
|
3247
3130
|
server.use(trailingSlashMiddleware({ rootConfig }));
|
|
3248
3131
|
server.use(rootPreviewServerMiddleware());
|
|
@@ -3261,14 +3144,14 @@ async function createPreviewServer(options) {
|
|
|
3261
3144
|
}
|
|
3262
3145
|
async function rootPreviewRendererMiddleware(options) {
|
|
3263
3146
|
const { distDir, rootConfig } = options;
|
|
3264
|
-
const render = await import(
|
|
3265
|
-
const manifestPath2 =
|
|
3147
|
+
const render = await import(path12.join(distDir, "server/render.js"));
|
|
3148
|
+
const manifestPath2 = path12.join(distDir, ".root/manifest.json");
|
|
3266
3149
|
if (!await fileExists(manifestPath2)) {
|
|
3267
3150
|
throw new Error(
|
|
3268
3151
|
`could not find ${manifestPath2}. run \`root build\` before \`root preview\`.`
|
|
3269
3152
|
);
|
|
3270
3153
|
}
|
|
3271
|
-
const elementGraphJsonPath =
|
|
3154
|
+
const elementGraphJsonPath = path12.join(distDir, ".root/elements.json");
|
|
3272
3155
|
if (!await fileExists(elementGraphJsonPath)) {
|
|
3273
3156
|
throw new Error(
|
|
3274
3157
|
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root preview\`.`
|
|
@@ -3308,7 +3191,7 @@ function rootPreviewServer404Middleware() {
|
|
|
3308
3191
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
3309
3192
|
if (req.renderer) {
|
|
3310
3193
|
const url = req.path;
|
|
3311
|
-
const ext =
|
|
3194
|
+
const ext = path12.extname(url);
|
|
3312
3195
|
if (!ext) {
|
|
3313
3196
|
const renderer = req.renderer;
|
|
3314
3197
|
const data = await renderer.render404({ currentPath: url });
|
|
@@ -3326,7 +3209,7 @@ function rootPreviewServer500Middleware() {
|
|
|
3326
3209
|
console.error(String(err.stack || err));
|
|
3327
3210
|
if (req.renderer) {
|
|
3328
3211
|
const url = req.path;
|
|
3329
|
-
const ext =
|
|
3212
|
+
const ext = path12.extname(url);
|
|
3330
3213
|
if (!ext) {
|
|
3331
3214
|
const renderer = req.renderer;
|
|
3332
3215
|
const data = await renderer.renderDevServer500(req, err);
|
|
@@ -3340,15 +3223,14 @@ function rootPreviewServer500Middleware() {
|
|
|
3340
3223
|
}
|
|
3341
3224
|
|
|
3342
3225
|
// src/cli/start.ts
|
|
3343
|
-
import
|
|
3344
|
-
import compression2 from "compression";
|
|
3226
|
+
import path13 from "node:path";
|
|
3345
3227
|
import cookieParser3 from "cookie-parser";
|
|
3346
3228
|
import { default as express3 } from "express";
|
|
3347
3229
|
import { dim as dim7 } from "kleur/colors";
|
|
3348
3230
|
import sirv3 from "sirv";
|
|
3349
3231
|
async function start(rootProjectDir, options) {
|
|
3350
3232
|
process.env.NODE_ENV = "production";
|
|
3351
|
-
const rootDir =
|
|
3233
|
+
const rootDir = path13.resolve(rootProjectDir || process.cwd());
|
|
3352
3234
|
const server = await createProdServer({ rootDir });
|
|
3353
3235
|
const port = parseInt(process.env.PORT || "4007");
|
|
3354
3236
|
const host = options?.host || "localhost";
|
|
@@ -3362,11 +3244,12 @@ async function start(rootProjectDir, options) {
|
|
|
3362
3244
|
async function createProdServer(options) {
|
|
3363
3245
|
const rootDir = options.rootDir;
|
|
3364
3246
|
const rootConfig = await loadBundledConfig(rootDir, { command: "start" });
|
|
3365
|
-
const distDir =
|
|
3247
|
+
const distDir = path13.join(rootDir, "dist");
|
|
3366
3248
|
const server = express3();
|
|
3367
3249
|
server.disable("x-powered-by");
|
|
3368
|
-
server.use(
|
|
3250
|
+
server.use(compressionMiddleware());
|
|
3369
3251
|
server.use(rootProjectMiddleware({ rootConfig }));
|
|
3252
|
+
server.use(securityHeadersMiddleware({ rootConfig }));
|
|
3370
3253
|
server.use(await rootProdRendererMiddleware({ rootConfig, distDir }));
|
|
3371
3254
|
server.use(hooksMiddleware());
|
|
3372
3255
|
const sessionCookieSecret = getSessionCookieSecret(rootConfig, rootDir);
|
|
@@ -3388,7 +3271,7 @@ async function createProdServer(options) {
|
|
|
3388
3271
|
if (rootConfig.server?.headers) {
|
|
3389
3272
|
server.use(headersMiddleware({ rootConfig }));
|
|
3390
3273
|
}
|
|
3391
|
-
const publicDir =
|
|
3274
|
+
const publicDir = path13.join(distDir, "html");
|
|
3392
3275
|
server.use(sirv3(publicDir, { dev: false }));
|
|
3393
3276
|
server.use(trailingSlashMiddleware({ rootConfig }));
|
|
3394
3277
|
server.use(rootProdServerMiddleware());
|
|
@@ -3407,14 +3290,14 @@ async function createProdServer(options) {
|
|
|
3407
3290
|
}
|
|
3408
3291
|
async function rootProdRendererMiddleware(options) {
|
|
3409
3292
|
const { distDir, rootConfig } = options;
|
|
3410
|
-
const render = await import(
|
|
3411
|
-
const manifestPath2 =
|
|
3293
|
+
const render = await import(path13.join(distDir, "server/render.js"));
|
|
3294
|
+
const manifestPath2 = path13.join(distDir, ".root/manifest.json");
|
|
3412
3295
|
if (!await fileExists(manifestPath2)) {
|
|
3413
3296
|
throw new Error(
|
|
3414
3297
|
`could not find ${manifestPath2}. run \`root build\` before \`root start\`.`
|
|
3415
3298
|
);
|
|
3416
3299
|
}
|
|
3417
|
-
const elementGraphJsonPath =
|
|
3300
|
+
const elementGraphJsonPath = path13.join(distDir, ".root/elements.json");
|
|
3418
3301
|
if (!await fileExists(elementGraphJsonPath)) {
|
|
3419
3302
|
throw new Error(
|
|
3420
3303
|
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root start\`.`
|
|
@@ -3454,7 +3337,7 @@ function rootProdServer404Middleware() {
|
|
|
3454
3337
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
3455
3338
|
if (req.renderer) {
|
|
3456
3339
|
const url = req.path;
|
|
3457
|
-
const ext =
|
|
3340
|
+
const ext = path13.extname(url);
|
|
3458
3341
|
if (!ext) {
|
|
3459
3342
|
const renderer = req.renderer;
|
|
3460
3343
|
const data = await renderer.render404({ currentPath: url });
|
|
@@ -3472,7 +3355,7 @@ function rootProdServer500Middleware() {
|
|
|
3472
3355
|
console.error(String(err.stack || err));
|
|
3473
3356
|
if (req.renderer) {
|
|
3474
3357
|
const url = req.path;
|
|
3475
|
-
const ext =
|
|
3358
|
+
const ext = path13.extname(url);
|
|
3476
3359
|
if (!ext) {
|
|
3477
3360
|
const renderer = req.renderer;
|
|
3478
3361
|
const data = await renderer.renderError(err);
|
|
@@ -3513,6 +3396,9 @@ var CliRunner = class {
|
|
|
3513
3396
|
"-c, --concurrency <num>",
|
|
3514
3397
|
"number of files to build concurrently",
|
|
3515
3398
|
"10"
|
|
3399
|
+
).option(
|
|
3400
|
+
"--threads [num]",
|
|
3401
|
+
'renders pages using worker threads; pass a number for exactly N workers, or omit the value (or pass "auto") to pick based on cpu cores and page count'
|
|
3516
3402
|
).option(
|
|
3517
3403
|
"--filter <urlPathRegex>",
|
|
3518
3404
|
'builds the url paths that match the given regex, e.g. "/products/.*"',
|
|
@@ -3579,4 +3465,4 @@ export {
|
|
|
3579
3465
|
createProdServer,
|
|
3580
3466
|
CliRunner
|
|
3581
3467
|
};
|
|
3582
|
-
//# sourceMappingURL=chunk-
|
|
3468
|
+
//# sourceMappingURL=chunk-E4F6CMO3.js.map
|