@blinkk/root 3.0.5 → 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-VQPDCDKL.js → chunk-E4F6CMO3.js} +469 -536
- package/dist/chunk-E4F6CMO3.js.map +7 -0
- package/dist/{chunk-6P3B7ZXL.js → chunk-I3RCAIW7.js} +1 -62
- 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/config.d.ts +11 -3
- package/dist/core/security.d.ts +14 -0
- package/dist/core.js.map +2 -2
- package/dist/functions.js +8 -4
- package/dist/functions.js.map +1 -1
- package/dist/jsx/types.d.ts +1 -0
- 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/asset-map/build-asset-map.d.ts +11 -1
- package/dist/render/html-transform.d.ts +15 -0
- package/dist/render/render.d.ts +15 -9
- package/dist/render.js +45 -104
- package/dist/render.js.map +2 -2
- package/package.json +2 -2
- package/dist/chunk-6NBKAR5Y.js.map +0 -7
- package/dist/chunk-6P3B7ZXL.js.map +0 -7
- package/dist/chunk-7PSEEE6C.js.map +0 -7
- package/dist/chunk-VQPDCDKL.js.map +0 -7
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "./chunk-6P3B7ZXL.js";
|
|
2
|
+
collectPods,
|
|
3
|
+
createViteServer,
|
|
4
|
+
preactToRootJsxPlugin,
|
|
5
|
+
rootPodsVitePlugin
|
|
6
|
+
} from "./chunk-YU22SAIG.js";
|
|
8
7
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
RouteTrie
|
|
9
|
+
} from "./chunk-I3RCAIW7.js";
|
|
10
|
+
import {
|
|
11
|
+
BuildAssetMap,
|
|
12
|
+
ElementGraph,
|
|
13
|
+
buildPage,
|
|
14
|
+
getElements,
|
|
15
|
+
getElementsDirs
|
|
16
|
+
} from "./chunk-M3E4RKS7.js";
|
|
14
17
|
import {
|
|
15
18
|
bundleRootConfig,
|
|
16
|
-
collectPods,
|
|
17
19
|
copyDir,
|
|
18
20
|
copyGlob,
|
|
19
|
-
createViteServer,
|
|
20
21
|
dirExists,
|
|
21
22
|
directoryContains,
|
|
22
23
|
fileExists,
|
|
@@ -28,144 +29,35 @@ import {
|
|
|
28
29
|
loadRootConfig,
|
|
29
30
|
loadRootConfigWithDeps,
|
|
30
31
|
makeDir,
|
|
31
|
-
preactToRootJsxPlugin,
|
|
32
32
|
rmDir,
|
|
33
|
-
rootPodsVitePlugin,
|
|
34
33
|
writeFile,
|
|
35
34
|
writeJson
|
|
36
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-KHO3HMX6.js";
|
|
37
36
|
import {
|
|
38
37
|
configureServerPlugins,
|
|
39
38
|
getVitePlugins
|
|
40
39
|
} from "./chunk-XSNCF7WU.js";
|
|
40
|
+
import {
|
|
41
|
+
compressionMiddleware,
|
|
42
|
+
headersMiddleware,
|
|
43
|
+
rootProjectMiddleware,
|
|
44
|
+
securityHeadersMiddleware,
|
|
45
|
+
sessionMiddleware,
|
|
46
|
+
trailingSlashMiddleware
|
|
47
|
+
} from "./chunk-TM6QRBGS.js";
|
|
41
48
|
|
|
42
49
|
// src/cli/cli.ts
|
|
43
50
|
import { Command, InvalidArgumentError } from "commander";
|
|
44
51
|
import { bgGreen, black } from "kleur/colors";
|
|
45
52
|
|
|
46
53
|
// src/cli/build.ts
|
|
47
|
-
import
|
|
48
|
-
import
|
|
54
|
+
import os from "node:os";
|
|
55
|
+
import path2 from "node:path";
|
|
56
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
49
57
|
import fsExtra from "fs-extra";
|
|
50
58
|
import { dim as dim2, cyan } from "kleur/colors";
|
|
51
|
-
import glob2 from "tiny-glob";
|
|
52
|
-
import { build as viteBuild } from "vite";
|
|
53
|
-
|
|
54
|
-
// src/node/element-graph.ts
|
|
55
|
-
import fs from "node:fs";
|
|
56
|
-
import path from "node:path";
|
|
57
59
|
import glob from "tiny-glob";
|
|
58
|
-
import {
|
|
59
|
-
var ElementGraph = class _ElementGraph {
|
|
60
|
-
/**
|
|
61
|
-
* Element tagName => sourceFile.
|
|
62
|
-
*/
|
|
63
|
-
sourceFiles = {};
|
|
64
|
-
/**
|
|
65
|
-
* Element tagName => set of element tagName dependencies.
|
|
66
|
-
*/
|
|
67
|
-
deps = {};
|
|
68
|
-
constructor(sourceFiles) {
|
|
69
|
-
this.sourceFiles = sourceFiles;
|
|
70
|
-
}
|
|
71
|
-
toJson() {
|
|
72
|
-
for (const tagName in this.sourceFiles) {
|
|
73
|
-
this.deps[tagName] ??= this.parseDepsFromSource(tagName);
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
sourceFiles: this.sourceFiles,
|
|
77
|
-
deps: this.deps
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
static fromJson(data) {
|
|
81
|
-
const graph = new _ElementGraph(data.sourceFiles);
|
|
82
|
-
graph.deps = data.deps;
|
|
83
|
-
return graph;
|
|
84
|
-
}
|
|
85
|
-
getDeps(tagName, visited) {
|
|
86
|
-
visited ??= /* @__PURE__ */ new Set();
|
|
87
|
-
if (visited.has(tagName)) {
|
|
88
|
-
return [];
|
|
89
|
-
}
|
|
90
|
-
visited.add(tagName);
|
|
91
|
-
this.deps[tagName] ??= this.parseDepsFromSource(tagName);
|
|
92
|
-
const deps = new Set(this.deps[tagName]);
|
|
93
|
-
for (const depTagName of this.deps[tagName]) {
|
|
94
|
-
for (const childDep of this.getDeps(depTagName, visited)) {
|
|
95
|
-
deps.add(childDep);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return Array.from(deps);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Parses an element's source file for usage of other custom elements.
|
|
102
|
-
*/
|
|
103
|
-
parseDepsFromSource(tagName) {
|
|
104
|
-
const srcFile = this.sourceFiles[tagName];
|
|
105
|
-
if (!srcFile) {
|
|
106
|
-
throw new Error(`could not find file path for tagName <${tagName}>`);
|
|
107
|
-
}
|
|
108
|
-
const src = fs.readFileSync(srcFile.filePath, "utf-8");
|
|
109
|
-
const tagNames = parseTagNames(src);
|
|
110
|
-
const deps = /* @__PURE__ */ new Set();
|
|
111
|
-
for (const depTagName of tagNames) {
|
|
112
|
-
if (depTagName !== tagName && depTagName in this.sourceFiles) {
|
|
113
|
-
deps.add(depTagName);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return Array.from(deps);
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
async function getElements(rootConfig, pods) {
|
|
120
|
-
const rootDir = rootConfig.rootDir;
|
|
121
|
-
const elementsDirs = getElementsDirs(rootConfig, pods);
|
|
122
|
-
const excludePatterns = rootConfig.elements?.exclude || [];
|
|
123
|
-
const excludeElement = (moduleId) => {
|
|
124
|
-
return excludePatterns.some((pattern) => Boolean(moduleId.match(pattern)));
|
|
125
|
-
};
|
|
126
|
-
const elementFilePaths = {};
|
|
127
|
-
for (const dirPath of elementsDirs) {
|
|
128
|
-
if (await isDirectory(dirPath)) {
|
|
129
|
-
const files = await glob("**/*", { cwd: dirPath });
|
|
130
|
-
files.forEach((file) => {
|
|
131
|
-
const parts = path.parse(file);
|
|
132
|
-
if (isJsFile(parts.base) && isValidTagName(parts.name)) {
|
|
133
|
-
const tagName = parts.name;
|
|
134
|
-
const filePath = path.join(dirPath, file);
|
|
135
|
-
const relPath = path.relative(rootDir, filePath);
|
|
136
|
-
if (!excludeElement(relPath)) {
|
|
137
|
-
elementFilePaths[tagName] = { filePath, relPath };
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const graph = new ElementGraph(elementFilePaths);
|
|
144
|
-
return graph;
|
|
145
|
-
}
|
|
146
|
-
function getElementsDirs(rootConfig, pods) {
|
|
147
|
-
const rootDir = rootConfig.rootDir;
|
|
148
|
-
const workspaceRoot = searchForWorkspaceRoot(rootDir);
|
|
149
|
-
const elementsDirs = [path.join(rootDir, "elements")];
|
|
150
|
-
const elementsInclude = rootConfig.elements?.include || [];
|
|
151
|
-
for (const dirPath of elementsInclude) {
|
|
152
|
-
const elementsDir = path.resolve(rootDir, dirPath);
|
|
153
|
-
if (!directoryContains(rootDir, elementsDir)) {
|
|
154
|
-
throw new Error(
|
|
155
|
-
`the elements dir (${dirPath}) should be within the project's workspace (${workspaceRoot})`
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
elementsDirs.push(elementsDir);
|
|
159
|
-
}
|
|
160
|
-
if (pods) {
|
|
161
|
-
for (const pod of pods) {
|
|
162
|
-
for (const dir of pod.elementsDirs) {
|
|
163
|
-
elementsDirs.push(dir);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return elementsDirs;
|
|
168
|
-
}
|
|
60
|
+
import { build as viteBuild } from "vite";
|
|
169
61
|
|
|
170
62
|
// src/node/vite-plugin-prune-empty-chunks.ts
|
|
171
63
|
import { dim } from "kleur/colors";
|
|
@@ -232,167 +124,6 @@ function removeSideEffectImport(code, fileName) {
|
|
|
232
124
|
return code.replace(re, "");
|
|
233
125
|
}
|
|
234
126
|
|
|
235
|
-
// src/render/asset-map/build-asset-map.ts
|
|
236
|
-
import fs2 from "node:fs";
|
|
237
|
-
import path2 from "node:path";
|
|
238
|
-
var BuildAssetMap = class _BuildAssetMap {
|
|
239
|
-
rootConfig;
|
|
240
|
-
srcToAsset;
|
|
241
|
-
constructor(rootConfig) {
|
|
242
|
-
this.rootConfig = rootConfig;
|
|
243
|
-
this.srcToAsset = /* @__PURE__ */ new Map();
|
|
244
|
-
}
|
|
245
|
-
async get(src) {
|
|
246
|
-
const asset = this.srcToAsset.get(src);
|
|
247
|
-
if (asset) {
|
|
248
|
-
return asset;
|
|
249
|
-
}
|
|
250
|
-
const realSrc = realPathRelativeTo(this.rootConfig.rootDir, src);
|
|
251
|
-
if (realSrc !== src) {
|
|
252
|
-
const asset2 = this.srcToAsset.get(realSrc);
|
|
253
|
-
if (asset2) {
|
|
254
|
-
return asset2;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
console.log(`could not find build asset: ${src}`);
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
add(asset) {
|
|
261
|
-
this.srcToAsset.set(asset.src, asset);
|
|
262
|
-
}
|
|
263
|
-
toJson() {
|
|
264
|
-
const result = {};
|
|
265
|
-
for (const src of this.srcToAsset.keys()) {
|
|
266
|
-
result[src] = this.srcToAsset.get(src).toJson();
|
|
267
|
-
}
|
|
268
|
-
return result;
|
|
269
|
-
}
|
|
270
|
-
static fromViteManifest(rootConfig, clientManifest, elementsGraph) {
|
|
271
|
-
const assetMap = new _BuildAssetMap(rootConfig);
|
|
272
|
-
const elementFiles = /* @__PURE__ */ new Set();
|
|
273
|
-
Object.values(elementsGraph.sourceFiles).forEach((elementSource) => {
|
|
274
|
-
elementFiles.add(elementSource.relPath);
|
|
275
|
-
const realSrc = realPathRelativeTo(
|
|
276
|
-
rootConfig.rootDir,
|
|
277
|
-
elementSource.relPath
|
|
278
|
-
);
|
|
279
|
-
if (realSrc !== elementSource.filePath) {
|
|
280
|
-
elementFiles.add(realSrc);
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
Object.keys(clientManifest).forEach((manifestKey) => {
|
|
284
|
-
const src = manifestKey;
|
|
285
|
-
const manifestChunk = clientManifest[manifestKey];
|
|
286
|
-
const isElement = elementFiles.has(src);
|
|
287
|
-
const assetUrl = src.startsWith("routes/") && isJsFile(src) ? "" : `/${manifestChunk.file}`;
|
|
288
|
-
const assetData = {
|
|
289
|
-
src,
|
|
290
|
-
assetUrl,
|
|
291
|
-
importedModules: manifestChunk.imports || [],
|
|
292
|
-
importedCss: (manifestChunk.css || []).map((relPath) => `/${relPath}`),
|
|
293
|
-
isElement
|
|
294
|
-
};
|
|
295
|
-
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
296
|
-
});
|
|
297
|
-
return assetMap;
|
|
298
|
-
}
|
|
299
|
-
static fromRootManifest(rootConfig, rootManifest) {
|
|
300
|
-
const assetMap = new _BuildAssetMap(rootConfig);
|
|
301
|
-
Object.keys(rootManifest).forEach((moduleId) => {
|
|
302
|
-
const assetData = rootManifest[moduleId];
|
|
303
|
-
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
304
|
-
});
|
|
305
|
-
return assetMap;
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
function realPathRelativeTo(rootDir, src) {
|
|
309
|
-
const fullPath = path2.resolve(rootDir, src);
|
|
310
|
-
if (!fs2.existsSync(fullPath)) {
|
|
311
|
-
return src;
|
|
312
|
-
}
|
|
313
|
-
const realpath = fs2.realpathSync(path2.resolve(rootDir, src));
|
|
314
|
-
return path2.relative(rootDir, realpath);
|
|
315
|
-
}
|
|
316
|
-
var BuildAsset = class {
|
|
317
|
-
src;
|
|
318
|
-
assetUrl;
|
|
319
|
-
assetMap;
|
|
320
|
-
importedModules;
|
|
321
|
-
importedCss;
|
|
322
|
-
isElement;
|
|
323
|
-
constructor(assetMap, assetData) {
|
|
324
|
-
this.assetMap = assetMap;
|
|
325
|
-
this.src = assetData.src;
|
|
326
|
-
this.assetUrl = assetData.assetUrl;
|
|
327
|
-
this.importedModules = assetData.importedModules;
|
|
328
|
-
this.importedCss = assetData.importedCss;
|
|
329
|
-
this.isElement = assetData.isElement;
|
|
330
|
-
}
|
|
331
|
-
async getCssDeps() {
|
|
332
|
-
const visited = /* @__PURE__ */ new Set();
|
|
333
|
-
const deps = /* @__PURE__ */ new Set();
|
|
334
|
-
await this.collectCss(this, deps, visited);
|
|
335
|
-
return Array.from(deps);
|
|
336
|
-
}
|
|
337
|
-
async getJsDeps() {
|
|
338
|
-
const visited = /* @__PURE__ */ new Set();
|
|
339
|
-
const deps = /* @__PURE__ */ new Set();
|
|
340
|
-
await this.collectJs(this, deps, visited);
|
|
341
|
-
return Array.from(deps);
|
|
342
|
-
}
|
|
343
|
-
async collectJs(asset, urls, visited) {
|
|
344
|
-
if (!asset) {
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
if (!asset.src) {
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
if (visited.has(asset.src)) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
visited.add(asset.src);
|
|
354
|
-
if (asset.isElement) {
|
|
355
|
-
urls.add(asset.assetUrl);
|
|
356
|
-
}
|
|
357
|
-
await Promise.all(
|
|
358
|
-
asset.importedModules.map(async (src) => {
|
|
359
|
-
const importedAsset = await this.assetMap.get(src);
|
|
360
|
-
this.collectJs(importedAsset, urls, visited);
|
|
361
|
-
})
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
async collectCss(asset, urls, visited) {
|
|
365
|
-
if (!asset) {
|
|
366
|
-
return;
|
|
367
|
-
}
|
|
368
|
-
if (!asset.src) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
if (visited.has(asset.src)) {
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
visited.add(asset.src);
|
|
375
|
-
if (asset.importedCss) {
|
|
376
|
-
asset.importedCss.forEach((cssUrl) => urls.add(cssUrl));
|
|
377
|
-
}
|
|
378
|
-
await Promise.all(
|
|
379
|
-
asset.importedModules.map(async (moduleId) => {
|
|
380
|
-
const importedAsset = await this.assetMap.get(moduleId);
|
|
381
|
-
this.collectCss(importedAsset, urls, visited);
|
|
382
|
-
})
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
toJson() {
|
|
386
|
-
return {
|
|
387
|
-
src: this.src,
|
|
388
|
-
assetUrl: this.assetUrl,
|
|
389
|
-
importedModules: this.importedModules,
|
|
390
|
-
importedCss: this.importedCss,
|
|
391
|
-
isElement: this.isElement
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
};
|
|
395
|
-
|
|
396
127
|
// src/utils/batch.ts
|
|
397
128
|
async function batchAsyncCalls(data, concurrency, asyncFunction) {
|
|
398
129
|
const result = new Array(data.length);
|
|
@@ -411,14 +142,144 @@ async function batchAsyncCalls(data, concurrency, asyncFunction) {
|
|
|
411
142
|
return result;
|
|
412
143
|
}
|
|
413
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
|
+
|
|
414
275
|
// src/cli/build.ts
|
|
415
|
-
var
|
|
276
|
+
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
416
277
|
async function build(rootProjectDir, options) {
|
|
417
278
|
const mode = options?.mode || "production";
|
|
418
279
|
process.env.NODE_ENV = mode;
|
|
419
|
-
const rootDir =
|
|
280
|
+
const rootDir = path2.resolve(rootProjectDir || process.cwd());
|
|
420
281
|
const rootConfig = await loadRootConfig(rootDir, { command: "build" });
|
|
421
|
-
const distDir =
|
|
282
|
+
const distDir = path2.join(rootDir, "dist");
|
|
422
283
|
const ssrOnly = options?.ssrOnly || false;
|
|
423
284
|
console.log();
|
|
424
285
|
console.log(`${dim2("\u2503")} project: ${rootDir}`);
|
|
@@ -429,12 +290,12 @@ async function build(rootProjectDir, options) {
|
|
|
429
290
|
await makeDir(distDir);
|
|
430
291
|
const pods = await collectPods(rootConfig);
|
|
431
292
|
const routeFiles = [];
|
|
432
|
-
if (await isDirectory(
|
|
433
|
-
const pageFiles = await
|
|
293
|
+
if (await isDirectory(path2.join(rootDir, "routes"))) {
|
|
294
|
+
const pageFiles = await glob("routes/**/*", { cwd: rootDir });
|
|
434
295
|
pageFiles.forEach((file) => {
|
|
435
|
-
const parts =
|
|
296
|
+
const parts = path2.parse(file);
|
|
436
297
|
if (!parts.name.startsWith("_") && isJsFile(parts.base)) {
|
|
437
|
-
routeFiles.push(
|
|
298
|
+
routeFiles.push(path2.resolve(rootDir, file));
|
|
438
299
|
}
|
|
439
300
|
});
|
|
440
301
|
}
|
|
@@ -448,12 +309,12 @@ async function build(rootProjectDir, options) {
|
|
|
448
309
|
return sourceFile.filePath;
|
|
449
310
|
});
|
|
450
311
|
const bundleScripts = [];
|
|
451
|
-
if (await isDirectory(
|
|
452
|
-
const bundleFiles = await
|
|
312
|
+
if (await isDirectory(path2.join(rootDir, "bundles"))) {
|
|
313
|
+
const bundleFiles = await glob("bundles/*", { cwd: rootDir });
|
|
453
314
|
bundleFiles.forEach((file) => {
|
|
454
|
-
const parts =
|
|
315
|
+
const parts = path2.parse(file);
|
|
455
316
|
if (isJsFile(parts.base)) {
|
|
456
|
-
bundleScripts.push(
|
|
317
|
+
bundleScripts.push(path2.resolve(rootDir, file));
|
|
457
318
|
}
|
|
458
319
|
});
|
|
459
320
|
}
|
|
@@ -483,7 +344,7 @@ async function build(rootProjectDir, options) {
|
|
|
483
344
|
plugins: vitePlugins
|
|
484
345
|
};
|
|
485
346
|
const ssrInput = {
|
|
486
|
-
render:
|
|
347
|
+
render: path2.resolve(__dirname2, "./render.js")
|
|
487
348
|
};
|
|
488
349
|
rootPlugins.forEach((plugin) => {
|
|
489
350
|
if (plugin.ssrInput) {
|
|
@@ -514,7 +375,7 @@ async function build(rootProjectDir, options) {
|
|
|
514
375
|
sanitizeFileName
|
|
515
376
|
}
|
|
516
377
|
},
|
|
517
|
-
outDir:
|
|
378
|
+
outDir: path2.join(distDir, "server"),
|
|
518
379
|
ssr: true,
|
|
519
380
|
ssrManifest: false,
|
|
520
381
|
cssCodeSplit: true,
|
|
@@ -547,7 +408,7 @@ async function build(rootProjectDir, options) {
|
|
|
547
408
|
...viteConfig?.build?.rolldownOptions?.output
|
|
548
409
|
}
|
|
549
410
|
},
|
|
550
|
-
outDir:
|
|
411
|
+
outDir: path2.join(distDir, ".build/routes"),
|
|
551
412
|
ssr: true,
|
|
552
413
|
ssrManifest: false,
|
|
553
414
|
ssrEmitAssets: true,
|
|
@@ -578,7 +439,7 @@ async function build(rootProjectDir, options) {
|
|
|
578
439
|
...viteConfig?.build?.rolldownOptions?.output
|
|
579
440
|
}
|
|
580
441
|
},
|
|
581
|
-
outDir:
|
|
442
|
+
outDir: path2.join(distDir, ".build/client"),
|
|
582
443
|
ssr: false,
|
|
583
444
|
ssrManifest: false,
|
|
584
445
|
manifest: true,
|
|
@@ -591,21 +452,21 @@ async function build(rootProjectDir, options) {
|
|
|
591
452
|
});
|
|
592
453
|
} else {
|
|
593
454
|
await writeFile(
|
|
594
|
-
|
|
455
|
+
path2.join(distDir, ".build/client/.vite/manifest.json"),
|
|
595
456
|
"{}"
|
|
596
457
|
);
|
|
597
458
|
}
|
|
598
|
-
await bundleRootConfig(rootDir,
|
|
459
|
+
await bundleRootConfig(rootDir, path2.join(distDir, "root.config.js"));
|
|
599
460
|
await copyGlob(
|
|
600
461
|
"**/*.css",
|
|
601
|
-
|
|
602
|
-
|
|
462
|
+
path2.join(distDir, ".build/routes"),
|
|
463
|
+
path2.join(distDir, ".build/client")
|
|
603
464
|
);
|
|
604
465
|
const routesManifest = await loadJson(
|
|
605
|
-
|
|
466
|
+
path2.join(distDir, ".build/routes/.vite/manifest.json")
|
|
606
467
|
);
|
|
607
468
|
const clientManifest = await loadJson(
|
|
608
|
-
|
|
469
|
+
path2.join(distDir, ".build/client/.vite/manifest.json")
|
|
609
470
|
);
|
|
610
471
|
function collectRouteCss(asset, cssDeps, visited) {
|
|
611
472
|
if (!asset || !asset.file || visited.has(asset.file)) {
|
|
@@ -634,24 +495,31 @@ async function build(rootProjectDir, options) {
|
|
|
634
495
|
clientManifest[manifestKey] = asset;
|
|
635
496
|
}
|
|
636
497
|
});
|
|
498
|
+
const podRoutes = pods.flatMap(
|
|
499
|
+
(pod) => pod.routeFiles.map((route) => ({
|
|
500
|
+
src: `pod/${pod.name}/${route.relPath}`,
|
|
501
|
+
filePath: route.filePath
|
|
502
|
+
}))
|
|
503
|
+
);
|
|
637
504
|
const assetMap = BuildAssetMap.fromViteManifest(
|
|
638
505
|
rootConfig,
|
|
639
506
|
clientManifest,
|
|
640
|
-
elementGraph
|
|
507
|
+
elementGraph,
|
|
508
|
+
podRoutes
|
|
641
509
|
);
|
|
642
510
|
const rootManifest = assetMap.toJson();
|
|
643
511
|
await writeFile(
|
|
644
|
-
|
|
512
|
+
path2.join(distDir, ".root/manifest.json"),
|
|
645
513
|
JSON.stringify(rootManifest, null, 2)
|
|
646
514
|
);
|
|
647
515
|
const elementGraphJson = elementGraph.toJson();
|
|
648
516
|
await writeFile(
|
|
649
|
-
|
|
517
|
+
path2.join(distDir, ".root/elements.json"),
|
|
650
518
|
JSON.stringify(elementGraphJson, null, 2)
|
|
651
519
|
);
|
|
652
|
-
const buildDir =
|
|
653
|
-
const publicDir =
|
|
654
|
-
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"))) {
|
|
655
523
|
fsExtra.copySync(publicDir, buildDir, { dereference: true });
|
|
656
524
|
} else {
|
|
657
525
|
await makeDir(buildDir);
|
|
@@ -663,8 +531,8 @@ async function build(rootProjectDir, options) {
|
|
|
663
531
|
}
|
|
664
532
|
seenAssets.add(assetUrl);
|
|
665
533
|
const assetRelPath = assetUrl.slice(1);
|
|
666
|
-
const assetFrom =
|
|
667
|
-
const assetTo =
|
|
534
|
+
const assetFrom = path2.join(distDir, ".build/client", assetRelPath);
|
|
535
|
+
const assetTo = path2.join(buildDir, assetRelPath);
|
|
668
536
|
if (!await fileExists(assetFrom)) {
|
|
669
537
|
console.log(`${assetFrom} does not exist`);
|
|
670
538
|
return;
|
|
@@ -694,7 +562,7 @@ async function build(rootProjectDir, options) {
|
|
|
694
562
|
})
|
|
695
563
|
);
|
|
696
564
|
if (!ssrOnly) {
|
|
697
|
-
const render = await import(
|
|
565
|
+
const render = await import(path2.join(distDir, "server/render.js"));
|
|
698
566
|
const renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
699
567
|
let sitemap = await renderer.getSitemap();
|
|
700
568
|
if (options?.filter) {
|
|
@@ -714,97 +582,118 @@ async function build(rootProjectDir, options) {
|
|
|
714
582
|
);
|
|
715
583
|
}
|
|
716
584
|
const domain = rootConfig.domain;
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
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;
|
|
728
623
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
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
|
|
737
650
|
});
|
|
738
|
-
|
|
739
|
-
|
|
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
|
+
);
|
|
740
662
|
}
|
|
741
|
-
|
|
742
|
-
props = { rootConfig, params: sitemapItem.params };
|
|
743
|
-
}
|
|
744
|
-
const result = await routeModule.getStaticContent(props);
|
|
745
|
-
let body;
|
|
746
|
-
if (typeof result === "string") {
|
|
747
|
-
body = result;
|
|
748
|
-
} else if (result && typeof result === "object") {
|
|
749
|
-
body = result.body;
|
|
750
|
-
} else {
|
|
751
|
-
body = "";
|
|
752
|
-
}
|
|
753
|
-
const outFilePath2 = urlPath.slice(1);
|
|
754
|
-
const outPath2 = path3.join(buildDir, outFilePath2);
|
|
755
|
-
await makeDir(path3.dirname(outPath2));
|
|
756
|
-
await writeFile(outPath2, normalizeLineEndings(body));
|
|
757
|
-
printFileOutput(fileSize(outPath2), "dist/html/", outFilePath2);
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
const data = await renderer.renderRoute(sitemapItem.route, {
|
|
761
|
-
routeParams: sitemapItem.params
|
|
762
|
-
});
|
|
763
|
-
if (data.notFound) {
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
let outFilePath = path3.join(urlPath.slice(1), "index.html");
|
|
767
|
-
if (outFilePath.endsWith("404/index.html")) {
|
|
768
|
-
outFilePath = outFilePath.replace("404/index.html", "404.html");
|
|
769
|
-
}
|
|
770
|
-
const outPath = path3.join(buildDir, outFilePath);
|
|
771
|
-
if (rootConfig.sitemap && outFilePath.endsWith("index.html")) {
|
|
772
|
-
const sitemapXmlItem = {
|
|
773
|
-
url: `${domain}${urlPath}`,
|
|
774
|
-
locale: sitemapItem.locale,
|
|
775
|
-
alts: []
|
|
776
|
-
};
|
|
777
|
-
sitemapXmlItems.push(sitemapXmlItem);
|
|
778
|
-
if (sitemapItem.alts) {
|
|
779
|
-
Object.entries(sitemapItem.alts).forEach(([altLocale, item]) => {
|
|
780
|
-
sitemapXmlItem.alts.push({
|
|
781
|
-
url: `${domain}${item.urlPath}`,
|
|
782
|
-
locale: altLocale,
|
|
783
|
-
hreflang: item.hrefLang
|
|
784
|
-
});
|
|
785
|
-
});
|
|
663
|
+
throw e;
|
|
786
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
|
+
);
|
|
787
693
|
}
|
|
788
|
-
let html = data.html || "";
|
|
789
|
-
if (rootConfig.prettyHtml) {
|
|
790
|
-
html = await htmlPretty(html, rootConfig.prettyHtmlOptions);
|
|
791
|
-
} else if (rootConfig.minifyHtml) {
|
|
792
|
-
html = await htmlMinify(html, rootConfig.minifyHtmlOptions);
|
|
793
|
-
}
|
|
794
|
-
await writeFile(outPath, normalizeLineEndings(html));
|
|
795
|
-
printFileOutput(fileSize(outPath), "dist/html/", outFilePath);
|
|
796
|
-
} catch (e) {
|
|
797
|
-
logBuildError(
|
|
798
|
-
{ route: sitemapItem.route, params: sitemapItem.params, urlPath },
|
|
799
|
-
e
|
|
800
|
-
);
|
|
801
|
-
throw new Error(
|
|
802
|
-
`BuildError: ${urlPath} (${sitemapItem.route.src}) failed to build.`,
|
|
803
|
-
{ cause: e }
|
|
804
|
-
);
|
|
805
694
|
}
|
|
806
|
-
|
|
807
|
-
|
|
695
|
+
);
|
|
696
|
+
}
|
|
808
697
|
if (rootConfig.sitemap) {
|
|
809
698
|
const sitemapXmlBuilder = [];
|
|
810
699
|
sitemapXmlItems.sort((a, b) => a.url.localeCompare(b.url));
|
|
@@ -830,7 +719,7 @@ async function build(rootProjectDir, options) {
|
|
|
830
719
|
"</urlset>"
|
|
831
720
|
];
|
|
832
721
|
const sitemapXml = sitemapXmlLines.join("\n");
|
|
833
|
-
const outPath =
|
|
722
|
+
const outPath = path2.join(buildDir, "sitemap.xml");
|
|
834
723
|
await writeFile(outPath, sitemapXml);
|
|
835
724
|
printFileOutput(fileSize(outPath), "dist/html/", "sitemap.xml");
|
|
836
725
|
}
|
|
@@ -844,6 +733,27 @@ async function build(rootProjectDir, options) {
|
|
|
844
733
|
function isRouteFile(filepath) {
|
|
845
734
|
return filepath.startsWith("routes") && isJsFile(filepath);
|
|
846
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
|
+
}
|
|
847
757
|
function fileSize(filepath) {
|
|
848
758
|
const stats = fsExtra.statSync(filepath);
|
|
849
759
|
const bytes = stats.size;
|
|
@@ -892,18 +802,15 @@ function formatParams(params) {
|
|
|
892
802
|
return ` ${key}: ${value}`;
|
|
893
803
|
}).join("\n");
|
|
894
804
|
}
|
|
895
|
-
function normalizeLineEndings(str) {
|
|
896
|
-
return str.replace(/\r\n?/g, "\n");
|
|
897
|
-
}
|
|
898
805
|
|
|
899
806
|
// src/cli/codegen.ts
|
|
900
|
-
import { promises as
|
|
901
|
-
import
|
|
902
|
-
import { fileURLToPath as
|
|
903
|
-
import
|
|
904
|
-
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));
|
|
905
812
|
async function codegen(type, name, options) {
|
|
906
|
-
const rootDir =
|
|
813
|
+
const rootDir = path3.resolve(process.cwd());
|
|
907
814
|
const project = new Project(rootDir);
|
|
908
815
|
await project.generateCode(type, name, options);
|
|
909
816
|
}
|
|
@@ -913,8 +820,8 @@ var Project = class {
|
|
|
913
820
|
constructor(rootDir) {
|
|
914
821
|
this.rootDir = rootDir;
|
|
915
822
|
this.tplDirs = [
|
|
916
|
-
|
|
917
|
-
|
|
823
|
+
path3.join(rootDir, "codegen"),
|
|
824
|
+
path3.join(__dirname3, "../codegen")
|
|
918
825
|
];
|
|
919
826
|
}
|
|
920
827
|
async generateCode(type, name, options) {
|
|
@@ -924,7 +831,7 @@ var Project = class {
|
|
|
924
831
|
return;
|
|
925
832
|
}
|
|
926
833
|
const outname = options?.out || `${type}s`;
|
|
927
|
-
const outdir =
|
|
834
|
+
const outdir = path3.join(this.rootDir, outname, name);
|
|
928
835
|
if (await dirExists(outdir)) {
|
|
929
836
|
await rmDir(outdir);
|
|
930
837
|
}
|
|
@@ -933,7 +840,7 @@ var Project = class {
|
|
|
933
840
|
const tpl = await files[tplName].read();
|
|
934
841
|
const content = tpl.replaceAll("[[name]]", name).replaceAll("[[name:camel_upper]]", toCamelCaseUpper(name));
|
|
935
842
|
const filename = tplName.replace("[name]", name);
|
|
936
|
-
const filepath =
|
|
843
|
+
const filepath = path3.join(outdir, filename);
|
|
937
844
|
await writeFile(filepath, content);
|
|
938
845
|
console.log(`saved ${filepath}`);
|
|
939
846
|
}
|
|
@@ -944,7 +851,7 @@ var Project = class {
|
|
|
944
851
|
*/
|
|
945
852
|
async loadFiles(type) {
|
|
946
853
|
for (const tplDir of this.tplDirs) {
|
|
947
|
-
const typeDir =
|
|
854
|
+
const typeDir = path3.join(tplDir, type);
|
|
948
855
|
if (await dirExists(typeDir)) {
|
|
949
856
|
return this.loadTplFiles(typeDir);
|
|
950
857
|
}
|
|
@@ -956,12 +863,12 @@ var Project = class {
|
|
|
956
863
|
*/
|
|
957
864
|
async loadTplFiles(dirpath) {
|
|
958
865
|
const tplFiles = {};
|
|
959
|
-
const files = await
|
|
866
|
+
const files = await glob2("*.tpl", { cwd: dirpath });
|
|
960
867
|
for (const filename of files) {
|
|
961
|
-
const filepath =
|
|
868
|
+
const filepath = path3.join(dirpath, filename);
|
|
962
869
|
const name = filename.slice(0, -4);
|
|
963
870
|
tplFiles[name] = {
|
|
964
|
-
read: () =>
|
|
871
|
+
read: () => fs.readFile(filepath, "utf-8")
|
|
965
872
|
};
|
|
966
873
|
}
|
|
967
874
|
return tplFiles;
|
|
@@ -977,23 +884,23 @@ function toTitleCase(str) {
|
|
|
977
884
|
}
|
|
978
885
|
|
|
979
886
|
// src/cli/create-package.ts
|
|
980
|
-
import { promises as
|
|
981
|
-
import
|
|
887
|
+
import { promises as fs2 } from "node:fs";
|
|
888
|
+
import path4 from "node:path";
|
|
982
889
|
import { build as esbuild } from "esbuild";
|
|
983
890
|
async function createPackage(rootProjectDir, options) {
|
|
984
891
|
const mode = options?.mode || "production";
|
|
985
892
|
process.env.NODE_ENV = mode;
|
|
986
|
-
const rootDir =
|
|
987
|
-
const distDir =
|
|
893
|
+
const rootDir = path4.resolve(rootProjectDir || process.cwd());
|
|
894
|
+
const distDir = path4.join(rootDir, "dist");
|
|
988
895
|
const target = options?.target || await getDefaultTarget(rootDir);
|
|
989
|
-
const outDir =
|
|
896
|
+
const outDir = path4.resolve(options?.out || target || "out");
|
|
990
897
|
await build(rootProjectDir, { ssrOnly: true, mode });
|
|
991
898
|
await rmDir(outDir);
|
|
992
899
|
await makeDir(outDir);
|
|
993
|
-
await copyDir(distDir,
|
|
994
|
-
const collectionsDir =
|
|
900
|
+
await copyDir(distDir, path4.resolve(outDir, "dist"));
|
|
901
|
+
const collectionsDir = path4.resolve(rootDir, "collections");
|
|
995
902
|
if (await dirExists(collectionsDir)) {
|
|
996
|
-
await copyDir(collectionsDir,
|
|
903
|
+
await copyDir(collectionsDir, path4.join(outDir, "collections"));
|
|
997
904
|
}
|
|
998
905
|
const packageJson = await generatePackageJson(rootDir, options);
|
|
999
906
|
if (options?.version && packageJson.dependencies) {
|
|
@@ -1008,21 +915,21 @@ async function createPackage(rootProjectDir, options) {
|
|
|
1008
915
|
}
|
|
1009
916
|
}
|
|
1010
917
|
if (target === "appengine") {
|
|
1011
|
-
const appYamlPath = options?.appYaml ||
|
|
918
|
+
const appYamlPath = options?.appYaml || path4.join(rootDir, "app.yaml");
|
|
1012
919
|
await onAppEngine({ packageJson, outDir, appYamlPath });
|
|
1013
920
|
} else if (target === "firebase") {
|
|
1014
921
|
await onFirebase({ rootDir, packageJson, outDir });
|
|
1015
922
|
}
|
|
1016
|
-
await writeJson(
|
|
923
|
+
await writeJson(path4.resolve(outDir, "package.json"), packageJson);
|
|
1017
924
|
console.log("done!");
|
|
1018
925
|
console.log(`saved package to ${outDir}`);
|
|
1019
926
|
}
|
|
1020
927
|
async function getDefaultTarget(rootDir) {
|
|
1021
|
-
const firebaseConfigPath =
|
|
928
|
+
const firebaseConfigPath = path4.resolve(rootDir, "firebase.json");
|
|
1022
929
|
if (await fileExists(firebaseConfigPath)) {
|
|
1023
930
|
return "firebase";
|
|
1024
931
|
}
|
|
1025
|
-
const appEngineConfigPath =
|
|
932
|
+
const appEngineConfigPath = path4.resolve(rootDir, "app.yaml");
|
|
1026
933
|
if (await fileExists(appEngineConfigPath)) {
|
|
1027
934
|
return "appengine";
|
|
1028
935
|
}
|
|
@@ -1030,7 +937,7 @@ async function getDefaultTarget(rootDir) {
|
|
|
1030
937
|
}
|
|
1031
938
|
async function generatePackageJson(rootDir, options) {
|
|
1032
939
|
const packageJson = await loadJson(
|
|
1033
|
-
|
|
940
|
+
path4.resolve(rootDir, "package.json")
|
|
1034
941
|
);
|
|
1035
942
|
const allDeps = flattenPackageDepsFromMonorepo(rootDir);
|
|
1036
943
|
packageJson.dependencies ??= {};
|
|
@@ -1057,7 +964,7 @@ async function generatePackageJson(rootDir, options) {
|
|
|
1057
964
|
async function onAppEngine(options) {
|
|
1058
965
|
const { outDir, packageJson, appYamlPath } = options;
|
|
1059
966
|
if (await fileExists(appYamlPath)) {
|
|
1060
|
-
await
|
|
967
|
+
await fs2.copyFile(appYamlPath, path4.resolve(outDir, "app.yaml"));
|
|
1061
968
|
}
|
|
1062
969
|
if (packageJson.scripts?.start) {
|
|
1063
970
|
packageJson.scripts = { start: packageJson.scripts.start };
|
|
@@ -1067,11 +974,11 @@ async function onAppEngine(options) {
|
|
|
1067
974
|
}
|
|
1068
975
|
async function onFirebase(options) {
|
|
1069
976
|
const { rootDir, outDir, packageJson } = options;
|
|
1070
|
-
const outBasename =
|
|
977
|
+
const outBasename = path4.basename(outDir);
|
|
1071
978
|
if (outBasename === "functions") {
|
|
1072
|
-
const indexTsFile =
|
|
979
|
+
const indexTsFile = path4.resolve(rootDir, "index.ts");
|
|
1073
980
|
if (await fileExists(indexTsFile)) {
|
|
1074
|
-
await bundleTsFile(indexTsFile,
|
|
981
|
+
await bundleTsFile(indexTsFile, path4.resolve(outDir, "index.js"));
|
|
1075
982
|
}
|
|
1076
983
|
}
|
|
1077
984
|
if (packageJson.scripts?.start) {
|
|
@@ -1096,7 +1003,7 @@ async function bundleTsFile(srcPath, outPath) {
|
|
|
1096
1003
|
setup(build2) {
|
|
1097
1004
|
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
1098
1005
|
const id = args.path;
|
|
1099
|
-
if (id[0] !== "." && !
|
|
1006
|
+
if (id[0] !== "." && !path4.isAbsolute(id)) {
|
|
1100
1007
|
return {
|
|
1101
1008
|
external: true
|
|
1102
1009
|
};
|
|
@@ -1110,13 +1017,13 @@ async function bundleTsFile(srcPath, outPath) {
|
|
|
1110
1017
|
}
|
|
1111
1018
|
|
|
1112
1019
|
// src/cli/dev.ts
|
|
1113
|
-
import
|
|
1114
|
-
import { fileURLToPath as
|
|
1020
|
+
import path11 from "node:path";
|
|
1021
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
1115
1022
|
import cookieParser from "cookie-parser";
|
|
1116
1023
|
import { default as express } from "express";
|
|
1117
1024
|
import { dim as dim5 } from "kleur/colors";
|
|
1118
1025
|
import sirv from "sirv";
|
|
1119
|
-
import
|
|
1026
|
+
import glob3 from "tiny-glob";
|
|
1120
1027
|
|
|
1121
1028
|
// src/middleware/hooks.ts
|
|
1122
1029
|
function hooksMiddleware() {
|
|
@@ -1204,8 +1111,8 @@ function testIsRedirectValid(url) {
|
|
|
1204
1111
|
}
|
|
1205
1112
|
|
|
1206
1113
|
// src/render/asset-map/dev-asset-map.ts
|
|
1207
|
-
import
|
|
1208
|
-
import { searchForWorkspaceRoot
|
|
1114
|
+
import path5 from "node:path";
|
|
1115
|
+
import { searchForWorkspaceRoot } from "vite";
|
|
1209
1116
|
var DevServerAssetMap = class {
|
|
1210
1117
|
rootConfig;
|
|
1211
1118
|
moduleGraph;
|
|
@@ -1214,7 +1121,7 @@ var DevServerAssetMap = class {
|
|
|
1214
1121
|
this.moduleGraph = moduleGraph;
|
|
1215
1122
|
}
|
|
1216
1123
|
async get(src) {
|
|
1217
|
-
const file =
|
|
1124
|
+
const file = path5.resolve(this.rootConfig.rootDir, src);
|
|
1218
1125
|
const viteModules = this.moduleGraph.getModulesByFile(file);
|
|
1219
1126
|
if (viteModules && viteModules.size > 0) {
|
|
1220
1127
|
const [viteModule] = viteModules;
|
|
@@ -1232,7 +1139,7 @@ var DevServerAssetMap = class {
|
|
|
1232
1139
|
getJsDeps: async () => [assetUrl]
|
|
1233
1140
|
};
|
|
1234
1141
|
}
|
|
1235
|
-
const workspaceRoot =
|
|
1142
|
+
const workspaceRoot = searchForWorkspaceRoot(this.rootConfig.rootDir);
|
|
1236
1143
|
if (await directoryContains(workspaceRoot, file)) {
|
|
1237
1144
|
const assetUrl = `/@fs/${file}`;
|
|
1238
1145
|
return {
|
|
@@ -1246,7 +1153,7 @@ var DevServerAssetMap = class {
|
|
|
1246
1153
|
return null;
|
|
1247
1154
|
}
|
|
1248
1155
|
filePathToSrc(file) {
|
|
1249
|
-
return
|
|
1156
|
+
return path5.relative(this.rootConfig.rootDir, file);
|
|
1250
1157
|
}
|
|
1251
1158
|
};
|
|
1252
1159
|
var DevServerAsset = class _DevServerAsset {
|
|
@@ -1288,7 +1195,7 @@ var DevServerAsset = class _DevServerAsset {
|
|
|
1288
1195
|
return;
|
|
1289
1196
|
}
|
|
1290
1197
|
visited.add(asset.moduleId);
|
|
1291
|
-
const parts =
|
|
1198
|
+
const parts = path5.parse(asset.assetUrl);
|
|
1292
1199
|
if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && asset.moduleId.includes("/elements/")) {
|
|
1293
1200
|
urls.add(asset.assetUrl);
|
|
1294
1201
|
}
|
|
@@ -1315,7 +1222,7 @@ var DevServerAsset = class _DevServerAsset {
|
|
|
1315
1222
|
}
|
|
1316
1223
|
visited.add(asset.assetUrl);
|
|
1317
1224
|
if (asset.src.endsWith(".scss")) {
|
|
1318
|
-
const parts =
|
|
1225
|
+
const parts = path5.parse(asset.src);
|
|
1319
1226
|
if (!parts.name.startsWith("_")) {
|
|
1320
1227
|
urls.add(asset.assetUrl);
|
|
1321
1228
|
}
|
|
@@ -1396,19 +1303,19 @@ function getSessionCookieSecret(rootConfig, rootDir) {
|
|
|
1396
1303
|
|
|
1397
1304
|
// src/cli/secrets.ts
|
|
1398
1305
|
import { spawn as spawn3 } from "node:child_process";
|
|
1399
|
-
import
|
|
1400
|
-
import
|
|
1306
|
+
import fs6 from "node:fs";
|
|
1307
|
+
import path9 from "node:path";
|
|
1401
1308
|
import * as readline from "node:readline";
|
|
1402
1309
|
import { dim as dim3, green, red, yellow } from "kleur/colors";
|
|
1403
1310
|
|
|
1404
1311
|
// src/secrets/manifest.ts
|
|
1405
|
-
import
|
|
1406
|
-
import
|
|
1312
|
+
import fs3 from "node:fs";
|
|
1313
|
+
import path6 from "node:path";
|
|
1407
1314
|
var MANIFEST_FILENAME = ".root.secrets.json";
|
|
1408
1315
|
var GSM_KEY_RE = /^[A-Za-z0-9_-]{1,255}$/;
|
|
1409
1316
|
var ENV_NAME_RE = /^[A-Za-z0-9_]+$/;
|
|
1410
1317
|
function manifestPath(dir) {
|
|
1411
|
-
return
|
|
1318
|
+
return path6.join(dir, MANIFEST_FILENAME);
|
|
1412
1319
|
}
|
|
1413
1320
|
function isValidEnvName(name) {
|
|
1414
1321
|
return ENV_NAME_RE.test(name);
|
|
@@ -1416,7 +1323,7 @@ function isValidEnvName(name) {
|
|
|
1416
1323
|
async function readManifest(filePath) {
|
|
1417
1324
|
let raw;
|
|
1418
1325
|
try {
|
|
1419
|
-
raw = await
|
|
1326
|
+
raw = await fs3.promises.readFile(filePath, "utf8");
|
|
1420
1327
|
} catch (err) {
|
|
1421
1328
|
if (err.code === "ENOENT") {
|
|
1422
1329
|
return null;
|
|
@@ -1443,8 +1350,8 @@ async function writeManifest(filePath, manifest) {
|
|
|
1443
1350
|
...manifest.import ? { import: manifest.import } : {},
|
|
1444
1351
|
secrets: sortedSecrets
|
|
1445
1352
|
};
|
|
1446
|
-
await
|
|
1447
|
-
await
|
|
1353
|
+
await fs3.promises.mkdir(path6.dirname(filePath), { recursive: true });
|
|
1354
|
+
await fs3.promises.writeFile(
|
|
1448
1355
|
filePath,
|
|
1449
1356
|
JSON.stringify(ordered, null, 2) + "\n",
|
|
1450
1357
|
"utf8"
|
|
@@ -1472,7 +1379,7 @@ async function resolveManagedKeys(rootDir) {
|
|
|
1472
1379
|
}
|
|
1473
1380
|
let shared;
|
|
1474
1381
|
if (site.import) {
|
|
1475
|
-
const sharedPath =
|
|
1382
|
+
const sharedPath = path6.resolve(rootDir, site.import.manifest);
|
|
1476
1383
|
const loaded = await readManifest(sharedPath);
|
|
1477
1384
|
if (!loaded) {
|
|
1478
1385
|
throw new Error(`imported manifest not found: ${sharedPath}`);
|
|
@@ -1599,16 +1506,16 @@ function validateManifest(value, filePath) {
|
|
|
1599
1506
|
|
|
1600
1507
|
// src/secrets/secrets.ts
|
|
1601
1508
|
import { spawn as spawn2 } from "node:child_process";
|
|
1602
|
-
import
|
|
1603
|
-
import
|
|
1509
|
+
import fs5 from "node:fs";
|
|
1510
|
+
import path8 from "node:path";
|
|
1604
1511
|
|
|
1605
1512
|
// src/secrets/env-file.ts
|
|
1606
|
-
import
|
|
1607
|
-
import
|
|
1513
|
+
import fs4 from "node:fs";
|
|
1514
|
+
import path7 from "node:path";
|
|
1608
1515
|
import dotenv from "dotenv";
|
|
1609
1516
|
async function readEnvFile(envPath2) {
|
|
1610
1517
|
try {
|
|
1611
|
-
return await
|
|
1518
|
+
return await fs4.promises.readFile(envPath2, "utf8");
|
|
1612
1519
|
} catch (err) {
|
|
1613
1520
|
if (err.code === "ENOENT") {
|
|
1614
1521
|
return "";
|
|
@@ -1617,11 +1524,11 @@ async function readEnvFile(envPath2) {
|
|
|
1617
1524
|
}
|
|
1618
1525
|
}
|
|
1619
1526
|
async function writeEnvFile(envPath2, content) {
|
|
1620
|
-
const dir =
|
|
1621
|
-
await
|
|
1622
|
-
const tmp =
|
|
1623
|
-
await
|
|
1624
|
-
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);
|
|
1625
1532
|
}
|
|
1626
1533
|
function parseEnv(content) {
|
|
1627
1534
|
return dotenv.parse(content);
|
|
@@ -1839,10 +1746,10 @@ function hashValue(salt, value) {
|
|
|
1839
1746
|
// src/secrets/secrets.ts
|
|
1840
1747
|
var STATE_FILENAME = "secrets-sync.json";
|
|
1841
1748
|
function localStatePath(rootDir) {
|
|
1842
|
-
return
|
|
1749
|
+
return path8.join(rootDir, ".root", STATE_FILENAME);
|
|
1843
1750
|
}
|
|
1844
1751
|
function envPath(rootDir) {
|
|
1845
|
-
return
|
|
1752
|
+
return path8.join(rootDir, ".env");
|
|
1846
1753
|
}
|
|
1847
1754
|
var inFlight = /* @__PURE__ */ new Map();
|
|
1848
1755
|
function syncSecrets(options) {
|
|
@@ -2068,7 +1975,7 @@ async function pushEnvToSecrets(options) {
|
|
|
2068
1975
|
};
|
|
2069
1976
|
}
|
|
2070
1977
|
async function sharedImportedNames(rootDir, manifestFilePath) {
|
|
2071
|
-
if (
|
|
1978
|
+
if (path8.resolve(manifestFilePath) !== path8.resolve(manifestPath(rootDir))) {
|
|
2072
1979
|
return /* @__PURE__ */ new Set();
|
|
2073
1980
|
}
|
|
2074
1981
|
try {
|
|
@@ -2131,7 +2038,7 @@ function isSyncDisabledByEnv() {
|
|
|
2131
2038
|
}
|
|
2132
2039
|
async function readLocalState(rootDir) {
|
|
2133
2040
|
try {
|
|
2134
|
-
const raw = await
|
|
2041
|
+
const raw = await fs5.promises.readFile(localStatePath(rootDir), "utf8");
|
|
2135
2042
|
const parsed = JSON.parse(raw);
|
|
2136
2043
|
if (parsed && typeof parsed === "object" && typeof parsed.salt === "string" && parsed.secrets && typeof parsed.secrets === "object") {
|
|
2137
2044
|
return {
|
|
@@ -2145,8 +2052,8 @@ async function readLocalState(rootDir) {
|
|
|
2145
2052
|
}
|
|
2146
2053
|
async function writeLocalState(rootDir, state) {
|
|
2147
2054
|
const file = localStatePath(rootDir);
|
|
2148
|
-
await
|
|
2149
|
-
await
|
|
2055
|
+
await fs5.promises.mkdir(path8.dirname(file), { recursive: true });
|
|
2056
|
+
await fs5.promises.writeFile(
|
|
2150
2057
|
file,
|
|
2151
2058
|
JSON.stringify(state, null, 2) + "\n",
|
|
2152
2059
|
"utf8"
|
|
@@ -2212,7 +2119,7 @@ function registerSecretsCommands(program) {
|
|
|
2212
2119
|
}
|
|
2213
2120
|
async function secretsInit(opts) {
|
|
2214
2121
|
const rootDir = process.cwd();
|
|
2215
|
-
const target = opts.manifest ?
|
|
2122
|
+
const target = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2216
2123
|
if (await readManifest(target)) {
|
|
2217
2124
|
console.log(
|
|
2218
2125
|
`${BAR} ${yellow("secrets:")} manifest already exists at ${rel(rootDir, target)}`
|
|
@@ -2245,7 +2152,7 @@ async function secretsInit(opts) {
|
|
|
2245
2152
|
}
|
|
2246
2153
|
async function secretsSet(name, opts) {
|
|
2247
2154
|
const rootDir = process.cwd();
|
|
2248
|
-
const manifestFilePath = opts.manifest ?
|
|
2155
|
+
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2249
2156
|
const secretValue = await readSecretValue(name);
|
|
2250
2157
|
if (!secretValue) {
|
|
2251
2158
|
throw new Error("no value provided on stdin");
|
|
@@ -2258,7 +2165,7 @@ async function secretsSet(name, opts) {
|
|
|
2258
2165
|
}
|
|
2259
2166
|
async function secretsRm(name, opts) {
|
|
2260
2167
|
const rootDir = process.cwd();
|
|
2261
|
-
const manifestFilePath = opts.manifest ?
|
|
2168
|
+
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2262
2169
|
await removeSecret({ rootDir, manifestFilePath, name });
|
|
2263
2170
|
console.log(`${BAR} ${green("secrets:")} removed ${name}`);
|
|
2264
2171
|
console.log(
|
|
@@ -2267,7 +2174,7 @@ async function secretsRm(name, opts) {
|
|
|
2267
2174
|
}
|
|
2268
2175
|
async function secretsPush(opts) {
|
|
2269
2176
|
const rootDir = process.cwd();
|
|
2270
|
-
const manifestFilePath = opts.manifest ?
|
|
2177
|
+
const manifestFilePath = opts.manifest ? path9.resolve(rootDir, opts.manifest) : manifestPath(rootDir);
|
|
2271
2178
|
const only = opts.keys ? opts.keys.split(",").map((k) => k.trim()).filter(Boolean) : void 0;
|
|
2272
2179
|
const confirm = opts.yes ? void 0 : async (names, gsmKey) => {
|
|
2273
2180
|
if (!process.stdin.isTTY) {
|
|
@@ -2444,10 +2351,11 @@ function printPushResult(result, rootDir, manifestFilePath) {
|
|
|
2444
2351
|
console.log();
|
|
2445
2352
|
}
|
|
2446
2353
|
async function ensureRootGitignored(rootDir) {
|
|
2447
|
-
const
|
|
2354
|
+
const gitRoot = await gitToplevel(rootDir) ?? rootDir;
|
|
2355
|
+
const gitignore = path9.join(gitRoot, ".gitignore");
|
|
2448
2356
|
let content = "";
|
|
2449
2357
|
try {
|
|
2450
|
-
content = await
|
|
2358
|
+
content = await fs6.promises.readFile(gitignore, "utf8");
|
|
2451
2359
|
} catch {
|
|
2452
2360
|
}
|
|
2453
2361
|
const lines = content.split(/\r?\n/).map((line) => line.trim());
|
|
@@ -2455,7 +2363,7 @@ async function ensureRootGitignored(rootDir) {
|
|
|
2455
2363
|
return false;
|
|
2456
2364
|
}
|
|
2457
2365
|
const prefix = content && !content.endsWith("\n") ? "\n" : "";
|
|
2458
|
-
await
|
|
2366
|
+
await fs6.promises.writeFile(gitignore, `${content}${prefix}.root/
|
|
2459
2367
|
`, "utf8");
|
|
2460
2368
|
return true;
|
|
2461
2369
|
}
|
|
@@ -2467,6 +2375,27 @@ async function warnIfEnvNotIgnored(rootDir) {
|
|
|
2467
2375
|
);
|
|
2468
2376
|
}
|
|
2469
2377
|
}
|
|
2378
|
+
function gitToplevel(rootDir) {
|
|
2379
|
+
return new Promise((resolve) => {
|
|
2380
|
+
try {
|
|
2381
|
+
const child = spawn3("git", ["rev-parse", "--show-toplevel"], {
|
|
2382
|
+
cwd: rootDir
|
|
2383
|
+
});
|
|
2384
|
+
let stdout = "";
|
|
2385
|
+
child.stdout.setEncoding("utf8");
|
|
2386
|
+
child.stdout.on("data", (chunk) => {
|
|
2387
|
+
stdout += chunk;
|
|
2388
|
+
});
|
|
2389
|
+
child.on("error", () => resolve(void 0));
|
|
2390
|
+
child.on("close", (code) => {
|
|
2391
|
+
const toplevel = stdout.trim();
|
|
2392
|
+
resolve(code === 0 && toplevel ? toplevel : void 0);
|
|
2393
|
+
});
|
|
2394
|
+
} catch {
|
|
2395
|
+
resolve(void 0);
|
|
2396
|
+
}
|
|
2397
|
+
});
|
|
2398
|
+
}
|
|
2470
2399
|
function isPathGitIgnored(rootDir, relPath) {
|
|
2471
2400
|
return new Promise((resolve) => {
|
|
2472
2401
|
try {
|
|
@@ -2562,7 +2491,7 @@ function withTimeout(promise, ms) {
|
|
|
2562
2491
|
});
|
|
2563
2492
|
}
|
|
2564
2493
|
function rel(rootDir, filePath) {
|
|
2565
|
-
return
|
|
2494
|
+
return path9.relative(rootDir, filePath) || path9.basename(filePath);
|
|
2566
2495
|
}
|
|
2567
2496
|
function firstLine(text) {
|
|
2568
2497
|
return String(text).split("\n")[0];
|
|
@@ -2579,8 +2508,8 @@ function action(fn) {
|
|
|
2579
2508
|
}
|
|
2580
2509
|
|
|
2581
2510
|
// src/cli/startup/startup-tasks.ts
|
|
2582
|
-
import
|
|
2583
|
-
import
|
|
2511
|
+
import os2 from "node:os";
|
|
2512
|
+
import path10 from "node:path";
|
|
2584
2513
|
|
|
2585
2514
|
// src/cli/startup/check-version.ts
|
|
2586
2515
|
import { dim as dim4, green as green2, yellow as yellow2 } from "kleur/colors";
|
|
@@ -2663,7 +2592,7 @@ function printUpdateNotice(current, latest) {
|
|
|
2663
2592
|
|
|
2664
2593
|
// src/cli/startup/startup-tasks.ts
|
|
2665
2594
|
var STARTUP_TASKS = [checkVersionTask];
|
|
2666
|
-
var STATE_FILE =
|
|
2595
|
+
var STATE_FILE = path10.join(os2.homedir(), ".root", "startup-tasks.json");
|
|
2667
2596
|
async function runStartupTasks(ctx) {
|
|
2668
2597
|
try {
|
|
2669
2598
|
const state = await readState();
|
|
@@ -2714,13 +2643,13 @@ async function writeState(state) {
|
|
|
2714
2643
|
}
|
|
2715
2644
|
|
|
2716
2645
|
// src/cli/dev.ts
|
|
2717
|
-
var
|
|
2646
|
+
var __dirname4 = path11.dirname(fileURLToPath4(import.meta.url));
|
|
2718
2647
|
var DEV_SERVER_404_LOG_IGNORE_PATHS = /* @__PURE__ */ new Set([
|
|
2719
2648
|
"/.well-known/appspecific/com.chrome.devtools.json"
|
|
2720
2649
|
]);
|
|
2721
2650
|
async function dev(rootProjectDir, options) {
|
|
2722
2651
|
process.env.NODE_ENV = "development";
|
|
2723
|
-
const rootDir =
|
|
2652
|
+
const rootDir = path11.resolve(rootProjectDir || process.cwd());
|
|
2724
2653
|
const defaultPort = parseInt(process.env.PORT || "4007");
|
|
2725
2654
|
const host = options?.host || "localhost";
|
|
2726
2655
|
const port = await findOpenPort(defaultPort, defaultPort + 10);
|
|
@@ -2748,7 +2677,7 @@ async function dev(rootProjectDir, options) {
|
|
|
2748
2677
|
"rootConfigDependencies"
|
|
2749
2678
|
);
|
|
2750
2679
|
const dependencies = [
|
|
2751
|
-
|
|
2680
|
+
path11.resolve(rootDir, "root.config.ts"),
|
|
2752
2681
|
...rootConfigDependencies
|
|
2753
2682
|
];
|
|
2754
2683
|
viteServer.watcher.add(dependencies);
|
|
@@ -2776,7 +2705,7 @@ ${dim5("\u2503")} root.config.ts changed. restarting server...`
|
|
|
2776
2705
|
await start2();
|
|
2777
2706
|
}
|
|
2778
2707
|
async function createDevServer(options) {
|
|
2779
|
-
const rootDir =
|
|
2708
|
+
const rootDir = path11.resolve(options?.rootDir || process.cwd());
|
|
2780
2709
|
const { rootConfig, dependencies } = await loadRootConfigWithDeps(rootDir, {
|
|
2781
2710
|
command: "dev"
|
|
2782
2711
|
});
|
|
@@ -2791,6 +2720,7 @@ async function createDevServer(options) {
|
|
|
2791
2720
|
});
|
|
2792
2721
|
server.set("viteServer", viteServer);
|
|
2793
2722
|
server.use(rootProjectMiddleware({ rootConfig }));
|
|
2723
|
+
server.use(securityHeadersMiddleware({ rootConfig }));
|
|
2794
2724
|
server.use(viteMiddleware);
|
|
2795
2725
|
server.use(hooksMiddleware());
|
|
2796
2726
|
const sessionCookieSecret = getSessionCookieSecret(rootConfig, rootDir);
|
|
@@ -2812,7 +2742,7 @@ async function createDevServer(options) {
|
|
|
2812
2742
|
if (rootConfig.server?.headers) {
|
|
2813
2743
|
server.use(headersMiddleware({ rootConfig }));
|
|
2814
2744
|
}
|
|
2815
|
-
const publicDir =
|
|
2745
|
+
const publicDir = path11.join(rootDir, "public");
|
|
2816
2746
|
if (await dirExists(publicDir)) {
|
|
2817
2747
|
server.use(rootPublicDirMiddleware({ publicDir, viteServer }));
|
|
2818
2748
|
}
|
|
@@ -2840,10 +2770,10 @@ async function createViteMiddleware(options) {
|
|
|
2840
2770
|
return sourceFile.relPath;
|
|
2841
2771
|
});
|
|
2842
2772
|
const bundleScripts = [];
|
|
2843
|
-
if (await isDirectory(
|
|
2844
|
-
const bundleFiles = await
|
|
2773
|
+
if (await isDirectory(path11.join(rootDir, "bundles"))) {
|
|
2774
|
+
const bundleFiles = await glob3("bundles/*", { cwd: rootDir });
|
|
2845
2775
|
bundleFiles.forEach((file) => {
|
|
2846
|
-
const parts =
|
|
2776
|
+
const parts = path11.parse(file);
|
|
2847
2777
|
if (isJsFile(parts.base)) {
|
|
2848
2778
|
bundleScripts.push(file);
|
|
2849
2779
|
}
|
|
@@ -2860,7 +2790,7 @@ async function createViteMiddleware(options) {
|
|
|
2860
2790
|
optimizeDeps
|
|
2861
2791
|
});
|
|
2862
2792
|
function isInElementsDir(changedFilePath) {
|
|
2863
|
-
const filePath =
|
|
2793
|
+
const filePath = path11.resolve(changedFilePath);
|
|
2864
2794
|
const elementsDirs = getElementsDirs(rootConfig, pods);
|
|
2865
2795
|
return elementsDirs.some((dirPath) => filePath.startsWith(dirPath));
|
|
2866
2796
|
}
|
|
@@ -2879,7 +2809,7 @@ async function createViteMiddleware(options) {
|
|
|
2879
2809
|
const viteMiddleware = async (req, res, next) => {
|
|
2880
2810
|
try {
|
|
2881
2811
|
req.viteServer = viteServer;
|
|
2882
|
-
const renderModulePath =
|
|
2812
|
+
const renderModulePath = path11.resolve(__dirname4, "./render.js");
|
|
2883
2813
|
const render = await viteServer.ssrLoadModule(
|
|
2884
2814
|
renderModulePath
|
|
2885
2815
|
);
|
|
@@ -2903,7 +2833,7 @@ function rootPublicDirMiddleware(options) {
|
|
|
2903
2833
|
handler = sirv(publicDir, sirvOptions);
|
|
2904
2834
|
}, 1e3);
|
|
2905
2835
|
function isInPublicDir(changedFilePath) {
|
|
2906
|
-
const filePath =
|
|
2836
|
+
const filePath = path11.resolve(changedFilePath);
|
|
2907
2837
|
return filePath.startsWith(publicDir);
|
|
2908
2838
|
}
|
|
2909
2839
|
const watcher = options.viteServer.watcher;
|
|
@@ -2935,7 +2865,7 @@ function rootDevServer404Middleware() {
|
|
|
2935
2865
|
}
|
|
2936
2866
|
if (req.renderer) {
|
|
2937
2867
|
const url = req.path;
|
|
2938
|
-
const ext =
|
|
2868
|
+
const ext = path11.extname(url);
|
|
2939
2869
|
if (!ext) {
|
|
2940
2870
|
const renderer = req.renderer;
|
|
2941
2871
|
const data = await renderer.renderDevServer404(req);
|
|
@@ -2953,7 +2883,7 @@ function rootDevServer500Middleware() {
|
|
|
2953
2883
|
console.error(String(err.stack || err));
|
|
2954
2884
|
if (req.renderer) {
|
|
2955
2885
|
const url = req.path;
|
|
2956
|
-
const ext =
|
|
2886
|
+
const ext = path11.extname(url);
|
|
2957
2887
|
if (!ext) {
|
|
2958
2888
|
const renderer = req.renderer;
|
|
2959
2889
|
const data = await renderer.renderDevServer500(req, err);
|
|
@@ -2979,7 +2909,7 @@ function debounce(fn, timeout) {
|
|
|
2979
2909
|
|
|
2980
2910
|
// src/cli/gae-deploy.ts
|
|
2981
2911
|
import { execSync } from "node:child_process";
|
|
2982
|
-
import
|
|
2912
|
+
import fs7 from "node:fs";
|
|
2983
2913
|
import yaml from "js-yaml";
|
|
2984
2914
|
async function gaeDeploy(appDir, options) {
|
|
2985
2915
|
if (!appDir) {
|
|
@@ -2993,10 +2923,10 @@ async function gaeDeploy(appDir, options) {
|
|
|
2993
2923
|
}
|
|
2994
2924
|
process.chdir(appDir);
|
|
2995
2925
|
const appYamlPath = "app.yaml";
|
|
2996
|
-
if (!
|
|
2926
|
+
if (!fs7.existsSync(appYamlPath)) {
|
|
2997
2927
|
throw new Error(`[gae-deplopy] Missing: ${appYamlPath}`);
|
|
2998
2928
|
}
|
|
2999
|
-
const appYaml = yaml.load(
|
|
2929
|
+
const appYaml = yaml.load(fs7.readFileSync(appYamlPath, "utf8"));
|
|
3000
2930
|
const service = appYaml.service;
|
|
3001
2931
|
if (!service) {
|
|
3002
2932
|
throw new Error(
|
|
@@ -3022,7 +2952,7 @@ async function gaeDeploy(appDir, options) {
|
|
|
3022
2952
|
{ stdio: "inherit" }
|
|
3023
2953
|
);
|
|
3024
2954
|
if (backupAppYaml) {
|
|
3025
|
-
|
|
2955
|
+
fs7.copyFileSync(backupAppYaml, "app.yaml");
|
|
3026
2956
|
}
|
|
3027
2957
|
if (options?.healthcheckUrl) {
|
|
3028
2958
|
const healthcheckPassed = await testHealth(
|
|
@@ -3109,8 +3039,8 @@ function testIsEnvPlaceholder(envValue) {
|
|
|
3109
3039
|
}
|
|
3110
3040
|
function updateAppYamlEnv(appYamlPath, appYaml) {
|
|
3111
3041
|
const backupAppYaml = `${appYamlPath}.bak`;
|
|
3112
|
-
|
|
3113
|
-
let content =
|
|
3042
|
+
fs7.copyFileSync(appYamlPath, backupAppYaml);
|
|
3043
|
+
let content = fs7.readFileSync(appYamlPath, "utf8");
|
|
3114
3044
|
const envVars = appYaml.env_variables;
|
|
3115
3045
|
Object.entries(envVars).forEach(([envVar, envValue]) => {
|
|
3116
3046
|
if (testIsEnvPlaceholder(envValue)) {
|
|
@@ -3123,7 +3053,7 @@ function updateAppYamlEnv(appYamlPath, appYaml) {
|
|
|
3123
3053
|
}
|
|
3124
3054
|
}
|
|
3125
3055
|
});
|
|
3126
|
-
|
|
3056
|
+
fs7.writeFileSync(appYamlPath, content, "utf8");
|
|
3127
3057
|
return backupAppYaml;
|
|
3128
3058
|
}
|
|
3129
3059
|
function getTimestamp() {
|
|
@@ -3147,15 +3077,14 @@ function testManagedVersion(service, appInfo, prefix) {
|
|
|
3147
3077
|
}
|
|
3148
3078
|
|
|
3149
3079
|
// src/cli/preview.ts
|
|
3150
|
-
import
|
|
3151
|
-
import compression from "compression";
|
|
3080
|
+
import path12 from "node:path";
|
|
3152
3081
|
import cookieParser2 from "cookie-parser";
|
|
3153
3082
|
import { default as express2 } from "express";
|
|
3154
3083
|
import { dim as dim6 } from "kleur/colors";
|
|
3155
3084
|
import sirv2 from "sirv";
|
|
3156
3085
|
async function preview(rootProjectDir, options) {
|
|
3157
3086
|
process.env.NODE_ENV = "development";
|
|
3158
|
-
const rootDir =
|
|
3087
|
+
const rootDir = path12.resolve(rootProjectDir || process.cwd());
|
|
3159
3088
|
const server = await createPreviewServer({ rootDir });
|
|
3160
3089
|
const port = parseInt(process.env.PORT || "4007");
|
|
3161
3090
|
const host = options?.host || "localhost";
|
|
@@ -3169,11 +3098,12 @@ async function preview(rootProjectDir, options) {
|
|
|
3169
3098
|
async function createPreviewServer(options) {
|
|
3170
3099
|
const rootDir = options.rootDir;
|
|
3171
3100
|
const rootConfig = await loadBundledConfig(rootDir, { command: "preview" });
|
|
3172
|
-
const distDir =
|
|
3101
|
+
const distDir = path12.join(rootDir, "dist");
|
|
3173
3102
|
const server = express2();
|
|
3174
3103
|
server.disable("x-powered-by");
|
|
3175
|
-
server.use(
|
|
3104
|
+
server.use(compressionMiddleware());
|
|
3176
3105
|
server.use(rootProjectMiddleware({ rootConfig }));
|
|
3106
|
+
server.use(securityHeadersMiddleware({ rootConfig }));
|
|
3177
3107
|
server.use(await rootPreviewRendererMiddleware({ rootConfig, distDir }));
|
|
3178
3108
|
server.use(hooksMiddleware());
|
|
3179
3109
|
const sessionCookieSecret = getSessionCookieSecret(rootConfig, rootDir);
|
|
@@ -3195,7 +3125,7 @@ async function createPreviewServer(options) {
|
|
|
3195
3125
|
if (rootConfig.server?.headers) {
|
|
3196
3126
|
server.use(headersMiddleware({ rootConfig }));
|
|
3197
3127
|
}
|
|
3198
|
-
const publicDir =
|
|
3128
|
+
const publicDir = path12.join(distDir, "html");
|
|
3199
3129
|
server.use(sirv2(publicDir, { dev: false }));
|
|
3200
3130
|
server.use(trailingSlashMiddleware({ rootConfig }));
|
|
3201
3131
|
server.use(rootPreviewServerMiddleware());
|
|
@@ -3214,14 +3144,14 @@ async function createPreviewServer(options) {
|
|
|
3214
3144
|
}
|
|
3215
3145
|
async function rootPreviewRendererMiddleware(options) {
|
|
3216
3146
|
const { distDir, rootConfig } = options;
|
|
3217
|
-
const render = await import(
|
|
3218
|
-
const manifestPath2 =
|
|
3147
|
+
const render = await import(path12.join(distDir, "server/render.js"));
|
|
3148
|
+
const manifestPath2 = path12.join(distDir, ".root/manifest.json");
|
|
3219
3149
|
if (!await fileExists(manifestPath2)) {
|
|
3220
3150
|
throw new Error(
|
|
3221
3151
|
`could not find ${manifestPath2}. run \`root build\` before \`root preview\`.`
|
|
3222
3152
|
);
|
|
3223
3153
|
}
|
|
3224
|
-
const elementGraphJsonPath =
|
|
3154
|
+
const elementGraphJsonPath = path12.join(distDir, ".root/elements.json");
|
|
3225
3155
|
if (!await fileExists(elementGraphJsonPath)) {
|
|
3226
3156
|
throw new Error(
|
|
3227
3157
|
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root preview\`.`
|
|
@@ -3261,7 +3191,7 @@ function rootPreviewServer404Middleware() {
|
|
|
3261
3191
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
3262
3192
|
if (req.renderer) {
|
|
3263
3193
|
const url = req.path;
|
|
3264
|
-
const ext =
|
|
3194
|
+
const ext = path12.extname(url);
|
|
3265
3195
|
if (!ext) {
|
|
3266
3196
|
const renderer = req.renderer;
|
|
3267
3197
|
const data = await renderer.render404({ currentPath: url });
|
|
@@ -3279,7 +3209,7 @@ function rootPreviewServer500Middleware() {
|
|
|
3279
3209
|
console.error(String(err.stack || err));
|
|
3280
3210
|
if (req.renderer) {
|
|
3281
3211
|
const url = req.path;
|
|
3282
|
-
const ext =
|
|
3212
|
+
const ext = path12.extname(url);
|
|
3283
3213
|
if (!ext) {
|
|
3284
3214
|
const renderer = req.renderer;
|
|
3285
3215
|
const data = await renderer.renderDevServer500(req, err);
|
|
@@ -3293,15 +3223,14 @@ function rootPreviewServer500Middleware() {
|
|
|
3293
3223
|
}
|
|
3294
3224
|
|
|
3295
3225
|
// src/cli/start.ts
|
|
3296
|
-
import
|
|
3297
|
-
import compression2 from "compression";
|
|
3226
|
+
import path13 from "node:path";
|
|
3298
3227
|
import cookieParser3 from "cookie-parser";
|
|
3299
3228
|
import { default as express3 } from "express";
|
|
3300
3229
|
import { dim as dim7 } from "kleur/colors";
|
|
3301
3230
|
import sirv3 from "sirv";
|
|
3302
3231
|
async function start(rootProjectDir, options) {
|
|
3303
3232
|
process.env.NODE_ENV = "production";
|
|
3304
|
-
const rootDir =
|
|
3233
|
+
const rootDir = path13.resolve(rootProjectDir || process.cwd());
|
|
3305
3234
|
const server = await createProdServer({ rootDir });
|
|
3306
3235
|
const port = parseInt(process.env.PORT || "4007");
|
|
3307
3236
|
const host = options?.host || "localhost";
|
|
@@ -3315,11 +3244,12 @@ async function start(rootProjectDir, options) {
|
|
|
3315
3244
|
async function createProdServer(options) {
|
|
3316
3245
|
const rootDir = options.rootDir;
|
|
3317
3246
|
const rootConfig = await loadBundledConfig(rootDir, { command: "start" });
|
|
3318
|
-
const distDir =
|
|
3247
|
+
const distDir = path13.join(rootDir, "dist");
|
|
3319
3248
|
const server = express3();
|
|
3320
3249
|
server.disable("x-powered-by");
|
|
3321
|
-
server.use(
|
|
3250
|
+
server.use(compressionMiddleware());
|
|
3322
3251
|
server.use(rootProjectMiddleware({ rootConfig }));
|
|
3252
|
+
server.use(securityHeadersMiddleware({ rootConfig }));
|
|
3323
3253
|
server.use(await rootProdRendererMiddleware({ rootConfig, distDir }));
|
|
3324
3254
|
server.use(hooksMiddleware());
|
|
3325
3255
|
const sessionCookieSecret = getSessionCookieSecret(rootConfig, rootDir);
|
|
@@ -3341,7 +3271,7 @@ async function createProdServer(options) {
|
|
|
3341
3271
|
if (rootConfig.server?.headers) {
|
|
3342
3272
|
server.use(headersMiddleware({ rootConfig }));
|
|
3343
3273
|
}
|
|
3344
|
-
const publicDir =
|
|
3274
|
+
const publicDir = path13.join(distDir, "html");
|
|
3345
3275
|
server.use(sirv3(publicDir, { dev: false }));
|
|
3346
3276
|
server.use(trailingSlashMiddleware({ rootConfig }));
|
|
3347
3277
|
server.use(rootProdServerMiddleware());
|
|
@@ -3360,14 +3290,14 @@ async function createProdServer(options) {
|
|
|
3360
3290
|
}
|
|
3361
3291
|
async function rootProdRendererMiddleware(options) {
|
|
3362
3292
|
const { distDir, rootConfig } = options;
|
|
3363
|
-
const render = await import(
|
|
3364
|
-
const manifestPath2 =
|
|
3293
|
+
const render = await import(path13.join(distDir, "server/render.js"));
|
|
3294
|
+
const manifestPath2 = path13.join(distDir, ".root/manifest.json");
|
|
3365
3295
|
if (!await fileExists(manifestPath2)) {
|
|
3366
3296
|
throw new Error(
|
|
3367
3297
|
`could not find ${manifestPath2}. run \`root build\` before \`root start\`.`
|
|
3368
3298
|
);
|
|
3369
3299
|
}
|
|
3370
|
-
const elementGraphJsonPath =
|
|
3300
|
+
const elementGraphJsonPath = path13.join(distDir, ".root/elements.json");
|
|
3371
3301
|
if (!await fileExists(elementGraphJsonPath)) {
|
|
3372
3302
|
throw new Error(
|
|
3373
3303
|
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root start\`.`
|
|
@@ -3407,7 +3337,7 @@ function rootProdServer404Middleware() {
|
|
|
3407
3337
|
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
3408
3338
|
if (req.renderer) {
|
|
3409
3339
|
const url = req.path;
|
|
3410
|
-
const ext =
|
|
3340
|
+
const ext = path13.extname(url);
|
|
3411
3341
|
if (!ext) {
|
|
3412
3342
|
const renderer = req.renderer;
|
|
3413
3343
|
const data = await renderer.render404({ currentPath: url });
|
|
@@ -3425,7 +3355,7 @@ function rootProdServer500Middleware() {
|
|
|
3425
3355
|
console.error(String(err.stack || err));
|
|
3426
3356
|
if (req.renderer) {
|
|
3427
3357
|
const url = req.path;
|
|
3428
|
-
const ext =
|
|
3358
|
+
const ext = path13.extname(url);
|
|
3429
3359
|
if (!ext) {
|
|
3430
3360
|
const renderer = req.renderer;
|
|
3431
3361
|
const data = await renderer.renderError(err);
|
|
@@ -3466,6 +3396,9 @@ var CliRunner = class {
|
|
|
3466
3396
|
"-c, --concurrency <num>",
|
|
3467
3397
|
"number of files to build concurrently",
|
|
3468
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'
|
|
3469
3402
|
).option(
|
|
3470
3403
|
"--filter <urlPathRegex>",
|
|
3471
3404
|
'builds the url paths that match the given regex, e.g. "/products/.*"',
|
|
@@ -3532,4 +3465,4 @@ export {
|
|
|
3532
3465
|
createProdServer,
|
|
3533
3466
|
CliRunner
|
|
3534
3467
|
};
|
|
3535
|
-
//# sourceMappingURL=chunk-
|
|
3468
|
+
//# sourceMappingURL=chunk-E4F6CMO3.js.map
|