@blinkk/root 2.0.0-rc.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5YDJSEDK.js → chunk-3KGEENDW.js} +47 -1
- package/dist/chunk-3KGEENDW.js.map +1 -0
- package/dist/{chunk-7D26JHIF.js → chunk-A4DNVP34.js} +335 -140
- package/dist/chunk-A4DNVP34.js.map +1 -0
- package/dist/{chunk-UJ6F5RQ5.js → chunk-HTBDTUFE.js} +148 -63
- package/dist/chunk-HTBDTUFE.js.map +1 -0
- package/dist/{chunk-ZUUGSC6Z.js → chunk-MA6MSEP4.js} +1 -1
- package/dist/chunk-MA6MSEP4.js.map +1 -0
- package/dist/cli.d.ts +4 -2
- package/dist/cli.js +4 -4
- package/dist/core.d.ts +35 -5
- package/dist/core.js +82 -9
- package/dist/core.js.map +1 -1
- package/dist/functions.js +4 -4
- package/dist/middleware.d.ts +2 -2
- package/dist/node.d.ts +17 -3
- package/dist/node.js +6 -2
- package/dist/render.d.ts +1 -1
- package/dist/render.js +12741 -125
- package/dist/render.js.map +1 -1
- package/dist/{types-RwR6rV2O.d.ts → types-Mr1zFAT1.d.ts} +80 -28
- package/package.json +6 -3
- package/dist/chunk-5YDJSEDK.js.map +0 -1
- package/dist/chunk-7D26JHIF.js.map +0 -1
- package/dist/chunk-UJ6F5RQ5.js.map +0 -1
- package/dist/chunk-ZUUGSC6Z.js.map +0 -1
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getVitePlugins
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MA6MSEP4.js";
|
|
4
4
|
|
|
5
|
-
// src/node/
|
|
5
|
+
// src/node/monorepo.ts
|
|
6
6
|
import path2 from "node:path";
|
|
7
|
-
import {
|
|
8
|
-
import { build } from "esbuild";
|
|
7
|
+
import { getWorkspaces, getWorkspaceRoot } from "workspace-tools";
|
|
9
8
|
|
|
10
9
|
// src/utils/fsutils.ts
|
|
11
|
-
import
|
|
10
|
+
import fs from "node:fs";
|
|
12
11
|
import path from "node:path";
|
|
13
12
|
import fsExtra from "fs-extra";
|
|
14
13
|
import glob from "tiny-glob";
|
|
@@ -18,13 +17,13 @@ function isJsFile(filename) {
|
|
|
18
17
|
async function writeFile(filepath, content) {
|
|
19
18
|
const dirPath = path.dirname(filepath);
|
|
20
19
|
await makeDir(dirPath);
|
|
21
|
-
await fs.writeFile(filepath, content);
|
|
20
|
+
await fs.promises.writeFile(filepath, content);
|
|
22
21
|
}
|
|
23
22
|
async function makeDir(dirpath) {
|
|
24
23
|
try {
|
|
25
|
-
await fs.access(dirpath);
|
|
24
|
+
await fs.promises.access(dirpath);
|
|
26
25
|
} catch (e) {
|
|
27
|
-
await fs.mkdir(dirpath, { recursive: true });
|
|
26
|
+
await fs.promises.mkdir(dirpath, { recursive: true });
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
async function copyDir(srcdir, dstdir) {
|
|
@@ -43,10 +42,14 @@ async function copyGlob(pattern, srcdir, dstdir) {
|
|
|
43
42
|
});
|
|
44
43
|
}
|
|
45
44
|
async function rmDir(dirpath) {
|
|
46
|
-
await fs.rm(dirpath, { recursive: true, force: true });
|
|
45
|
+
await fs.promises.rm(dirpath, { recursive: true, force: true });
|
|
47
46
|
}
|
|
48
47
|
async function loadJson(filepath) {
|
|
49
|
-
const content = await fs.readFile(filepath, "utf-8");
|
|
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");
|
|
50
53
|
return JSON.parse(content);
|
|
51
54
|
}
|
|
52
55
|
async function writeJson(filepath, data) {
|
|
@@ -54,7 +57,7 @@ async function writeJson(filepath, data) {
|
|
|
54
57
|
await writeFile(filepath, content);
|
|
55
58
|
}
|
|
56
59
|
async function isDirectory(dirpath) {
|
|
57
|
-
return fs.stat(dirpath).then((fsStat) => {
|
|
60
|
+
return fs.promises.stat(dirpath).then((fsStat) => {
|
|
58
61
|
return fsStat.isDirectory();
|
|
59
62
|
}).catch((err) => {
|
|
60
63
|
if (err.code === "ENOENT") {
|
|
@@ -64,11 +67,19 @@ async function isDirectory(dirpath) {
|
|
|
64
67
|
});
|
|
65
68
|
}
|
|
66
69
|
function fileExists(filepath) {
|
|
67
|
-
return fs.access(filepath).then(() => true).catch(() => false);
|
|
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
|
+
}
|
|
68
79
|
}
|
|
69
80
|
async function dirExists(dirpath) {
|
|
70
81
|
try {
|
|
71
|
-
const stat = await fs.stat(dirpath);
|
|
82
|
+
const stat = await fs.promises.stat(dirpath);
|
|
72
83
|
return stat.isDirectory();
|
|
73
84
|
} catch (error) {
|
|
74
85
|
if (error.code === "ENOENT") {
|
|
@@ -78,21 +89,105 @@ async function dirExists(dirpath) {
|
|
|
78
89
|
}
|
|
79
90
|
}
|
|
80
91
|
async function directoryContains(dirpath, subpath) {
|
|
81
|
-
const outer = await fs.realpath(dirpath);
|
|
82
|
-
const inner = await fs.realpath(subpath);
|
|
92
|
+
const outer = await fs.promises.realpath(dirpath);
|
|
93
|
+
const inner = await fs.promises.realpath(subpath);
|
|
83
94
|
const rel = path.relative(outer, inner);
|
|
84
95
|
return !rel.startsWith("..");
|
|
85
96
|
}
|
|
86
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
|
+
|
|
87
178
|
// src/node/load-config.ts
|
|
179
|
+
import path3 from "node:path";
|
|
180
|
+
import { bundleRequire } from "bundle-require";
|
|
181
|
+
import { build } from "esbuild";
|
|
88
182
|
async function loadRootConfig(rootDir, options) {
|
|
89
|
-
const configPath =
|
|
183
|
+
const configPath = path3.resolve(rootDir, "root.config.ts");
|
|
90
184
|
const exists = await fileExists(configPath);
|
|
91
185
|
if (!exists) {
|
|
92
186
|
throw new Error(`${configPath} does not exist`);
|
|
93
187
|
}
|
|
94
188
|
const configBundle = await bundleRequire({
|
|
95
|
-
filepath: configPath
|
|
189
|
+
filepath: configPath,
|
|
190
|
+
esbuildOptions: { plugins: [esbuildExternalsPlugin({ rootDir })] }
|
|
96
191
|
});
|
|
97
192
|
let config = configBundle.mod.default || {};
|
|
98
193
|
if (typeof config === "function") {
|
|
@@ -101,27 +196,11 @@ async function loadRootConfig(rootDir, options) {
|
|
|
101
196
|
return Object.assign({}, config, { rootDir });
|
|
102
197
|
}
|
|
103
198
|
async function bundleRootConfig(rootDir, outPath) {
|
|
104
|
-
const configPath =
|
|
199
|
+
const configPath = path3.resolve(rootDir, "root.config.ts");
|
|
105
200
|
const configExists = await fileExists(configPath);
|
|
106
201
|
if (!configExists) {
|
|
107
202
|
throw new Error(`${configPath} does not exist`);
|
|
108
203
|
}
|
|
109
|
-
const packageJsonPath = path2.resolve(rootDir, "package.json");
|
|
110
|
-
const packageJson = await loadPackageJson(packageJsonPath);
|
|
111
|
-
const allDeps = {
|
|
112
|
-
...packageJson.peerDependencies,
|
|
113
|
-
...packageJson.dependencies
|
|
114
|
-
};
|
|
115
|
-
function getPackageName(id) {
|
|
116
|
-
const segments = id.split("/");
|
|
117
|
-
if (segments.length > 1) {
|
|
118
|
-
if (segments[0].startsWith("@") && segments[0].length > 1) {
|
|
119
|
-
return `${segments[0]}/${segments[1]}`;
|
|
120
|
-
}
|
|
121
|
-
return segments[0];
|
|
122
|
-
}
|
|
123
|
-
return id;
|
|
124
|
-
}
|
|
125
204
|
await build({
|
|
126
205
|
entryPoints: [configPath],
|
|
127
206
|
bundle: true,
|
|
@@ -131,30 +210,11 @@ async function bundleRootConfig(rootDir, outPath) {
|
|
|
131
210
|
sourcemap: "inline",
|
|
132
211
|
metafile: true,
|
|
133
212
|
format: "esm",
|
|
134
|
-
plugins: [
|
|
135
|
-
// Externalizes deps that are in package.json.
|
|
136
|
-
{
|
|
137
|
-
name: "externalize-package-json-deps",
|
|
138
|
-
setup(build2) {
|
|
139
|
-
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
140
|
-
const id = args.path;
|
|
141
|
-
if (id[0] !== "." && !id.startsWith("@/")) {
|
|
142
|
-
const packageName = getPackageName(id);
|
|
143
|
-
if (packageName in allDeps) {
|
|
144
|
-
return {
|
|
145
|
-
external: true
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return null;
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
]
|
|
213
|
+
plugins: [esbuildExternalsPlugin({ rootDir })]
|
|
154
214
|
});
|
|
155
215
|
}
|
|
156
216
|
async function loadBundledConfig(rootDir, options) {
|
|
157
|
-
const configPath =
|
|
217
|
+
const configPath = path3.resolve(rootDir, "dist/root.config.js");
|
|
158
218
|
const exists = await fileExists(configPath);
|
|
159
219
|
if (!exists) {
|
|
160
220
|
throw new Error(`${configPath} does not exist`);
|
|
@@ -166,13 +226,36 @@ async function loadBundledConfig(rootDir, options) {
|
|
|
166
226
|
}
|
|
167
227
|
return Object.assign({}, config, { rootDir });
|
|
168
228
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
229
|
+
function esbuildExternalsPlugin(options) {
|
|
230
|
+
const rootDir = options.rootDir;
|
|
231
|
+
const allDeps = flattenPackageDepsFromMonorepo(rootDir);
|
|
232
|
+
function getPackageName(id) {
|
|
233
|
+
const segments = id.split("/");
|
|
234
|
+
if (segments.length > 1) {
|
|
235
|
+
if (segments[0].startsWith("@") && segments[0].length > 1) {
|
|
236
|
+
return `${segments[0]}/${segments[1]}`;
|
|
237
|
+
}
|
|
238
|
+
return segments[0];
|
|
239
|
+
}
|
|
240
|
+
return id;
|
|
175
241
|
}
|
|
242
|
+
return {
|
|
243
|
+
name: "root-externals-plugin",
|
|
244
|
+
setup(build2) {
|
|
245
|
+
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
246
|
+
const id = args.path;
|
|
247
|
+
if (id[0] !== "." && !id.startsWith("@/")) {
|
|
248
|
+
const packageName = getPackageName(id);
|
|
249
|
+
if (packageName in allDeps) {
|
|
250
|
+
return {
|
|
251
|
+
external: true
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
};
|
|
176
259
|
}
|
|
177
260
|
|
|
178
261
|
// src/node/vite.ts
|
|
@@ -257,11 +340,13 @@ export {
|
|
|
257
340
|
fileExists,
|
|
258
341
|
dirExists,
|
|
259
342
|
directoryContains,
|
|
343
|
+
loadPackageJson,
|
|
344
|
+
getMonorepoPackageDeps,
|
|
345
|
+
flattenPackageDepsFromMonorepo,
|
|
260
346
|
loadRootConfig,
|
|
261
347
|
bundleRootConfig,
|
|
262
348
|
loadBundledConfig,
|
|
263
|
-
loadPackageJson,
|
|
264
349
|
createViteServer,
|
|
265
350
|
viteSsrLoadModule
|
|
266
351
|
};
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
352
|
+
//# sourceMappingURL=chunk-HTBDTUFE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/node/monorepo.ts","../src/utils/fsutils.ts","../src/node/load-config.ts","../src/node/vite.ts"],"sourcesContent":["import path from 'node:path';\nimport {getWorkspaces, getWorkspaceRoot, PackageInfo} from 'workspace-tools';\nimport {fileExistsSync, loadJsonSync} from '../utils/fsutils.js';\n\ninterface WorkspacePackage {\n name: string;\n path: string;\n packageJson: PackageInfo;\n}\n\nexport function loadPackageJson(filepath: string): PackageInfo | null {\n if (!fileExistsSync(filepath)) {\n return null;\n }\n return loadJsonSync(filepath);\n}\n\n/**\n * Returns a map of all packages in the monorepo and the corresponding\n * package.json path.\n */\nfunction getMonorepoPackages(\n rootDir: string\n): Record<string, WorkspacePackage> {\n const monorepoRoot = getWorkspaceRoot(rootDir);\n if (!monorepoRoot) {\n return {};\n }\n\n const workspaces = getWorkspaces(monorepoRoot);\n const packages: Record<string, WorkspacePackage> = {};\n workspaces.forEach((workspaceInfo) => {\n packages[workspaceInfo.name] = workspaceInfo;\n });\n return packages;\n}\n\n/**\n * Returns the top-level monorepo package's deps, if any.\n */\nexport function getMonorepoPackageDeps(\n rootDir: string\n): Record<string, string> {\n const monorepoRoot = getWorkspaceRoot(rootDir);\n if (!monorepoRoot) {\n return {};\n }\n\n const packageJsonPath = path.join(monorepoRoot, 'package.json');\n const packageJson = loadPackageJson(packageJsonPath);\n return packageJson?.dependencies || {};\n}\n\n/**\n * Flattens package.json deps from the root project dir, taking into account any\n * deps from the monorepo root as well as any `workspace:` deps from within the\n * monorepo.\n */\nexport function flattenPackageDepsFromMonorepo(\n rootDir: string,\n options?: {ignore?: Set<string>}\n): Record<string, string> {\n const packageJsonPath = path.resolve(rootDir, 'package.json');\n const packageJson = loadPackageJson(packageJsonPath);\n const monorepoDeps = getMonorepoPackageDeps(rootDir);\n\n // Flatten `peerDependencies` and `dependencies`.\n const projectDeps = {\n ...packageJson?.peerDependencies,\n ...packageJson?.dependencies,\n };\n\n const allDeps: Record<string, string> = {};\n const workspacePackages = getMonorepoPackages(rootDir);\n const ignore = options?.ignore || new Set();\n Object.entries(projectDeps).forEach(([depName, depVersion]) => {\n if (\n depName.startsWith('@blinkk/root') &&\n depVersion.startsWith('workspace:')\n ) {\n const packageInfo = workspacePackages[depName];\n if (packageInfo) {\n allDeps[depName] = packageInfo.packageJson.version;\n }\n } else if (depVersion.startsWith('workspace:')) {\n // For internal packages within the workspace, recursively collect the\n // deps from those packages.\n if (ignore.has(depName)) {\n return;\n }\n ignore.add(depName);\n const packageInfo = workspacePackages[depName];\n if (packageInfo) {\n const workspacePackageDir = packageInfo.path;\n const deps = flattenPackageDepsFromMonorepo(workspacePackageDir, {\n ignore: ignore,\n });\n for (const key in deps) {\n const currentValue = allDeps[key];\n if (\n deps[key] &&\n deps[key] !== '*' &&\n (!currentValue || currentValue === '*')\n ) {\n allDeps[key] = deps[key];\n }\n }\n }\n } else if (depVersion === '*' && monorepoDeps[depName]) {\n // For any dependencies using a wildcard version `*`, if the top-level\n // package.json has the depdenency defined, overwrite the version.\n allDeps[depName] = monorepoDeps[depName];\n } else {\n allDeps[depName] = depVersion;\n }\n });\n return sortDeps(allDeps);\n}\n\nfunction sortDeps(deps: Record<string, string>): Record<string, string> {\n const keys = Object.keys(deps).sort();\n const sortedDeps: Record<string, string> = {};\n for (const key of keys) {\n sortedDeps[key] = deps[key];\n }\n return sortedDeps;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport fsExtra from 'fs-extra';\nimport glob from 'tiny-glob';\n\nexport function isJsFile(filename: string) {\n return !!filename.match(/\\.(j|t)sx?$/);\n}\n\nexport async function writeFile(filepath: string, content: string) {\n const dirPath = path.dirname(filepath);\n await makeDir(dirPath);\n await fs.promises.writeFile(filepath, content);\n}\n\nexport async function makeDir(dirpath: string) {\n try {\n await fs.promises.access(dirpath);\n } catch (e) {\n await fs.promises.mkdir(dirpath, {recursive: true});\n }\n}\n\nexport async function copyDir(srcdir: string, dstdir: string) {\n if (!fsExtra.existsSync(srcdir)) {\n return;\n }\n fsExtra.copySync(srcdir, dstdir, {overwrite: true});\n}\n\n/**\n * Copies a glob of files from one directory to another.\n *\n * Example:\n *\n * ```\n * await copyGlob('*.css', 'src/styles', 'dist/html/styles');\n * ```\n */\nexport async function copyGlob(\n pattern: string,\n srcdir: string,\n dstdir: string\n) {\n const files = await glob(pattern, {cwd: srcdir});\n if (files.length > 0) {\n await makeDir(dstdir);\n }\n files.forEach((file) => {\n fsExtra.copySync(path.resolve(srcdir, file), path.resolve(dstdir, file));\n });\n}\n\nexport async function rmDir(dirpath: string) {\n await fs.promises.rm(dirpath, {recursive: true, force: true});\n}\n\nexport async function loadJson<T = unknown>(filepath: string): Promise<T> {\n const content = await fs.promises.readFile(filepath, 'utf-8');\n return JSON.parse(content);\n}\n\nexport function loadJsonSync<T = unknown>(filepath: string): T {\n const content = fs.readFileSync(filepath, 'utf-8');\n return JSON.parse(content);\n}\n\nexport async function writeJson(filepath: string, data: any) {\n const content = JSON.stringify(data, null, 2);\n await writeFile(filepath, content);\n}\n\nexport async function isDirectory(dirpath: string) {\n return fs.promises\n .stat(dirpath)\n .then((fsStat) => {\n return fsStat.isDirectory();\n })\n .catch((err) => {\n if (err.code === 'ENOENT') {\n return false;\n }\n throw err;\n });\n}\n\nexport function fileExists(filepath: string): Promise<boolean> {\n return fs.promises\n .access(filepath)\n .then(() => true)\n .catch(() => false);\n}\n\nexport function fileExistsSync(filepath: string): boolean {\n try {\n fs.accessSync(filepath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function dirExists(dirpath: string): Promise<boolean> {\n try {\n const stat = await fs.promises.stat(dirpath);\n return stat.isDirectory();\n } catch (error) {\n if (error.code === 'ENOENT') {\n return false;\n }\n throw error;\n }\n}\n\nexport async function directoryContains(\n dirpath: string,\n subpath: string\n): Promise<boolean> {\n const outer = await fs.promises.realpath(dirpath);\n const inner = await fs.promises.realpath(subpath);\n const rel = path.relative(outer, inner);\n return !rel.startsWith('..');\n}\n\nexport async function listFilesRecursive(dirPath: string): Promise<string[]> {\n const files: string[] = [];\n const entries = await fs.promises.readdir(dirPath, {withFileTypes: true});\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n const subFiles = await listFilesRecursive(fullPath);\n files.push(...subFiles);\n } else {\n files.push(fullPath);\n }\n }\n return files;\n}\n","import path from 'node:path';\nimport {bundleRequire} from 'bundle-require';\nimport {build, Plugin as EsbuildPlugin} from 'esbuild';\nimport {RootConfig} from '../core/config.js';\nimport {fileExists} from '../utils/fsutils.js';\nimport {flattenPackageDepsFromMonorepo} from './monorepo.js';\n\nexport interface ConfigOptions {\n command: string;\n}\n\nexport async function loadRootConfig(\n rootDir: string,\n options: ConfigOptions\n): Promise<RootConfig> {\n const configPath = path.resolve(rootDir, 'root.config.ts');\n const exists = await fileExists(configPath);\n if (!exists) {\n throw new Error(`${configPath} does not exist`);\n }\n const configBundle = await bundleRequire({\n filepath: configPath,\n esbuildOptions: {plugins: [esbuildExternalsPlugin({rootDir})]},\n });\n let config = configBundle.mod.default || {};\n if (typeof config === 'function') {\n config = (await config(options)) || {};\n }\n return Object.assign({}, config, {rootDir});\n}\n\n/**\n * Compiles a root.config.ts file to root.config.js.\n */\nexport async function bundleRootConfig(rootDir: string, outPath: string) {\n const configPath = path.resolve(rootDir, 'root.config.ts');\n const configExists = await fileExists(configPath);\n if (!configExists) {\n throw new Error(`${configPath} does not exist`);\n }\n await build({\n entryPoints: [configPath],\n bundle: true,\n minify: true,\n platform: 'node',\n outfile: outPath,\n sourcemap: 'inline',\n metafile: true,\n format: 'esm',\n plugins: [esbuildExternalsPlugin({rootDir})],\n });\n}\n\n/**\n * Loads a pre-bundled config file from dist/root.config.js.\n */\nexport async function loadBundledConfig(\n rootDir: string,\n options: ConfigOptions\n): Promise<RootConfig> {\n const configPath = path.resolve(rootDir, 'dist/root.config.js');\n const exists = await fileExists(configPath);\n if (!exists) {\n throw new Error(`${configPath} does not exist`);\n }\n const module = await import(configPath);\n let config = module.default || {};\n if (typeof config === 'function') {\n config = (await config(options)) || {};\n }\n return Object.assign({}, config, {rootDir});\n}\n\n/**\n * Externalizes node_modules deps from the package and any dependent packages\n * from the monorepo.\n */\nfunction esbuildExternalsPlugin(options: {rootDir: string}): EsbuildPlugin {\n const rootDir = options.rootDir;\n const allDeps = flattenPackageDepsFromMonorepo(rootDir);\n\n function getPackageName(id: string): string {\n const segments = id.split('/');\n if (segments.length > 1) {\n // Check if package is an org path like `@blinkk/root`.\n if (segments[0].startsWith('@') && segments[0].length > 1) {\n return `${segments[0]}/${segments[1]}`;\n }\n // For imports like `my-package/subpackage`, return `my-package`.\n return segments[0];\n }\n return id;\n }\n\n return {\n name: 'root-externals-plugin',\n setup(build) {\n build.onResolve({filter: /.*/}, (args) => {\n const id = args.path;\n if (id[0] !== '.' && !id.startsWith('@/')) {\n const packageName = getPackageName(id);\n if (packageName in allDeps) {\n return {\n external: true,\n };\n }\n }\n return null;\n });\n },\n };\n}\n","import {createServer, ViteDevServer} from 'vite';\nimport {RootConfig} from '../core/config.js';\nimport {getVitePlugins} from '../core/plugin.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 // As of vite v5 / esbuild v19, experimentalDecorators need to be\n // explicitly set, and for some reason this option isn't read from the\n // project's tsconfig.json file by default.\n // See: https://vitejs.dev/blog/announcing-vite5\n esbuildOptions: {\n tsconfigRaw: {\n compilerOptions: {\n target: 'esnext',\n experimentalDecorators: true,\n useDefineForClassFields: false,\n },\n },\n },\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'],\n },\n esbuild: {\n ...(viteConfig.esbuild || {}),\n jsx: 'automatic',\n jsxImportSource: 'preact',\n },\n plugins: [\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(\n rootConfig: RootConfig,\n file: string\n): Promise<Record<string, any>> {\n const viteServer = await createViteServer(rootConfig, {hmr: false});\n const module = await viteServer.ssrLoadModule(file);\n await viteServer.close();\n return module;\n}\n"],"mappings":"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","names":["path","path","path","path","build"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/plugin.ts"],"sourcesContent":["import {ViteDevServer, PluginOption as VitePlugin} from 'vite';\nimport {RootConfig} from './config.js';\nimport {NextFunction, Request, Response, Server} from './types.js';\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport type ConfigureServerHook = (\n server: Server,\n options: ConfigureServerOptions\n) => MaybePromise<void> | MaybePromise<() => void>;\n\nexport interface ConfigureServerOptions {\n type: 'dev' | 'preview' | 'prod';\n rootConfig: RootConfig;\n}\n\nexport interface PluginHooks {\n /**\n * Post-render hook that's called before the HTML is rendered to the response\n * object. If a string is returned from this hook, it will replace the\n * rendered HTML.\n */\n preRender: (html: string) => void | string | Promise<string>;\n}\n\nexport interface Plugin {\n [key: string]: any;\n /** The name of the plugin. */\n name?: string;\n /**\n * Configures the root.js express server. Any middleware defined by the plugin\n * will be added to the server first. If a callback fn is returned, it will\n * be called after the root.js middlewares are added.\n */\n configureServer?: ConfigureServerHook;\n /**\n * Hook for file changes.\n */\n onFileChange?: (\n eventName: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir',\n path: string\n ) => void;\n /**\n * Returns a list of deps to bundle for ssr. The files will be bundled and\n * output to `dist/server/`. The return value should be a map of\n * `{output filename => input filepath}`.\n *\n * E.g. a value of `{foo: 'path/to/bar.js'}` will output `dist/server/foo.js`.\n *\n * @experimental This config is subject to change to be incorporated into a\n * broader config option called \"ssr\" or \"ssrOptions\".\n */\n ssrInput?: () => {[entryAlias: string]: string};\n /** Adds vite plugins. */\n vitePlugins?: VitePlugin[];\n /** Plugin lifecycle callback hooks. */\n hooks?: PluginHooks;\n /** Custom 404 handler. */\n handle404?: (\n req: Request,\n res: Response,\n next: NextFunction\n ) => void | Promise<void>;\n}\n\n/**\n * Runs the pre-hook configureServer method of every plugin, calls a callback\n * function, and then runs the configureServer's post-hook if provided. Plugins\n * provide a post-hook by returning a callback function from configureServer.\n */\nexport async function configureServerPlugins(\n server: Server,\n callback: () => Promise<void>,\n plugins: Plugin[],\n options: ConfigureServerOptions\n) {\n const postHooks: Array<() => void> = [];\n const viteServer = server.get('viteServer') as ViteDevServer;\n\n // Call the `configureServer()` method for each plugin.\n for (const plugin of plugins) {\n if (plugin.configureServer) {\n const postHook = await plugin.configureServer(server, options);\n if (postHook) {\n postHooks.push(postHook);\n }\n }\n\n if (viteServer && plugin.onFileChange) {\n viteServer.watcher.on('all', plugin.onFileChange);\n }\n }\n\n // Register any built-in middleware.\n callback();\n\n // Run any post hooks returned by `plugin.configureServer()`.\n for (const postHook of postHooks) {\n await postHook();\n }\n}\n\nexport function getVitePlugins(plugins: Plugin[]): VitePlugin[] {\n const vitePlugins: VitePlugin[] = [];\n for (const plugin of plugins) {\n if (plugin.vitePlugins) {\n vitePlugins.push(...plugin.vitePlugins);\n }\n }\n return vitePlugins;\n}\n"],"mappings":";AAsEA,eAAsB,uBACpB,QACA,UACA,SACA,SACA;AACA,QAAM,YAA+B,CAAC;AACtC,QAAM,aAAa,OAAO,IAAI,YAAY;AAG1C,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,iBAAiB;AAC1B,YAAM,WAAW,MAAM,OAAO,gBAAgB,QAAQ,OAAO;AAC7D,UAAI,UAAU;AACZ,kBAAU,KAAK,QAAQ;AAAA,MACzB;AAAA,IACF;AAEA,QAAI,cAAc,OAAO,cAAc;AACrC,iBAAW,QAAQ,GAAG,OAAO,OAAO,YAAY;AAAA,IAClD;AAAA,EACF;AAGA,WAAS;AAGT,aAAW,YAAY,WAAW;AAChC,UAAM,SAAS;AAAA,EACjB;AACF;AAEO,SAAS,eAAe,SAAiC;AAC9D,QAAM,cAA4B,CAAC;AACnC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,aAAa;AACtB,kBAAY,KAAK,GAAG,OAAO,WAAW;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as Server } from './types-
|
|
1
|
+
import { S as Server } from './types-Mr1zFAT1.js';
|
|
2
2
|
import 'express';
|
|
3
3
|
import 'preact';
|
|
4
4
|
import 'vite';
|
|
@@ -9,6 +9,7 @@ interface BuildOptions {
|
|
|
9
9
|
ssrOnly?: boolean;
|
|
10
10
|
mode?: string;
|
|
11
11
|
concurrency?: string | number;
|
|
12
|
+
filter?: string;
|
|
12
13
|
}
|
|
13
14
|
declare function build(rootProjectDir?: string, options?: BuildOptions): Promise<void>;
|
|
14
15
|
|
|
@@ -18,6 +19,7 @@ interface CreatePackageOptions {
|
|
|
18
19
|
out?: string;
|
|
19
20
|
target?: DeployTarget;
|
|
20
21
|
version?: string;
|
|
22
|
+
appYaml?: string;
|
|
21
23
|
}
|
|
22
24
|
declare function createPackage(rootProjectDir?: string, options?: CreatePackageOptions): Promise<void>;
|
|
23
25
|
|
|
@@ -53,4 +55,4 @@ declare class CliRunner {
|
|
|
53
55
|
run(argv: string[]): Promise<void>;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
export { CliRunner, build, createDevServer, createPackage, createPreviewServer, createProdServer, dev, preview, start };
|
|
58
|
+
export { type BuildOptions, CliRunner, build, createDevServer, createPackage, createPreviewServer, createProdServer, dev, preview, start };
|
package/dist/cli.js
CHANGED
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
dev,
|
|
9
9
|
preview,
|
|
10
10
|
start
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-A4DNVP34.js";
|
|
12
12
|
import "./chunk-DISVDCLA.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-HTBDTUFE.js";
|
|
14
|
+
import "./chunk-MA6MSEP4.js";
|
|
15
|
+
import "./chunk-3KGEENDW.js";
|
|
16
16
|
export {
|
|
17
17
|
CliRunner,
|
|
18
18
|
build,
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Route } from './types-
|
|
2
|
-
export { j as ConfigureServerHook, k as ConfigureServerOptions, C as ContentSecurityPolicyConfig, p as GetStaticPaths, G as GetStaticProps, t as Handler, H as HandlerContext,
|
|
1
|
+
import { R as Route } from './types-Mr1zFAT1.js';
|
|
2
|
+
export { j as ConfigureServerHook, k as ConfigureServerOptions, C as ContentSecurityPolicyConfig, v as GetStaticContent, p as GetStaticPaths, G as GetStaticProps, t as Handler, H as HandlerContext, y as HandlerRenderFn, x as HandlerRenderOptions, L as LocaleGroup, M as MultipartFile, N as NextFunction, l as Plugin, P as PluginHooks, r as Request, q as RequestMiddleware, s as Response, d as RootBuildConfig, b as RootConfig, f as RootHeaderConfig, c as RootI18nConfig, e as RootRedirectConfig, g as RootSecurityConfig, h as RootServerConfig, a as RootUserConfig, w as RouteModule, o as RouteParams, S as Server, z as Sitemap, A as SitemapItem, u as StaticContentResult, X as XFrameOptionsConfig, m as configureServerPlugins, i as defineConfig, n as getVitePlugins } from './types-Mr1zFAT1.js';
|
|
3
3
|
import * as preact$1 from 'preact';
|
|
4
4
|
import { FunctionalComponent, ComponentChildren } from 'preact';
|
|
5
5
|
import 'express';
|
|
@@ -72,7 +72,9 @@ type HtmlProps = preact$1.JSX.HTMLAttributes<HTMLHtmlElement> & {
|
|
|
72
72
|
*/
|
|
73
73
|
declare const Html: FunctionalComponent<HtmlProps>;
|
|
74
74
|
|
|
75
|
-
type ScriptProps = preact.JSX.HTMLAttributes<HTMLScriptElement
|
|
75
|
+
type ScriptProps = preact.JSX.HTMLAttributes<HTMLScriptElement> & {
|
|
76
|
+
src?: string;
|
|
77
|
+
};
|
|
76
78
|
/**
|
|
77
79
|
* The <Script> component is used for rendering any custom script modules. At
|
|
78
80
|
* the moment, the system only pre-renders and bundles files that are in the
|
|
@@ -87,7 +89,11 @@ type ScriptProps = preact.JSX.HTMLAttributes<HTMLScriptElement>;
|
|
|
87
89
|
declare const Script: FunctionalComponent<ScriptProps>;
|
|
88
90
|
|
|
89
91
|
type StringParamsContext = Record<string, string>;
|
|
90
|
-
|
|
92
|
+
interface StringParamsProviderProps {
|
|
93
|
+
value?: StringParamsContext;
|
|
94
|
+
children?: ComponentChildren;
|
|
95
|
+
}
|
|
96
|
+
declare const StringParamsProvider: FunctionalComponent<StringParamsProviderProps>;
|
|
91
97
|
/**
|
|
92
98
|
* A hook that returns a map of string params, configured via the
|
|
93
99
|
* `StringParamsProvider` context provider. These params are automatically
|
|
@@ -115,6 +121,30 @@ declare const StringParamsProvider: preact$1.Provider<StringParamsContext | null
|
|
|
115
121
|
*/
|
|
116
122
|
declare function useStringParams(): StringParamsContext;
|
|
117
123
|
|
|
124
|
+
type TransformFn = (str: string) => string;
|
|
125
|
+
interface TranslationMiddleware {
|
|
126
|
+
/** Transform the string before translation lookup. */
|
|
127
|
+
beforeTranslate?: TransformFn;
|
|
128
|
+
/** Transform the string after translation lookup. */
|
|
129
|
+
afterTranslate?: TransformFn;
|
|
130
|
+
/** Transform the string before `{param}` values are replaced. */
|
|
131
|
+
beforeReplaceParams?: TransformFn;
|
|
132
|
+
/** Transform the string after `{param}` values are replaced. */
|
|
133
|
+
afterReplaceParams?: TransformFn;
|
|
134
|
+
}
|
|
135
|
+
interface TranslationMiddlewareContext {
|
|
136
|
+
beforeTranslateFns: TransformFn[];
|
|
137
|
+
afterTranslateFns: TransformFn[];
|
|
138
|
+
beforeReplaceParamsFns: TransformFn[];
|
|
139
|
+
afterReplaceParamsFns: TransformFn[];
|
|
140
|
+
}
|
|
141
|
+
interface TranslationMiddlewareProviderProps {
|
|
142
|
+
value?: TranslationMiddleware;
|
|
143
|
+
children?: ComponentChildren;
|
|
144
|
+
}
|
|
145
|
+
declare const TranslationMiddlewareProvider: FunctionalComponent<TranslationMiddlewareProviderProps>;
|
|
146
|
+
declare function useTranslationMiddleware(): TranslationMiddlewareContext;
|
|
147
|
+
|
|
118
148
|
interface I18nContext {
|
|
119
149
|
locale: string;
|
|
120
150
|
translations: Record<string, string>;
|
|
@@ -175,4 +205,4 @@ declare function useRequestContext(): RequestContext;
|
|
|
175
205
|
*/
|
|
176
206
|
declare function useTranslations(): (str: string, params?: Record<string, string | number>) => string;
|
|
177
207
|
|
|
178
|
-
export { Body, HTML_CONTEXT, Head, Html, type I18nContext, type RequestContext, Route, Script, type StringParamsContext, StringParamsProvider, getTranslations, useI18nContext, useRequestContext, useStringParams, useTranslations };
|
|
208
|
+
export { Body, HTML_CONTEXT, Head, Html, type I18nContext, type RequestContext, Route, Script, type StringParamsContext, StringParamsProvider, TranslationMiddlewareProvider, getTranslations, useI18nContext, useRequestContext, useStringParams, useTranslationMiddleware, useTranslations };
|
package/dist/core.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
configureServerPlugins,
|
|
3
3
|
getVitePlugins
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MA6MSEP4.js";
|
|
5
5
|
import {
|
|
6
6
|
HTML_CONTEXT,
|
|
7
7
|
Html,
|
|
@@ -56,17 +56,63 @@ var Script = (props) => {
|
|
|
56
56
|
return null;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
// src/core/hooks/useStringParams.
|
|
59
|
+
// src/core/hooks/useStringParams.tsx
|
|
60
60
|
import { createContext } from "preact";
|
|
61
61
|
import { useContext as useContext4 } from "preact/hooks";
|
|
62
|
+
import { jsx as jsx2 } from "preact/jsx-runtime";
|
|
62
63
|
var STRING_PARAMS_CONTEXT = createContext(
|
|
63
64
|
null
|
|
64
65
|
);
|
|
65
|
-
var StringParamsProvider =
|
|
66
|
+
var StringParamsProvider = (props) => {
|
|
67
|
+
const parent = useContext4(STRING_PARAMS_CONTEXT) || {};
|
|
68
|
+
const merged = { ...parent, ...props.value };
|
|
69
|
+
return /* @__PURE__ */ jsx2(STRING_PARAMS_CONTEXT.Provider, { value: merged, children: props.children });
|
|
70
|
+
};
|
|
66
71
|
function useStringParams() {
|
|
67
72
|
return useContext4(STRING_PARAMS_CONTEXT) || {};
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
// src/core/hooks/useTranslationsMiddleware.tsx
|
|
76
|
+
import { createContext as createContext2 } from "preact";
|
|
77
|
+
import { useContext as useContext5 } from "preact/hooks";
|
|
78
|
+
import { jsx as jsx3 } from "preact/jsx-runtime";
|
|
79
|
+
var TRANSLATION_MIDDLEWARE_CONTEXT = createContext2(null);
|
|
80
|
+
var TranslationMiddlewareProvider = (props) => {
|
|
81
|
+
const parent = useContext5(TRANSLATION_MIDDLEWARE_CONTEXT) || {
|
|
82
|
+
beforeTranslateFns: [],
|
|
83
|
+
afterTranslateFns: [],
|
|
84
|
+
beforeReplaceParamsFns: [],
|
|
85
|
+
afterReplaceParamsFns: []
|
|
86
|
+
};
|
|
87
|
+
const merged = {
|
|
88
|
+
beforeTranslateFns: [...parent.beforeTranslateFns],
|
|
89
|
+
afterTranslateFns: [...parent.afterTranslateFns],
|
|
90
|
+
beforeReplaceParamsFns: [...parent.beforeReplaceParamsFns],
|
|
91
|
+
afterReplaceParamsFns: [...parent.afterReplaceParamsFns]
|
|
92
|
+
};
|
|
93
|
+
if (props.value?.beforeTranslate) {
|
|
94
|
+
merged.beforeTranslateFns.push(props.value.beforeTranslate);
|
|
95
|
+
}
|
|
96
|
+
if (props.value?.afterTranslate) {
|
|
97
|
+
merged.afterTranslateFns.push(props.value.afterTranslate);
|
|
98
|
+
}
|
|
99
|
+
if (props.value?.beforeReplaceParams) {
|
|
100
|
+
merged.beforeReplaceParamsFns.push(props.value.beforeReplaceParams);
|
|
101
|
+
}
|
|
102
|
+
if (props.value?.afterReplaceParams) {
|
|
103
|
+
merged.afterReplaceParamsFns.push(props.value.afterReplaceParams);
|
|
104
|
+
}
|
|
105
|
+
return /* @__PURE__ */ jsx3(TRANSLATION_MIDDLEWARE_CONTEXT.Provider, { value: merged, children: props.children });
|
|
106
|
+
};
|
|
107
|
+
function useTranslationMiddleware() {
|
|
108
|
+
return useContext5(TRANSLATION_MIDDLEWARE_CONTEXT) || {
|
|
109
|
+
beforeTranslateFns: [],
|
|
110
|
+
afterTranslateFns: [],
|
|
111
|
+
beforeReplaceParamsFns: [],
|
|
112
|
+
afterReplaceParamsFns: []
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
70
116
|
// src/core/hooks/useTranslations.ts
|
|
71
117
|
function useTranslations() {
|
|
72
118
|
let i18nContext = null;
|
|
@@ -77,14 +123,28 @@ function useTranslations() {
|
|
|
77
123
|
}
|
|
78
124
|
const translations = i18nContext?.translations || {};
|
|
79
125
|
const stringParams = useStringParams();
|
|
126
|
+
const middleware = useTranslationMiddleware();
|
|
80
127
|
const t = (str, params) => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
128
|
+
let input = normalizeString(str);
|
|
129
|
+
middleware.beforeTranslateFns.forEach((fn) => {
|
|
130
|
+
input = fn(input);
|
|
131
|
+
});
|
|
132
|
+
let translation = translations[input] ?? input ?? "";
|
|
133
|
+
middleware.afterTranslateFns.forEach((fn) => {
|
|
134
|
+
translation = fn(translation);
|
|
135
|
+
});
|
|
136
|
+
middleware.beforeReplaceParamsFns.forEach((fn) => {
|
|
137
|
+
translation = fn(translation);
|
|
138
|
+
});
|
|
139
|
+
if (testHasStringParams(translation)) {
|
|
140
|
+
translation = replaceStringParams(translation, {
|
|
141
|
+
...stringParams,
|
|
142
|
+
...params
|
|
143
|
+
});
|
|
87
144
|
}
|
|
145
|
+
middleware.afterReplaceParamsFns.forEach((fn) => {
|
|
146
|
+
translation = fn(translation);
|
|
147
|
+
});
|
|
88
148
|
return translation;
|
|
89
149
|
};
|
|
90
150
|
return t;
|
|
@@ -96,6 +156,17 @@ function normalizeString(str) {
|
|
|
96
156
|
function removeTrailingWhitespace(str) {
|
|
97
157
|
return String(str).trimEnd().replace(/ $/, "");
|
|
98
158
|
}
|
|
159
|
+
function testHasStringParams(str) {
|
|
160
|
+
return str.includes("{") && str.includes("}");
|
|
161
|
+
}
|
|
162
|
+
function replaceStringParams(str, params) {
|
|
163
|
+
return str.replace(/{([^}]+)}/g, (match, key) => {
|
|
164
|
+
if (key in params) {
|
|
165
|
+
return String(params[key]);
|
|
166
|
+
}
|
|
167
|
+
return match;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
99
170
|
export {
|
|
100
171
|
Body,
|
|
101
172
|
HTML_CONTEXT,
|
|
@@ -103,6 +174,7 @@ export {
|
|
|
103
174
|
Html,
|
|
104
175
|
Script,
|
|
105
176
|
StringParamsProvider,
|
|
177
|
+
TranslationMiddlewareProvider,
|
|
106
178
|
configureServerPlugins,
|
|
107
179
|
defineConfig,
|
|
108
180
|
getTranslations,
|
|
@@ -110,6 +182,7 @@ export {
|
|
|
110
182
|
useI18nContext,
|
|
111
183
|
useRequestContext,
|
|
112
184
|
useStringParams,
|
|
185
|
+
useTranslationMiddleware,
|
|
113
186
|
useTranslations
|
|
114
187
|
};
|
|
115
188
|
//# sourceMappingURL=core.js.map
|