@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,281 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isDirectory,
|
|
3
|
+
isJsFile
|
|
4
|
+
} from "./chunk-KHO3HMX6.js";
|
|
1
5
|
import {
|
|
2
6
|
getVitePlugins
|
|
3
7
|
} from "./chunk-XSNCF7WU.js";
|
|
4
8
|
|
|
5
|
-
// src/node/
|
|
6
|
-
import path2 from "node:path";
|
|
7
|
-
import { getWorkspaces, getWorkspaceRoot } from "workspace-tools";
|
|
8
|
-
|
|
9
|
-
// src/utils/fsutils.ts
|
|
10
|
-
import fs from "node:fs";
|
|
9
|
+
// src/node/pod-collector.ts
|
|
11
10
|
import path from "node:path";
|
|
12
|
-
import fsExtra from "fs-extra";
|
|
13
11
|
import glob from "tiny-glob";
|
|
14
|
-
function isJsFile(filename) {
|
|
15
|
-
return !!filename.match(/\.(j|t)sx?$/);
|
|
16
|
-
}
|
|
17
|
-
async function writeFile(filepath, content) {
|
|
18
|
-
const dirPath = path.dirname(filepath);
|
|
19
|
-
await makeDir(dirPath);
|
|
20
|
-
await fs.promises.writeFile(filepath, content);
|
|
21
|
-
}
|
|
22
|
-
async function makeDir(dirpath) {
|
|
23
|
-
try {
|
|
24
|
-
await fs.promises.access(dirpath);
|
|
25
|
-
} catch {
|
|
26
|
-
await fs.promises.mkdir(dirpath, { recursive: true });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async function copyDir(srcdir, dstdir) {
|
|
30
|
-
if (!fsExtra.existsSync(srcdir)) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
fsExtra.copySync(srcdir, dstdir, { overwrite: true });
|
|
34
|
-
}
|
|
35
|
-
async function copyGlob(pattern, srcdir, dstdir) {
|
|
36
|
-
const files = await glob(pattern, { cwd: srcdir });
|
|
37
|
-
if (files.length > 0) {
|
|
38
|
-
await makeDir(dstdir);
|
|
39
|
-
}
|
|
40
|
-
files.forEach((file) => {
|
|
41
|
-
fsExtra.copySync(path.resolve(srcdir, file), path.resolve(dstdir, file));
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
async function rmDir(dirpath) {
|
|
45
|
-
await fs.promises.rm(dirpath, { recursive: true, force: true });
|
|
46
|
-
}
|
|
47
|
-
async function loadJson(filepath) {
|
|
48
|
-
const content = await fs.promises.readFile(filepath, "utf-8");
|
|
49
|
-
return JSON.parse(content);
|
|
50
|
-
}
|
|
51
|
-
function loadJsonSync(filepath) {
|
|
52
|
-
const content = fs.readFileSync(filepath, "utf-8");
|
|
53
|
-
return JSON.parse(content);
|
|
54
|
-
}
|
|
55
|
-
async function writeJson(filepath, data) {
|
|
56
|
-
const content = JSON.stringify(data, null, 2);
|
|
57
|
-
await writeFile(filepath, content);
|
|
58
|
-
}
|
|
59
|
-
async function isDirectory(dirpath) {
|
|
60
|
-
return fs.promises.stat(dirpath).then((fsStat) => {
|
|
61
|
-
return fsStat.isDirectory();
|
|
62
|
-
}).catch((err) => {
|
|
63
|
-
if (err.code === "ENOENT") {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
throw err;
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
function fileExists(filepath) {
|
|
70
|
-
return fs.promises.access(filepath).then(() => true).catch(() => false);
|
|
71
|
-
}
|
|
72
|
-
function fileExistsSync(filepath) {
|
|
73
|
-
try {
|
|
74
|
-
fs.accessSync(filepath);
|
|
75
|
-
return true;
|
|
76
|
-
} catch {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
async function dirExists(dirpath) {
|
|
81
|
-
try {
|
|
82
|
-
const stat = await fs.promises.stat(dirpath);
|
|
83
|
-
return stat.isDirectory();
|
|
84
|
-
} catch (error) {
|
|
85
|
-
if (error.code === "ENOENT") {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
throw error;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
async function directoryContains(dirpath, subpath) {
|
|
92
|
-
const outer = await fs.promises.realpath(dirpath);
|
|
93
|
-
const inner = await fs.promises.realpath(subpath);
|
|
94
|
-
const rel = path.relative(outer, inner);
|
|
95
|
-
return !rel.startsWith("..");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// src/node/monorepo.ts
|
|
99
|
-
function loadPackageJson(filepath) {
|
|
100
|
-
if (!fileExistsSync(filepath)) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
return loadJsonSync(filepath);
|
|
104
|
-
}
|
|
105
|
-
function getMonorepoPackages(rootDir) {
|
|
106
|
-
const monorepoRoot = getWorkspaceRoot(rootDir);
|
|
107
|
-
if (!monorepoRoot) {
|
|
108
|
-
return {};
|
|
109
|
-
}
|
|
110
|
-
const workspaces = getWorkspaces(monorepoRoot);
|
|
111
|
-
const packages = {};
|
|
112
|
-
workspaces.forEach((workspaceInfo) => {
|
|
113
|
-
packages[workspaceInfo.name] = workspaceInfo;
|
|
114
|
-
});
|
|
115
|
-
return packages;
|
|
116
|
-
}
|
|
117
|
-
function getMonorepoPackageDeps(rootDir) {
|
|
118
|
-
const monorepoRoot = getWorkspaceRoot(rootDir);
|
|
119
|
-
if (!monorepoRoot) {
|
|
120
|
-
return {};
|
|
121
|
-
}
|
|
122
|
-
const packageJsonPath = path2.join(monorepoRoot, "package.json");
|
|
123
|
-
const packageJson = loadPackageJson(packageJsonPath);
|
|
124
|
-
return packageJson?.dependencies || {};
|
|
125
|
-
}
|
|
126
|
-
function flattenPackageDepsFromMonorepo(rootDir, options) {
|
|
127
|
-
const packageJsonPath = path2.resolve(rootDir, "package.json");
|
|
128
|
-
const packageJson = loadPackageJson(packageJsonPath);
|
|
129
|
-
const monorepoDeps = getMonorepoPackageDeps(rootDir);
|
|
130
|
-
const projectDeps = {
|
|
131
|
-
...packageJson?.peerDependencies,
|
|
132
|
-
...packageJson?.dependencies
|
|
133
|
-
};
|
|
134
|
-
const allDeps = {};
|
|
135
|
-
const workspacePackages = getMonorepoPackages(rootDir);
|
|
136
|
-
const ignore = options?.ignore || /* @__PURE__ */ new Set();
|
|
137
|
-
Object.entries(projectDeps).forEach(([depName, depVersion]) => {
|
|
138
|
-
if (depName.startsWith("@blinkk/root") && depVersion.startsWith("workspace:")) {
|
|
139
|
-
const packageInfo = workspacePackages[depName];
|
|
140
|
-
if (packageInfo) {
|
|
141
|
-
allDeps[depName] = packageInfo.packageJson.version;
|
|
142
|
-
}
|
|
143
|
-
} else if (depVersion.startsWith("workspace:")) {
|
|
144
|
-
if (ignore.has(depName)) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
ignore.add(depName);
|
|
148
|
-
const packageInfo = workspacePackages[depName];
|
|
149
|
-
if (packageInfo) {
|
|
150
|
-
const workspacePackageDir = packageInfo.path;
|
|
151
|
-
const deps = flattenPackageDepsFromMonorepo(workspacePackageDir, {
|
|
152
|
-
ignore
|
|
153
|
-
});
|
|
154
|
-
for (const key in deps) {
|
|
155
|
-
const currentValue = allDeps[key];
|
|
156
|
-
if (deps[key] && deps[key] !== "*" && (!currentValue || currentValue === "*")) {
|
|
157
|
-
allDeps[key] = deps[key];
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
} else if (depVersion === "*" && monorepoDeps[depName]) {
|
|
162
|
-
allDeps[depName] = monorepoDeps[depName];
|
|
163
|
-
} else {
|
|
164
|
-
allDeps[depName] = depVersion;
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
return sortDeps(allDeps);
|
|
168
|
-
}
|
|
169
|
-
function sortDeps(deps) {
|
|
170
|
-
const keys = Object.keys(deps).sort();
|
|
171
|
-
const sortedDeps = {};
|
|
172
|
-
for (const key of keys) {
|
|
173
|
-
sortedDeps[key] = deps[key];
|
|
174
|
-
}
|
|
175
|
-
return sortedDeps;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// src/node/load-config.ts
|
|
179
|
-
import path3 from "node:path";
|
|
180
|
-
import { bundleRequire } from "bundle-require";
|
|
181
|
-
import { build } from "esbuild";
|
|
182
|
-
async function loadRootConfig(rootDir, options) {
|
|
183
|
-
const { rootConfig } = await loadRootConfigWithDeps(rootDir, options);
|
|
184
|
-
return rootConfig;
|
|
185
|
-
}
|
|
186
|
-
async function loadRootConfigWithDeps(rootDir, options) {
|
|
187
|
-
const configPath = path3.resolve(rootDir, "root.config.ts");
|
|
188
|
-
const exists = await fileExists(configPath);
|
|
189
|
-
if (!exists) {
|
|
190
|
-
throw new Error(`${configPath} does not exist`);
|
|
191
|
-
}
|
|
192
|
-
const configBundle = await bundleRequire({
|
|
193
|
-
filepath: configPath,
|
|
194
|
-
esbuildOptions: { plugins: [esbuildExternalsPlugin({ rootDir })] }
|
|
195
|
-
});
|
|
196
|
-
let config = configBundle.mod.default || {};
|
|
197
|
-
if (typeof config === "function") {
|
|
198
|
-
config = await config(options) || {};
|
|
199
|
-
}
|
|
200
|
-
const rootConfig = Object.assign({}, config, { rootDir });
|
|
201
|
-
validateRootconfig(rootConfig);
|
|
202
|
-
return { rootConfig, dependencies: configBundle.dependencies };
|
|
203
|
-
}
|
|
204
|
-
function validateRootconfig(rootConfig) {
|
|
205
|
-
const scss = rootConfig.vite?.css?.preprocessorOptions?.scss;
|
|
206
|
-
if (scss?.includePaths) {
|
|
207
|
-
console.warn(
|
|
208
|
-
'[deprecation warning] root.config.ts: vite.css.preprocessorOptions.scss.includePaths is deprecated. rename "includePaths" -> "loadPaths"'
|
|
209
|
-
);
|
|
210
|
-
scss.loadPaths = scss.includePaths;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
async function bundleRootConfig(rootDir, outPath) {
|
|
214
|
-
const configPath = path3.resolve(rootDir, "root.config.ts");
|
|
215
|
-
const configExists = await fileExists(configPath);
|
|
216
|
-
if (!configExists) {
|
|
217
|
-
throw new Error(`${configPath} does not exist`);
|
|
218
|
-
}
|
|
219
|
-
await build({
|
|
220
|
-
entryPoints: [configPath],
|
|
221
|
-
bundle: true,
|
|
222
|
-
minify: true,
|
|
223
|
-
platform: "node",
|
|
224
|
-
outfile: outPath,
|
|
225
|
-
sourcemap: "inline",
|
|
226
|
-
metafile: true,
|
|
227
|
-
format: "esm",
|
|
228
|
-
plugins: [esbuildExternalsPlugin({ rootDir })]
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
async function loadBundledConfig(rootDir, options) {
|
|
232
|
-
const configPath = path3.resolve(rootDir, "dist/root.config.js");
|
|
233
|
-
const exists = await fileExists(configPath);
|
|
234
|
-
if (!exists) {
|
|
235
|
-
throw new Error(`${configPath} does not exist`);
|
|
236
|
-
}
|
|
237
|
-
const module = await import(configPath);
|
|
238
|
-
let config = module.default || {};
|
|
239
|
-
if (typeof config === "function") {
|
|
240
|
-
config = await config(options) || {};
|
|
241
|
-
}
|
|
242
|
-
return Object.assign({}, config, { rootDir });
|
|
243
|
-
}
|
|
244
|
-
function esbuildExternalsPlugin(options) {
|
|
245
|
-
const rootDir = options.rootDir;
|
|
246
|
-
const allDeps = flattenPackageDepsFromMonorepo(rootDir);
|
|
247
|
-
function getPackageName(id) {
|
|
248
|
-
const segments = id.split("/");
|
|
249
|
-
if (segments.length > 1) {
|
|
250
|
-
if (segments[0].startsWith("@") && segments[0].length > 1) {
|
|
251
|
-
return `${segments[0]}/${segments[1]}`;
|
|
252
|
-
}
|
|
253
|
-
return segments[0];
|
|
254
|
-
}
|
|
255
|
-
return id;
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
name: "root-externals-plugin",
|
|
259
|
-
setup(build2) {
|
|
260
|
-
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
261
|
-
const id = args.path;
|
|
262
|
-
if (id[0] !== "." && !id.startsWith("@/")) {
|
|
263
|
-
const packageName = getPackageName(id);
|
|
264
|
-
if (packageName in allDeps) {
|
|
265
|
-
return {
|
|
266
|
-
external: true
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return null;
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// src/node/pod-collector.ts
|
|
277
|
-
import path4 from "node:path";
|
|
278
|
-
import glob2 from "tiny-glob";
|
|
279
12
|
var cachedPods = null;
|
|
280
13
|
function invalidatePodCache() {
|
|
281
14
|
cachedPods = null;
|
|
@@ -352,24 +85,24 @@ async function scanRouteFiles(routesDir, mount, userConfig, rootConfig) {
|
|
|
352
85
|
if (!await isDirectory(routesDir)) {
|
|
353
86
|
return [];
|
|
354
87
|
}
|
|
355
|
-
const files = await
|
|
88
|
+
const files = await glob("**/*", { cwd: routesDir });
|
|
356
89
|
const routes = [];
|
|
357
90
|
const excludePatterns = userConfig.routes?.exclude || [];
|
|
358
91
|
for (const file of files) {
|
|
359
|
-
const parts =
|
|
92
|
+
const parts = path.parse(file);
|
|
360
93
|
if (parts.name.startsWith("_") || !isJsFile(parts.base)) {
|
|
361
94
|
continue;
|
|
362
95
|
}
|
|
363
96
|
if (shouldExclude(file, excludePatterns)) {
|
|
364
97
|
continue;
|
|
365
98
|
}
|
|
366
|
-
const filePath =
|
|
99
|
+
const filePath = path.join(routesDir, file);
|
|
367
100
|
let relativeRoutePath = "/" + file.replace(/\\/g, "/");
|
|
368
|
-
const routeParts =
|
|
101
|
+
const routeParts = path.parse(relativeRoutePath);
|
|
369
102
|
if (routeParts.name === "index") {
|
|
370
103
|
relativeRoutePath = routeParts.dir;
|
|
371
104
|
} else {
|
|
372
|
-
relativeRoutePath =
|
|
105
|
+
relativeRoutePath = path.join(routeParts.dir, routeParts.name);
|
|
373
106
|
}
|
|
374
107
|
relativeRoutePath = relativeRoutePath.replace(/\\/g, "/");
|
|
375
108
|
const routePath = normalizeRoutePath(mount, relativeRoutePath, rootConfig);
|
|
@@ -381,26 +114,26 @@ async function scanBundleFiles(bundlesDir) {
|
|
|
381
114
|
if (!await isDirectory(bundlesDir)) {
|
|
382
115
|
return [];
|
|
383
116
|
}
|
|
384
|
-
const files = await
|
|
385
|
-
return files.filter((file) => isJsFile(
|
|
117
|
+
const files = await glob("*", { cwd: bundlesDir });
|
|
118
|
+
return files.filter((file) => isJsFile(path.parse(file).base)).map((file) => path.join(bundlesDir, file));
|
|
386
119
|
}
|
|
387
120
|
async function scanCollectionFiles(collectionsDir, userConfig) {
|
|
388
121
|
if (!await isDirectory(collectionsDir)) {
|
|
389
122
|
return [];
|
|
390
123
|
}
|
|
391
|
-
const files = await
|
|
124
|
+
const files = await glob("**/*.schema.ts", { cwd: collectionsDir });
|
|
392
125
|
const excludeIds = new Set(userConfig.collections?.exclude || []);
|
|
393
126
|
const renameMap = userConfig.collections?.rename || {};
|
|
394
127
|
const collections = [];
|
|
395
128
|
for (const file of files) {
|
|
396
|
-
const parts =
|
|
129
|
+
const parts = path.parse(file);
|
|
397
130
|
const rawId = parts.name.replace(".schema", "");
|
|
398
131
|
if (excludeIds.has(rawId)) {
|
|
399
132
|
continue;
|
|
400
133
|
}
|
|
401
134
|
const id = renameMap[rawId] || rawId;
|
|
402
135
|
collections.push({
|
|
403
|
-
filePath:
|
|
136
|
+
filePath: path.join(collectionsDir, file),
|
|
404
137
|
relPath: file,
|
|
405
138
|
id
|
|
406
139
|
});
|
|
@@ -411,10 +144,10 @@ async function scanTranslationFiles(translationsDir) {
|
|
|
411
144
|
if (!await isDirectory(translationsDir)) {
|
|
412
145
|
return [];
|
|
413
146
|
}
|
|
414
|
-
const files = await
|
|
147
|
+
const files = await glob("*.json", { cwd: translationsDir });
|
|
415
148
|
return files.map((file) => ({
|
|
416
|
-
locale:
|
|
417
|
-
filePath:
|
|
149
|
+
locale: path.parse(file).name,
|
|
150
|
+
filePath: path.join(translationsDir, file)
|
|
418
151
|
}));
|
|
419
152
|
}
|
|
420
153
|
function validateCollectionIds(pods) {
|
|
@@ -477,8 +210,8 @@ function shouldExclude(filePath, patterns) {
|
|
|
477
210
|
import { createServer } from "vite";
|
|
478
211
|
|
|
479
212
|
// src/node/pods-vite-plugin.ts
|
|
480
|
-
import
|
|
481
|
-
import
|
|
213
|
+
import path2 from "node:path";
|
|
214
|
+
import glob2 from "tiny-glob";
|
|
482
215
|
var VIRTUAL_ROUTES_ID = "virtual:root/routes";
|
|
483
216
|
var VIRTUAL_SCHEMAS_ID = "virtual:root/schemas";
|
|
484
217
|
var VIRTUAL_TRANSLATIONS_ID = "virtual:root/translations";
|
|
@@ -573,11 +306,11 @@ async function buildRoutesModule(rootConfig, pods) {
|
|
|
573
306
|
const userEntries = [];
|
|
574
307
|
const podEntries = [];
|
|
575
308
|
let idx = 0;
|
|
576
|
-
const routesDir =
|
|
309
|
+
const routesDir = path2.join(rootDir, "routes");
|
|
577
310
|
if (await isDirectory(routesDir)) {
|
|
578
|
-
const files = await
|
|
311
|
+
const files = await glob2("**/*", { cwd: routesDir });
|
|
579
312
|
for (const file of files) {
|
|
580
|
-
const parts =
|
|
313
|
+
const parts = path2.parse(file);
|
|
581
314
|
if (parts.name.startsWith("_") || !isJsFile(parts.base)) {
|
|
582
315
|
continue;
|
|
583
316
|
}
|
|
@@ -614,11 +347,11 @@ async function buildSchemasModule(rootConfig, pods) {
|
|
|
614
347
|
const entries = [];
|
|
615
348
|
let idx = 0;
|
|
616
349
|
const userCollectionIds = /* @__PURE__ */ new Set();
|
|
617
|
-
const collectionsDir =
|
|
350
|
+
const collectionsDir = path2.join(rootDir, "collections");
|
|
618
351
|
if (await isDirectory(collectionsDir)) {
|
|
619
|
-
const files = await
|
|
352
|
+
const files = await glob2("**/*.schema.ts", { cwd: collectionsDir });
|
|
620
353
|
for (const file of files) {
|
|
621
|
-
const parts =
|
|
354
|
+
const parts = path2.parse(file);
|
|
622
355
|
const id = parts.name.replace(".schema", "");
|
|
623
356
|
userCollectionIds.add(id);
|
|
624
357
|
const modulePath = `/collections/${file.replace(/\\/g, "/")}`;
|
|
@@ -658,7 +391,7 @@ async function scanRootSchemaFiles(rootDir) {
|
|
|
658
391
|
const excludeDirs = ["appengine", "functions", "gae", "node_modules", "dist"];
|
|
659
392
|
let files;
|
|
660
393
|
try {
|
|
661
|
-
files = await
|
|
394
|
+
files = await glob2("**/*.schema.ts", { cwd: rootDir });
|
|
662
395
|
} catch {
|
|
663
396
|
return [];
|
|
664
397
|
}
|
|
@@ -673,11 +406,11 @@ async function buildTranslationsModule(rootConfig, pods) {
|
|
|
673
406
|
const entries = [];
|
|
674
407
|
let idx = 0;
|
|
675
408
|
const userLocales = /* @__PURE__ */ new Set();
|
|
676
|
-
const translationsDir =
|
|
409
|
+
const translationsDir = path2.join(rootDir, "translations");
|
|
677
410
|
if (await isDirectory(translationsDir)) {
|
|
678
|
-
const files = await
|
|
411
|
+
const files = await glob2("*.json", { cwd: translationsDir });
|
|
679
412
|
for (const file of files) {
|
|
680
|
-
const locale =
|
|
413
|
+
const locale = path2.parse(file).name;
|
|
681
414
|
userLocales.add(locale);
|
|
682
415
|
const modulePath = `/translations/${file}`;
|
|
683
416
|
const varName = `_t${idx++}`;
|
|
@@ -825,25 +558,6 @@ function hmrSSRReload() {
|
|
|
825
558
|
}
|
|
826
559
|
|
|
827
560
|
export {
|
|
828
|
-
isJsFile,
|
|
829
|
-
writeFile,
|
|
830
|
-
makeDir,
|
|
831
|
-
copyDir,
|
|
832
|
-
copyGlob,
|
|
833
|
-
rmDir,
|
|
834
|
-
loadJson,
|
|
835
|
-
writeJson,
|
|
836
|
-
isDirectory,
|
|
837
|
-
fileExists,
|
|
838
|
-
dirExists,
|
|
839
|
-
directoryContains,
|
|
840
|
-
loadPackageJson,
|
|
841
|
-
getMonorepoPackageDeps,
|
|
842
|
-
flattenPackageDepsFromMonorepo,
|
|
843
|
-
loadRootConfig,
|
|
844
|
-
loadRootConfigWithDeps,
|
|
845
|
-
bundleRootConfig,
|
|
846
|
-
loadBundledConfig,
|
|
847
561
|
invalidatePodCache,
|
|
848
562
|
collectPods,
|
|
849
563
|
rootPodsVitePlugin,
|
|
@@ -851,4 +565,4 @@ export {
|
|
|
851
565
|
createViteServer,
|
|
852
566
|
viteSsrLoadModule
|
|
853
567
|
};
|
|
854
|
-
//# sourceMappingURL=chunk-
|
|
568
|
+
//# sourceMappingURL=chunk-YU22SAIG.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/node/pod-collector.ts", "../src/node/vite.ts", "../src/node/pods-vite-plugin.ts", "../src/node/vite-plugin-root-jsx-virtual.ts"],
|
|
4
|
+
"sourcesContent": ["import path from 'node:path';\nimport glob from 'tiny-glob';\nimport {RootConfig} from '../core/config.js';\nimport {Plugin} from '../core/plugin.js';\nimport {Pod, PodConfig} from '../core/pod.js';\nimport {isDirectory, isJsFile} from '../utils/fsutils.js';\n\nexport interface ResolvedPodRoute {\n filePath: string;\n relPath: string;\n routePath: string;\n}\n\nexport interface ResolvedPodCollection {\n filePath: string;\n relPath: string;\n id: string;\n}\n\nexport interface ResolvedPod {\n name: string;\n enabled: boolean;\n mount: string;\n priority: number;\n routesDir?: string;\n elementsDirs: string[];\n bundlesDir?: string;\n collectionsDir?: string;\n translationsDir?: string;\n routeFiles: ResolvedPodRoute[];\n bundleFiles: string[];\n collectionFiles: ResolvedPodCollection[];\n translationFiles: Array<{locale: string; filePath: string}>;\n config: PodConfig;\n}\n\nlet cachedPods: ResolvedPod[] | null = null;\n\nexport function invalidatePodCache() {\n cachedPods = null;\n}\n\nexport async function collectPods(\n rootConfig: RootConfig\n): Promise<ResolvedPod[]> {\n if (cachedPods) {\n return cachedPods;\n }\n\n const plugins = rootConfig.plugins || [];\n const userPodConfigs = rootConfig.pods || {};\n\n const rawPods = await resolvePluginPods(plugins, rootConfig);\n const resolved: ResolvedPod[] = [];\n\n const seenNames = new Set<string>();\n for (const pod of rawPods) {\n if (seenNames.has(pod.name)) {\n throw new Error(\n `Duplicate pod name: \"${pod.name}\". Each pod must have a unique name.`\n );\n }\n seenNames.add(pod.name);\n\n const userConfig = userPodConfigs[pod.name] || {};\n if (userConfig.enabled === false) {\n continue;\n }\n\n const resolvedPod = await resolvePod(pod, userConfig, rootConfig);\n resolved.push(resolvedPod);\n }\n\n validateCollectionIds(resolved);\n\n cachedPods = resolved;\n return resolved;\n}\n\nasync function resolvePluginPods(\n plugins: Plugin[],\n rootConfig: RootConfig\n): Promise<Pod[]> {\n const pods: Pod[] = [];\n for (const plugin of plugins) {\n if (!plugin.pod) {\n continue;\n }\n if (typeof plugin.pod === 'function') {\n const result = await plugin.pod({rootConfig});\n pods.push(result);\n } else if (Array.isArray(plugin.pod)) {\n pods.push(...plugin.pod);\n } else {\n pods.push(plugin.pod);\n }\n }\n return pods;\n}\n\nasync function resolvePod(\n pod: Pod,\n userConfig: PodConfig,\n rootConfig: RootConfig\n): Promise<ResolvedPod> {\n const mount = normalizeMountPath(userConfig.mount ?? pod.mount ?? '/');\n const priority = userConfig.priority ?? pod.priority ?? 0;\n\n const routeFiles = pod.routesDir\n ? await scanRouteFiles(pod.routesDir, mount, userConfig, rootConfig)\n : [];\n\n const bundleFiles = pod.bundlesDir\n ? await scanBundleFiles(pod.bundlesDir)\n : [];\n\n const collectionFiles = pod.collectionsDir\n ? await scanCollectionFiles(pod.collectionsDir, userConfig)\n : [];\n\n const translationFiles = pod.translationsDir\n ? await scanTranslationFiles(pod.translationsDir)\n : [];\n\n return {\n name: pod.name,\n enabled: true,\n mount,\n priority,\n routesDir: pod.routesDir,\n elementsDirs: pod.elementsDirs || [],\n bundlesDir: pod.bundlesDir,\n collectionsDir: pod.collectionsDir,\n translationsDir: pod.translationsDir,\n routeFiles,\n bundleFiles,\n collectionFiles,\n translationFiles,\n config: userConfig,\n };\n}\n\nasync function scanRouteFiles(\n routesDir: string,\n mount: string,\n userConfig: PodConfig,\n rootConfig: RootConfig\n): Promise<ResolvedPodRoute[]> {\n if (!(await isDirectory(routesDir))) {\n return [];\n }\n\n const files = await glob('**/*', {cwd: routesDir});\n const routes: ResolvedPodRoute[] = [];\n const excludePatterns = userConfig.routes?.exclude || [];\n\n for (const file of files) {\n const parts = path.parse(file);\n if (parts.name.startsWith('_') || !isJsFile(parts.base)) {\n continue;\n }\n\n if (shouldExclude(file, excludePatterns)) {\n continue;\n }\n\n const filePath = path.join(routesDir, file);\n let relativeRoutePath = '/' + file.replace(/\\\\/g, '/');\n const routeParts = path.parse(relativeRoutePath);\n if (routeParts.name === 'index') {\n relativeRoutePath = routeParts.dir;\n } else {\n relativeRoutePath = path.join(routeParts.dir, routeParts.name);\n }\n relativeRoutePath = relativeRoutePath.replace(/\\\\/g, '/');\n\n const routePath = normalizeRoutePath(mount, relativeRoutePath, rootConfig);\n\n routes.push({filePath, relPath: file, routePath});\n }\n\n return routes;\n}\n\nasync function scanBundleFiles(bundlesDir: string): Promise<string[]> {\n if (!(await isDirectory(bundlesDir))) {\n return [];\n }\n const files = await glob('*', {cwd: bundlesDir});\n return files\n .filter((file) => isJsFile(path.parse(file).base))\n .map((file) => path.join(bundlesDir, file));\n}\n\nasync function scanCollectionFiles(\n collectionsDir: string,\n userConfig: PodConfig\n): Promise<ResolvedPodCollection[]> {\n if (!(await isDirectory(collectionsDir))) {\n return [];\n }\n const files = await glob('**/*.schema.ts', {cwd: collectionsDir});\n const excludeIds = new Set(userConfig.collections?.exclude || []);\n const renameMap = userConfig.collections?.rename || {};\n const collections: ResolvedPodCollection[] = [];\n\n for (const file of files) {\n const parts = path.parse(file);\n const rawId = parts.name.replace('.schema', '');\n if (excludeIds.has(rawId)) {\n continue;\n }\n const id = renameMap[rawId] || rawId;\n collections.push({\n filePath: path.join(collectionsDir, file),\n relPath: file,\n id,\n });\n }\n\n return collections;\n}\n\nasync function scanTranslationFiles(\n translationsDir: string\n): Promise<Array<{locale: string; filePath: string}>> {\n if (!(await isDirectory(translationsDir))) {\n return [];\n }\n const files = await glob('*.json', {cwd: translationsDir});\n return files.map((file) => ({\n locale: path.parse(file).name,\n filePath: path.join(translationsDir, file),\n }));\n}\n\nfunction validateCollectionIds(pods: ResolvedPod[]) {\n const seenIds = new Map<string, string>();\n\n for (const pod of pods) {\n for (const col of pod.collectionFiles) {\n const existing = seenIds.get(col.id);\n if (existing) {\n throw new Error(\n `Collection \"${col.id}\" is defined by both \"${existing}\" and ` +\n `\"${pod.name}\". Use rootConfig.pods['${pod.name}'].collections.rename ` +\n 'to disambiguate.'\n );\n }\n seenIds.set(col.id, pod.name);\n }\n }\n}\n\nfunction normalizeMountPath(mount: string): string {\n if (!mount.startsWith('/')) {\n mount = '/' + mount;\n }\n if (mount.endsWith('/') && mount.length > 1) {\n mount = mount.slice(0, -1);\n }\n return mount;\n}\n\nfunction normalizeRoutePath(\n mount: string,\n relativeRoutePath: string,\n rootConfig: RootConfig\n): string {\n const basePath = rootConfig.base || '/';\n let fullPath: string;\n if (mount === '/') {\n fullPath = relativeRoutePath || '/';\n } else {\n fullPath = mount + (relativeRoutePath || '');\n }\n\n if (basePath !== '/') {\n const base = basePath.replace(/^\\/|\\/$/g, '');\n fullPath = `/${base}${fullPath}`;\n }\n\n // Collapse multiple slashes.\n fullPath = fullPath.replace(/\\/+/g, '/');\n if (!fullPath.startsWith('/')) {\n fullPath = '/' + fullPath;\n }\n return fullPath || '/';\n}\n\nfunction shouldExclude(\n filePath: string,\n patterns: (string | RegExp)[]\n): boolean {\n for (const pattern of patterns) {\n if (typeof pattern === 'string') {\n if (filePath.includes(pattern)) {\n return true;\n }\n } else {\n if (pattern.test(filePath)) {\n return true;\n }\n }\n }\n return false;\n}\n", "import {createServer, ViteDevServer} from 'vite';\nimport type {Plugin, EnvironmentModuleNode} from 'vite';\nimport {RootConfig} from '../core/config.js';\nimport {getVitePlugins} from '../core/plugin.js';\nimport {rootPodsVitePlugin} from './pods-vite-plugin.js';\nimport {preactToRootJsxPlugin} from './vite-plugin-root-jsx-virtual.js';\n\nexport interface CreateViteServerOptions {\n /** Override HMR settings. */\n hmr?: boolean;\n /** The port the server will run on. */\n port?: number;\n /** List of files to include in the optimizeDeps.include config. */\n optimizeDeps?: string[];\n}\n\n/**\n * Returns a vite dev server.\n */\nexport async function createViteServer(\n rootConfig: RootConfig,\n options?: CreateViteServerOptions\n): Promise<ViteDevServer> {\n const rootDir = rootConfig.rootDir;\n const viteConfig = rootConfig.vite || {};\n\n let hmrOptions = viteConfig.server?.hmr;\n if (options?.hmr === false) {\n hmrOptions = false;\n } else if (typeof hmrOptions === 'undefined' && options?.port) {\n // Automatically set the HMR port to `port + 10`. This allows multiple\n // root.js dev servers to run without conflicts.\n hmrOptions = {port: options.port + 10};\n }\n\n const viteServer = await createServer({\n ...viteConfig,\n mode: 'development',\n root: rootDir,\n // publicDir is disabled from the vite dev server since it's handled by the\n // root dev server directly, which allows user middlewares to override\n // files in the public dir.\n publicDir: false,\n server: {\n ...(viteConfig.server || {}),\n middlewareMode: true,\n hmr: hmrOptions,\n },\n appType: 'custom',\n optimizeDeps: {\n ...(viteConfig.optimizeDeps || {}),\n include: [\n ...(options?.optimizeDeps || []),\n ...(viteConfig.optimizeDeps?.include || []),\n ],\n extensions: [...(viteConfig.optimizeDeps?.extensions || []), '.tsx'],\n },\n ssr: {\n ...(viteConfig.ssr || {}),\n noExternal: ['@blinkk/root', '@blinkk/root-cms/richtext', /^virtual:/],\n },\n plugins: [\n rootPodsVitePlugin(rootConfig),\n hmrSSRReload(),\n preactToRootJsxPlugin({useRootJsx: !!rootConfig.jsxRenderer?.mode}),\n ...(viteConfig.plugins || []),\n ...getVitePlugins(rootConfig.plugins || []),\n ],\n });\n return viteServer;\n}\n\n/**\n * Shortcut `viteServer.ssrLoadModule()` without starting an actual dev server.\n */\nexport async function viteSsrLoadModule<T = Record<string, any>>(\n rootConfig: RootConfig,\n file: string\n): Promise<T> {\n const viteServer = await createViteServer(rootConfig, {hmr: false});\n const module = await viteServer.ssrLoadModule(file);\n await viteServer.close();\n return module as T;\n}\n\n/**\n * Vite plugin to reload the page when SSR modules change.\n * https://github.com/vitejs/vite/issues/19114\n */\nfunction hmrSSRReload(): Plugin {\n return {\n name: 'hmr-ssr-reload',\n enforce: 'post',\n hotUpdate: {\n order: 'post',\n handler({modules, server, timestamp}) {\n if (this.environment.name !== 'ssr') {\n return;\n }\n\n let hasSsrOnlyModules = false;\n const invalidatedModules = new Set<EnvironmentModuleNode>();\n for (const mod of modules) {\n if (mod.id === null) {\n continue;\n }\n const clientModule =\n server.environments.client.moduleGraph.getModuleById(mod.id);\n if (clientModule) {\n continue;\n }\n\n hasSsrOnlyModules = true;\n this.environment.moduleGraph.invalidateModule(\n mod,\n invalidatedModules,\n timestamp,\n true\n );\n }\n\n if (hasSsrOnlyModules) {\n server.ws.send({type: 'full-reload'});\n return [];\n }\n\n return;\n },\n },\n };\n}\n", "import path from 'node:path';\nimport glob from 'tiny-glob';\nimport type {Plugin as VitePlugin} from 'vite';\nimport {RootConfig} from '../core/config.js';\nimport {isDirectory, isJsFile} from '../utils/fsutils.js';\nimport {collectPods, invalidatePodCache, ResolvedPod} from './pod-collector.js';\n\nexport const VIRTUAL_ROUTES_ID = 'virtual:root/routes';\nexport const VIRTUAL_SCHEMAS_ID = 'virtual:root/schemas';\nexport const VIRTUAL_TRANSLATIONS_ID = 'virtual:root/translations';\n\nconst RESOLVED_VIRTUAL_ROUTES = '\\0' + VIRTUAL_ROUTES_ID;\nconst RESOLVED_VIRTUAL_SCHEMAS = '\\0' + VIRTUAL_SCHEMAS_ID;\nconst RESOLVED_VIRTUAL_TRANSLATIONS = '\\0' + VIRTUAL_TRANSLATIONS_ID;\n\nexport function rootPodsVitePlugin(rootConfig: RootConfig): VitePlugin {\n let podsPromise: Promise<ResolvedPod[]> | null = null;\n\n const getPods = () => {\n if (!podsPromise) {\n podsPromise = collectPods(rootConfig);\n }\n return podsPromise;\n };\n\n return {\n name: 'root:pods',\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ROUTES_ID) return RESOLVED_VIRTUAL_ROUTES;\n if (id === VIRTUAL_SCHEMAS_ID) return RESOLVED_VIRTUAL_SCHEMAS;\n if (id === VIRTUAL_TRANSLATIONS_ID) return RESOLVED_VIRTUAL_TRANSLATIONS;\n return null;\n },\n\n async load(id) {\n if (id === RESOLVED_VIRTUAL_ROUTES) {\n return buildRoutesModule(rootConfig, await getPods());\n }\n if (id === RESOLVED_VIRTUAL_SCHEMAS) {\n return buildSchemasModule(rootConfig, await getPods());\n }\n if (id === RESOLVED_VIRTUAL_TRANSLATIONS) {\n return buildTranslationsModule(rootConfig, await getPods());\n }\n return null;\n },\n\n configureServer(server) {\n const watchDirs: string[] = [];\n getPods().then((pods) => {\n for (const pod of pods) {\n if (pod.routesDir) watchDirs.push(pod.routesDir);\n if (pod.collectionsDir) watchDirs.push(pod.collectionsDir);\n if (pod.translationsDir) watchDirs.push(pod.translationsDir);\n if (pod.bundlesDir) watchDirs.push(pod.bundlesDir);\n for (const dir of pod.elementsDirs) {\n watchDirs.push(dir);\n }\n }\n for (const dir of watchDirs) {\n server.watcher.add(dir);\n }\n });\n\n const invalidateVirtualModules = () => {\n invalidatePodCache();\n podsPromise = null;\n const mods = [\n RESOLVED_VIRTUAL_ROUTES,\n RESOLVED_VIRTUAL_SCHEMAS,\n RESOLVED_VIRTUAL_TRANSLATIONS,\n ];\n for (const modId of mods) {\n const mod = server.moduleGraph.getModuleById(modId);\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n }\n }\n server.ws.send({type: 'full-reload'});\n };\n\n server.watcher.on('add', (filePath) => {\n if (isInPodDir(filePath, watchDirs)) {\n invalidateVirtualModules();\n }\n });\n server.watcher.on('unlink', (filePath) => {\n if (isInPodDir(filePath, watchDirs)) {\n invalidateVirtualModules();\n }\n });\n },\n };\n}\n\nfunction isInPodDir(filePath: string, watchDirs: string[]): boolean {\n for (const dir of watchDirs) {\n if (filePath.startsWith(dir)) {\n return true;\n }\n }\n return false;\n}\n\nasync function buildRoutesModule(\n rootConfig: RootConfig,\n pods: ResolvedPod[]\n): Promise<string> {\n const rootDir = rootConfig.rootDir;\n const imports: string[] = [];\n const userEntries: string[] = [];\n const podEntries: string[] = [];\n let idx = 0;\n\n // User project routes.\n const routesDir = path.join(rootDir, 'routes');\n if (await isDirectory(routesDir)) {\n const files = await glob('**/*', {cwd: routesDir});\n for (const file of files) {\n const parts = path.parse(file);\n if (parts.name.startsWith('_') || !isJsFile(parts.base)) {\n continue;\n }\n const modulePath = `/routes/${file.replace(/\\\\/g, '/')}`;\n const varName = `_r${idx++}`;\n imports.push(`import * as ${varName} from '${modulePath}';`);\n userEntries.push(` '${modulePath}': ${varName},`);\n }\n }\n\n // Pod routes.\n for (const pod of pods) {\n for (const route of pod.routeFiles) {\n const varName = `_r${idx++}`;\n imports.push(`import * as ${varName} from '${route.filePath}';`);\n podEntries.push(\n ` '${route.filePath}': {module: ${varName}, podName: ${JSON.stringify(pod.name)}, routePath: ${JSON.stringify(route.routePath)}, src: ${JSON.stringify(`pod/${pod.name}/${route.relPath}`)}},`\n );\n }\n }\n\n return [\n ...imports,\n '',\n 'export const ROUTE_MODULES = {',\n ...userEntries,\n '};',\n '',\n 'export const POD_ROUTE_MODULES = {',\n ...podEntries,\n '};',\n ].join('\\n');\n}\n\nasync function buildSchemasModule(\n rootConfig: RootConfig,\n pods: ResolvedPod[]\n): Promise<string> {\n const rootDir = rootConfig.rootDir;\n const imports: string[] = [];\n const entries: string[] = [];\n let idx = 0;\n\n // User project collections \u2014 these win over pod collections.\n const userCollectionIds = new Set<string>();\n const collectionsDir = path.join(rootDir, 'collections');\n if (await isDirectory(collectionsDir)) {\n const files = await glob('**/*.schema.ts', {cwd: collectionsDir});\n for (const file of files) {\n const parts = path.parse(file);\n const id = parts.name.replace('.schema', '');\n userCollectionIds.add(id);\n const modulePath = `/collections/${file.replace(/\\\\/g, '/')}`;\n const varName = `_s${idx++}`;\n imports.push(`import * as ${varName} from '${modulePath}';`);\n entries.push(` '${modulePath}': ${varName},`);\n }\n }\n\n // Also scan root-level schema files that match the existing patterns\n // (e.g. /templates/**/*.schema.ts), excluding known non-collection dirs.\n const rootSchemaFiles = await scanRootSchemaFiles(rootDir);\n for (const file of rootSchemaFiles) {\n const modulePath = `/${file.replace(/\\\\/g, '/')}`;\n // Skip if already in collections.\n if (modulePath.startsWith('/collections/')) continue;\n const varName = `_s${idx++}`;\n imports.push(`import * as ${varName} from '${modulePath}';`);\n entries.push(` '${modulePath}': ${varName},`);\n }\n\n // Pod collections \u2014 user project wins on id collision.\n for (const pod of pods) {\n for (const col of pod.collectionFiles) {\n if (userCollectionIds.has(col.id)) {\n continue;\n }\n const varName = `_s${idx++}`;\n imports.push(`import * as ${varName} from '${col.filePath}';`);\n const key = `/collections/${col.id}.schema.ts`;\n entries.push(` '${key}': ${varName},`);\n }\n }\n\n return [\n ...imports,\n '',\n 'export const SCHEMA_MODULES = {',\n ...entries,\n '};',\n ].join('\\n');\n}\n\nasync function scanRootSchemaFiles(rootDir: string): Promise<string[]> {\n const excludeDirs = ['appengine', 'functions', 'gae', 'node_modules', 'dist'];\n let files: string[];\n try {\n files = await glob('**/*.schema.ts', {cwd: rootDir});\n } catch {\n return [];\n }\n return files.filter((file) => {\n const normalized = file.replace(/\\\\/g, '/');\n return !excludeDirs.some((dir) => normalized.startsWith(dir + '/'));\n });\n}\n\nasync function buildTranslationsModule(\n rootConfig: RootConfig,\n pods: ResolvedPod[]\n): Promise<string> {\n const rootDir = rootConfig.rootDir;\n const imports: string[] = [];\n const entries: string[] = [];\n let idx = 0;\n\n // User translations take precedence.\n const userLocales = new Set<string>();\n const translationsDir = path.join(rootDir, 'translations');\n if (await isDirectory(translationsDir)) {\n const files = await glob('*.json', {cwd: translationsDir});\n for (const file of files) {\n const locale = path.parse(file).name;\n userLocales.add(locale);\n const modulePath = `/translations/${file}`;\n const varName = `_t${idx++}`;\n imports.push(`import ${varName} from '${modulePath}';`);\n entries.push(` '${modulePath}': {default: ${varName}},`);\n }\n }\n\n // Pod translations.\n for (const pod of pods) {\n for (const t of pod.translationFiles) {\n const varName = `_t${idx++}`;\n imports.push(`import ${varName} from '${t.filePath}';`);\n // Use a synthetic key that includes the pod name for merging.\n const key = `/translations/pod:${pod.name}:${t.locale}.json`;\n entries.push(` '${key}': {default: ${varName}},`);\n }\n }\n\n return [\n ...imports,\n '',\n 'export const TRANSLATION_MODULES = {',\n ...entries,\n '};',\n ].join('\\n');\n}\n", "import type {Plugin} from 'vite';\n\nexport interface PreactToRootJsxPluginOptions {\n /** Whether Root's JSX renderer mode is enabled. */\n useRootJsx?: boolean;\n}\n\n/**\n * Vite plugin that aliases `preact` imports to `@blinkk/root/jsx` in the SSR\n * environment only.\n *\n * When `jsxRenderer.mode` is configured, the project uses Root's built-in JSX\n * runtime instead of Preact for server-side rendering. This plugin redirects\n * `preact` imports (`preact`, `preact/hooks`, `preact/jsx-runtime`, etc.) to\n * Root's JSX package, but only in the SSR environment. Client-side code (e.g.\n * islands that depend on real Preact for hydration) is left untouched.\n */\nexport function preactToRootJsxPlugin(\n options?: PreactToRootJsxPluginOptions\n): Plugin {\n const useRootJsx = options?.useRootJsx ?? false;\n\n /**\n * Preact import specifiers to redirect in SSR when `jsxRenderer.mode` is\n * enabled.\n */\n const SSR_REDIRECTS: Record<string, string> = {\n preact: '@blinkk/root/jsx',\n 'preact/hooks': '@blinkk/root/jsx',\n 'preact/jsx-runtime': '@blinkk/root/jsx/jsx-runtime',\n 'preact/jsx-dev-runtime': '@blinkk/root/jsx/jsx-dev-runtime',\n };\n\n return {\n name: 'root:preact-to-jsx',\n async resolveId(id, importer, resolveOptions) {\n if (!useRootJsx) {\n return null;\n }\n\n const ssrTarget = SSR_REDIRECTS[id];\n if (!ssrTarget) {\n return null;\n }\n\n // Only rewrite in the SSR environment. Client-side code (islands)\n // continues to use the real Preact package.\n const isSSR = this.environment?.name === 'ssr';\n if (!isSSR) {\n return null;\n }\n\n const resolved = await this.resolve(ssrTarget, importer, {\n ...resolveOptions,\n skipSelf: true,\n });\n return resolved;\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path", "glob", "path", "glob"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { RootConfig } from '../core/config.js';
|
|
2
|
+
import { Route } from '../core/types.js';
|
|
3
|
+
type Renderer = import('../render/render.js').Renderer;
|
|
4
|
+
/** A single page to build during the SSG phase of `root build`. */
|
|
5
|
+
export interface BuildPageTask {
|
|
6
|
+
/** The url path to build, e.g. `/intl/de/about/`. */
|
|
7
|
+
urlPath: string;
|
|
8
|
+
/** Route params used to build the page. */
|
|
9
|
+
params: Record<string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* The route's src file (e.g. `routes/blog/[slug].tsx`). Used by worker
|
|
12
|
+
* threads to disambiguate overlapping routes that match the same url path.
|
|
13
|
+
*/
|
|
14
|
+
routeSrc?: string;
|
|
15
|
+
/** The route's locale, used with `routeSrc` to disambiguate routes. */
|
|
16
|
+
locale?: string;
|
|
17
|
+
}
|
|
18
|
+
/** The result of building a single page. */
|
|
19
|
+
export interface BuildPageResult {
|
|
20
|
+
urlPath: string;
|
|
21
|
+
/** Output file path relative to the build dir. Unset when `notFound`. */
|
|
22
|
+
outFilePath?: string;
|
|
23
|
+
notFound?: boolean;
|
|
24
|
+
/** Whether the output was generated via `getStaticContent()`. */
|
|
25
|
+
staticContent?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** Message sent from the build worker to the main thread. */
|
|
28
|
+
export type BuildWorkerResponse = {
|
|
29
|
+
type: 'ready';
|
|
30
|
+
} | {
|
|
31
|
+
type: 'result';
|
|
32
|
+
id: number;
|
|
33
|
+
result: BuildPageResult;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'error';
|
|
36
|
+
id: number;
|
|
37
|
+
urlPath: string;
|
|
38
|
+
params: Record<string, string>;
|
|
39
|
+
routeSrc?: string;
|
|
40
|
+
error: string;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'fatal';
|
|
43
|
+
error: string;
|
|
44
|
+
};
|
|
45
|
+
/** Message sent from the main thread to the build worker. */
|
|
46
|
+
export type BuildWorkerRequest = {
|
|
47
|
+
type: 'render';
|
|
48
|
+
id: number;
|
|
49
|
+
task: BuildPageTask;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Builds a single page (or static content file) to the build dir. Shared by
|
|
53
|
+
* the in-process SSG build loop and the `--threads` build worker.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildPage(renderer: Renderer, rootConfig: RootConfig, buildDir: string, route: Route, task: BuildPageTask): Promise<BuildPageResult>;
|
|
56
|
+
export declare function normalizeLineEndings(str: string): string;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { BuildPageResult, BuildPageTask } from './build-page.js';
|
|
2
|
+
export interface BuildWorkerPoolOptions {
|
|
3
|
+
/** Number of worker threads. */
|
|
4
|
+
numWorkers: number;
|
|
5
|
+
/**
|
|
6
|
+
* Number of pages each worker renders concurrently. Rendering is async, so
|
|
7
|
+
* pages that wait on I/O (e.g. CMS fetches in `getStaticProps()`) don't
|
|
8
|
+
* block other pages on the same thread.
|
|
9
|
+
*/
|
|
10
|
+
workerConcurrency: number;
|
|
11
|
+
/** Project root dir, passed to each worker. */
|
|
12
|
+
rootDir: string;
|
|
13
|
+
/** Build mode (e.g. "production"), passed to each worker. */
|
|
14
|
+
mode: string;
|
|
15
|
+
}
|
|
16
|
+
interface PendingTask {
|
|
17
|
+
id: number;
|
|
18
|
+
task: BuildPageTask;
|
|
19
|
+
resolve: (result: BuildPageResult) => void;
|
|
20
|
+
reject: (err: Error) => void;
|
|
21
|
+
}
|
|
22
|
+
export declare class BuildPageError extends Error {
|
|
23
|
+
urlPath: string;
|
|
24
|
+
params: Record<string, string>;
|
|
25
|
+
routeSrc?: string;
|
|
26
|
+
workerError: string;
|
|
27
|
+
constructor(urlPath: string, params: Record<string, string>, routeSrc: string | undefined, workerError: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A pool of worker threads that render SSG pages in parallel. Each worker
|
|
31
|
+
* loads the site's built server bundle (`dist/server/render.js`) and renders
|
|
32
|
+
* pages independently, allowing the build to utilize multiple CPU cores.
|
|
33
|
+
*/
|
|
34
|
+
export declare class BuildWorkerPool {
|
|
35
|
+
private workers;
|
|
36
|
+
private queue;
|
|
37
|
+
private nextTaskId;
|
|
38
|
+
constructor(options: BuildWorkerPoolOptions);
|
|
39
|
+
/** Waits for all workers to finish initializing. */
|
|
40
|
+
ready(): Promise<void>;
|
|
41
|
+
/** Schedules a page build and resolves when the page finishes. */
|
|
42
|
+
run(task: BuildPageTask): Promise<BuildPageResult>;
|
|
43
|
+
dequeue(): PendingTask | undefined;
|
|
44
|
+
terminate(): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
package/dist/cli/build.d.ts
CHANGED
|
@@ -3,5 +3,11 @@ export interface BuildOptions {
|
|
|
3
3
|
mode?: string;
|
|
4
4
|
concurrency?: string | number;
|
|
5
5
|
filter?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Renders pages using worker threads. Pass a number to use exactly N
|
|
8
|
+
* workers, or pass without a value (or "auto") to pick a worker count
|
|
9
|
+
* automatically based on CPU cores and the number of pages to build.
|
|
10
|
+
*/
|
|
11
|
+
threads?: string | boolean;
|
|
6
12
|
}
|
|
7
13
|
export declare function build(rootProjectDir?: string, options?: BuildOptions): Promise<void>;
|