@blinkk/root 3.0.1-alpha.0 → 3.0.1-beta.2

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.
@@ -1,9 +1,9 @@
1
1
  import { Express, Request as Request$1, Response as Response$1, NextFunction as NextFunction$1 } from 'express';
2
2
  import { ComponentType } from 'preact';
3
3
  import { PluginOption, UserConfig, ViteDevServer } from 'vite';
4
+ import { J as JsxRenderOptions } from './jsx-C8BaDh-4.js';
4
5
  import { Options } from 'html-minifier-terser';
5
6
  import { HTMLBeautifyOptions } from 'js-beautify';
6
- import { J as JsxRenderOptions } from './jsx-C8BaDh-4.js';
7
7
 
8
8
  declare class Hooks {
9
9
  private callbacks;
@@ -39,6 +39,59 @@ type HtmlMinifyOptions = Options;
39
39
 
40
40
  type HtmlPrettyOptions = HTMLBeautifyOptions;
41
41
 
42
+ interface Pod {
43
+ /** Unique pod name, e.g. '@blinkk/root-docs-pod'. */
44
+ name: string;
45
+ /**
46
+ * URL prefix for pod routes. Routes within the pod are served under this
47
+ * mount path. Defaults to '/'.
48
+ */
49
+ mount?: string;
50
+ /**
51
+ * Priority for route conflict resolution. Higher values win when multiple
52
+ * pods register the same URL path. User-site routes always take precedence
53
+ * regardless of priority. Defaults to 0.
54
+ */
55
+ priority?: number;
56
+ /** Absolute path to the pod's routes/ directory. */
57
+ routesDir?: string;
58
+ /** Absolute path(s) to the pod's elements/ directory(s). */
59
+ elementsDirs?: string[];
60
+ /** Absolute path to the pod's bundles/ directory. */
61
+ bundlesDir?: string;
62
+ /** Absolute path to the pod's collections/ directory (root-cms only). */
63
+ collectionsDir?: string;
64
+ /** Absolute path to the pod's translations/ directory. */
65
+ translationsDir?: string;
66
+ /** Extra Vite plugins contributed by the pod. */
67
+ vitePlugins?: PluginOption[];
68
+ }
69
+ type PodFactory = (ctx: {
70
+ rootConfig: RootConfig;
71
+ }) => Pod | Promise<Pod>;
72
+ interface PodConfig {
73
+ /** Whether the pod is enabled. Defaults to true. */
74
+ enabled?: boolean;
75
+ /** Override the pod's mount path. */
76
+ mount?: string;
77
+ /** Override the pod's priority. */
78
+ priority?: number;
79
+ /** Filter pod routes. */
80
+ routes?: {
81
+ exclude?: (string | RegExp)[];
82
+ };
83
+ /** Configure pod collections. */
84
+ collections?: {
85
+ exclude?: string[];
86
+ /** Rename collection ids, e.g. {Posts: 'DocsPosts'}. */
87
+ rename?: Record<string, string>;
88
+ };
89
+ }
90
+ /**
91
+ * Helper to define a pod with type-checking.
92
+ */
93
+ declare function definePod(pod: Pod): Pod;
94
+
42
95
  type MaybePromise<T> = T | Promise<T>;
43
96
  type PreBuildHook = (rootConfig: RootConfig) => MaybePromise<void>;
44
97
  interface PostBuildOptions {
@@ -100,6 +153,12 @@ interface Plugin {
100
153
  hooks?: PluginHooks;
101
154
  /** Custom 404 handler. */
102
155
  handle404?: (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
156
+ /**
157
+ * Registers a pod (a mini root.js site) that gets merged into the parent
158
+ * site at dev/build time. A plugin may return a single pod, an array of
159
+ * pods, or a factory that receives the rootConfig.
160
+ */
161
+ pod?: Pod | Pod[] | PodFactory;
103
162
  }
104
163
  /**
105
164
  * Runs the pre-hook configureServer method of every plugin, calls a callback
@@ -215,6 +274,11 @@ interface RootUserConfig {
215
274
  * Plugins.
216
275
  */
217
276
  plugins?: Plugin[];
277
+ /**
278
+ * Per-pod user-level overrides. The key is the pod name as declared in
279
+ * Pod.name.
280
+ */
281
+ pods?: Record<string, PodConfig>;
218
282
  /**
219
283
  * Experimental config options. Note: these are subject to change at any time.
220
284
  */
@@ -718,6 +782,11 @@ interface Route {
718
782
  * Per the example above, this value contains placeholder params.
719
783
  */
720
784
  localeRoutePath: string;
785
+ /**
786
+ * The name of the pod that contributed this route, or undefined if the
787
+ * route is from the user's project.
788
+ */
789
+ podName?: string;
721
790
  }
722
791
  interface HandlerRenderOptions {
723
792
  /** HTTP status code to return. Defaults to 200. */
@@ -755,4 +824,4 @@ interface SitemapItem {
755
824
  }>;
756
825
  }
757
826
 
758
- export { type StaticContentResult as A, type GetStaticContent as B, type ContentSecurityPolicyConfig as C, type RouteModule as D, type HandlerRenderOptions as E, type HandlerRenderFn as F, type GetStaticProps as G, type HandlerContext as H, type Sitemap as I, type SitemapItem as J, Renderer as K, type LocaleGroup as L, type MultipartFile as M, type NextFunction as N, type PostBuildOptions as P, type RootConfig as R, SESSION_COOKIE as S, type XFrameOptionsConfig as X, type Request as a, type Response as b, type SessionMiddlewareOptions as c, type SaveSessionOptions as d, Session as e, type Server as f, type Route as g, type RootUserConfig as h, type RootI18nConfig as i, type RootBuildConfig as j, type RootRedirectConfig as k, type RootHeaderConfig as l, type RootSecurityConfig as m, type RootServerConfig as n, defineConfig as o, type ConfigureServerHook as p, type ConfigureServerOptions as q, type PluginHooks as r, sessionMiddleware as s, type Plugin as t, configureServerPlugins as u, getVitePlugins as v, type RouteParams as w, type GetStaticPaths as x, type RequestMiddleware as y, type Handler as z };
827
+ export { type RouteParams as A, type GetStaticPaths as B, type ContentSecurityPolicyConfig as C, type RequestMiddleware as D, type Handler as E, type StaticContentResult as F, type GetStaticProps as G, type HandlerContext as H, type GetStaticContent as I, type RouteModule as J, type HandlerRenderOptions as K, type LocaleGroup as L, type MultipartFile as M, type NextFunction as N, type HandlerRenderFn as O, type PodConfig as P, type Sitemap as Q, type RootConfig as R, SESSION_COOKIE as S, type SitemapItem as T, Renderer as U, type XFrameOptionsConfig as X, type Request as a, type Response as b, type SessionMiddlewareOptions as c, type SaveSessionOptions as d, Session as e, type Server as f, type Route as g, type RootUserConfig as h, type RootI18nConfig as i, type RootBuildConfig as j, type RootRedirectConfig as k, type RootHeaderConfig as l, type RootSecurityConfig as m, type RootServerConfig as n, defineConfig as o, type Pod as p, type PodFactory as q, definePod as r, sessionMiddleware as s, type PostBuildOptions as t, type ConfigureServerHook as u, type ConfigureServerOptions as v, type PluginHooks as w, type Plugin as x, configureServerPlugins as y, getVitePlugins as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkk/root",
3
- "version": "3.0.1-alpha.0",
3
+ "version": "3.0.1-beta.2",
4
4
  "author": "s@blinkk.com",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -1 +0,0 @@
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\ntype PreBuildHook = (rootConfig: RootConfig) => MaybePromise<void>;\n\nexport interface PostBuildOptions {\n /** Whether the build was SSR-only (no SSG pre-rendering). */\n ssrOnly?: boolean;\n}\n\ntype PostBuildHook = (\n rootConfig: RootConfig,\n options?: PostBuildOptions\n) => MaybePromise<void>;\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 * Hook that runs before the build starts.\n */\n preBuild?: PreBuildHook;\n\n /**\n * Hook that runs after the build completes.\n */\n postBuild?: PostBuildHook;\n\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 | MaybePromise<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":";AA4FA,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":[]}
@@ -1,417 +0,0 @@
1
- import {
2
- getVitePlugins
3
- } from "./chunk-6FDF3DXT.js";
4
-
5
- // src/node/monorepo.ts
6
- import path2 from "path";
7
- import { getWorkspaces, getWorkspaceRoot } from "workspace-tools";
8
-
9
- // src/utils/fsutils.ts
10
- import fs from "fs";
11
- import path from "path";
12
- import fsExtra from "fs-extra";
13
- 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 (e) {
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 "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/vite.ts
277
- import { createServer } from "vite";
278
-
279
- // src/node/vite-plugin-preact-alias.ts
280
- function preactToRootJsxPlugin() {
281
- return {
282
- name: "root:preact-to-jsx",
283
- config() {
284
- return {
285
- resolve: {
286
- alias: [
287
- { find: /^preact\/hooks$/, replacement: "@blinkk/root/jsx" },
288
- {
289
- find: /^preact\/jsx-runtime$/,
290
- replacement: "@blinkk/root/jsx/jsx-runtime"
291
- },
292
- {
293
- find: /^preact\/jsx-dev-runtime$/,
294
- replacement: "@blinkk/root/jsx/jsx-dev-runtime"
295
- },
296
- { find: /^preact$/, replacement: "@blinkk/root/jsx" }
297
- ]
298
- }
299
- };
300
- }
301
- };
302
- }
303
-
304
- // src/node/vite.ts
305
- async function createViteServer(rootConfig, options) {
306
- const rootDir = rootConfig.rootDir;
307
- const viteConfig = rootConfig.vite || {};
308
- let hmrOptions = viteConfig.server?.hmr;
309
- if (options?.hmr === false) {
310
- hmrOptions = false;
311
- } else if (typeof hmrOptions === "undefined" && options?.port) {
312
- hmrOptions = { port: options.port + 10 };
313
- }
314
- const viteServer = await createServer({
315
- ...viteConfig,
316
- mode: "development",
317
- root: rootDir,
318
- // publicDir is disabled from the vite dev server since it's handled by the
319
- // root dev server directly, which allows user middlewares to override
320
- // files in the public dir.
321
- publicDir: false,
322
- server: {
323
- ...viteConfig.server || {},
324
- middlewareMode: true,
325
- hmr: hmrOptions
326
- },
327
- appType: "custom",
328
- optimizeDeps: {
329
- ...viteConfig.optimizeDeps || {},
330
- include: [
331
- ...options?.optimizeDeps || [],
332
- ...viteConfig.optimizeDeps?.include || []
333
- ],
334
- extensions: [...viteConfig.optimizeDeps?.extensions || [], ".tsx"]
335
- },
336
- ssr: {
337
- ...viteConfig.ssr || {},
338
- noExternal: ["@blinkk/root", "@blinkk/root-cms/richtext"]
339
- },
340
- plugins: [
341
- hmrSSRReload(),
342
- ...rootConfig.jsxRenderer?.mode ? [preactToRootJsxPlugin()] : [],
343
- ...viteConfig.plugins || [],
344
- ...getVitePlugins(rootConfig.plugins || [])
345
- ]
346
- });
347
- return viteServer;
348
- }
349
- async function viteSsrLoadModule(rootConfig, file) {
350
- const viteServer = await createViteServer(rootConfig, { hmr: false });
351
- const module = await viteServer.ssrLoadModule(file);
352
- await viteServer.close();
353
- return module;
354
- }
355
- function hmrSSRReload() {
356
- return {
357
- name: "hmr-ssr-reload",
358
- enforce: "post",
359
- hotUpdate: {
360
- order: "post",
361
- handler({ modules, server, timestamp }) {
362
- if (this.environment.name !== "ssr") {
363
- return;
364
- }
365
- let hasSsrOnlyModules = false;
366
- const invalidatedModules = /* @__PURE__ */ new Set();
367
- for (const mod of modules) {
368
- if (mod.id === null) {
369
- continue;
370
- }
371
- const clientModule = server.environments.client.moduleGraph.getModuleById(mod.id);
372
- if (clientModule) {
373
- continue;
374
- }
375
- hasSsrOnlyModules = true;
376
- this.environment.moduleGraph.invalidateModule(
377
- mod,
378
- invalidatedModules,
379
- timestamp,
380
- true
381
- );
382
- }
383
- if (hasSsrOnlyModules) {
384
- server.ws.send({ type: "full-reload" });
385
- return [];
386
- }
387
- return;
388
- }
389
- }
390
- };
391
- }
392
-
393
- export {
394
- isJsFile,
395
- writeFile,
396
- makeDir,
397
- copyDir,
398
- copyGlob,
399
- rmDir,
400
- loadJson,
401
- writeJson,
402
- isDirectory,
403
- fileExists,
404
- dirExists,
405
- directoryContains,
406
- loadPackageJson,
407
- getMonorepoPackageDeps,
408
- flattenPackageDepsFromMonorepo,
409
- loadRootConfig,
410
- loadRootConfigWithDeps,
411
- bundleRootConfig,
412
- loadBundledConfig,
413
- preactToRootJsxPlugin,
414
- createViteServer,
415
- viteSsrLoadModule
416
- };
417
- //# sourceMappingURL=chunk-EBE4O463.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/node/monorepo.ts","../src/utils/fsutils.ts","../src/node/load-config.ts","../src/node/vite.ts","../src/node/vite-plugin-preact-alias.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 {rootConfig} = await loadRootConfigWithDeps(rootDir, options);\n return rootConfig;\n}\n\nexport async function loadRootConfigWithDeps(\n rootDir: string,\n options: ConfigOptions\n): Promise<{rootConfig: RootConfig; dependencies: string[]}> {\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 const rootConfig = Object.assign({}, config, {rootDir});\n validateRootconfig(rootConfig);\n return {rootConfig, dependencies: configBundle.dependencies};\n}\n\nfunction validateRootconfig(rootConfig: RootConfig) {\n // Update vite legacy config options.\n const scss: any = rootConfig.vite?.css?.preprocessorOptions?.scss;\n if (scss?.includePaths) {\n console.warn(\n '[deprecation warning] root.config.ts: vite.css.preprocessorOptions.scss.includePaths is deprecated. rename \"includePaths\" -> \"loadPaths\"'\n );\n scss.loadPaths = scss.includePaths;\n }\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 type {Plugin, EnvironmentModuleNode} from 'vite';\nimport {RootConfig} from '../core/config.js';\nimport {getVitePlugins} from '../core/plugin.js';\nimport {preactToRootJsxPlugin} from './vite-plugin-preact-alias.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'],\n },\n plugins: [\n hmrSSRReload(),\n ...(rootConfig.jsxRenderer?.mode ? [preactToRootJsxPlugin()] : []),\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 type {Plugin} from 'vite';\n\n/**\n * Vite plugin that aliases `preact` imports to `@blinkk/root/jsx`.\n *\n * When `jsxRenderer.mode` is configured, the project uses Root's built-in JSX\n * runtime instead of Preact. This plugin redirects all `preact` imports\n * (including `preact/hooks`, `preact/jsx-runtime`, etc.) so that Root's\n * built-in hooks and components use Root's context API rather than Preact's.\n */\nexport function preactToRootJsxPlugin(): Plugin {\n return {\n name: 'root:preact-to-jsx',\n config() {\n return {\n resolve: {\n alias: [\n {find: /^preact\\/hooks$/, replacement: '@blinkk/root/jsx'},\n {\n find: /^preact\\/jsx-runtime$/,\n replacement: '@blinkk/root/jsx/jsx-runtime',\n },\n {\n find: /^preact\\/jsx-dev-runtime$/,\n replacement: '@blinkk/root/jsx/jsx-dev-runtime',\n },\n {find: /^preact$/, replacement: '@blinkk/root/jsx'},\n ],\n },\n };\n },\n };\n}\n"],"mappings":"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","names":["path","path","path","path","build"]}