@react-router/dev 0.0.0-experimental-f20b6b7b0 → 0.0.0-experimental-39630069d

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/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-f20b6b7b0
2
+ * @react-router/dev v0.0.0-experimental-39630069d
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -48,13 +48,28 @@ module.exports = __toCommonJS(vite_exports);
48
48
  var import_node_crypto = require("crypto");
49
49
  var path4 = __toESM(require("path"));
50
50
  var url2 = __toESM(require("url"));
51
- var fse2 = __toESM(require("fs-extra"));
51
+ var fse = __toESM(require("fs-extra"));
52
52
  var babel = __toESM(require("@babel/core"));
53
53
  var import_react_router2 = require("react-router");
54
54
  var import_es_module_lexer = require("es-module-lexer");
55
55
  var import_jsesc = __toESM(require("jsesc"));
56
+ var import_picocolors3 = __toESM(require("picocolors"));
57
+
58
+ // typegen/index.ts
59
+ var import_node_fs2 = __toESM(require("fs"));
60
+ var Path4 = __toESM(require("pathe"));
56
61
  var import_picocolors2 = __toESM(require("picocolors"));
57
62
 
63
+ // config/config.ts
64
+ var import_node_fs = __toESM(require("fs"));
65
+ var import_node_child_process = require("child_process");
66
+ var import_package_json = __toESM(require("@npmcli/package-json"));
67
+
68
+ // vite/vite-node.ts
69
+ var import_server = require("vite-node/server");
70
+ var import_client = require("vite-node/client");
71
+ var import_source_map = require("vite-node/source-map");
72
+
58
73
  // invariant.ts
59
74
  function invariant(value, message) {
60
75
  if (value === false || value === null || typeof value === "undefined") {
@@ -65,82 +80,6 @@ function invariant(value, message) {
65
80
  }
66
81
  }
67
82
 
68
- // vite/babel.ts
69
- var import_parser = require("@babel/parser");
70
- var t = __toESM(require("@babel/types"));
71
- var traverse = require("@babel/traverse").default;
72
- var generate = require("@babel/generator").default;
73
-
74
- // vite/node-adapter.ts
75
- var import_node_events = require("events");
76
- var import_node_stream = require("stream");
77
- var import_set_cookie_parser = require("set-cookie-parser");
78
- var import_node = require("@react-router/node");
79
- function fromNodeHeaders(nodeHeaders) {
80
- let headers = new Headers();
81
- for (let [key, values] of Object.entries(nodeHeaders)) {
82
- if (values) {
83
- if (Array.isArray(values)) {
84
- for (let value of values) {
85
- headers.append(key, value);
86
- }
87
- } else {
88
- headers.set(key, values);
89
- }
90
- }
91
- }
92
- return headers;
93
- }
94
- function fromNodeRequest(nodeReq, nodeRes) {
95
- let origin = nodeReq.headers.origin && "null" !== nodeReq.headers.origin ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
96
- invariant(
97
- nodeReq.originalUrl,
98
- "Expected `nodeReq.originalUrl` to be defined"
99
- );
100
- let url3 = new URL(nodeReq.originalUrl, origin);
101
- let controller = new AbortController();
102
- let init = {
103
- method: nodeReq.method,
104
- headers: fromNodeHeaders(nodeReq.headers),
105
- signal: controller.signal
106
- };
107
- nodeRes.on("finish", () => controller = null);
108
- nodeRes.on("close", () => controller?.abort());
109
- if (nodeReq.method !== "GET" && nodeReq.method !== "HEAD") {
110
- init.body = (0, import_node.createReadableStreamFromReadable)(nodeReq);
111
- init.duplex = "half";
112
- }
113
- return new Request(url3.href, init);
114
- }
115
- async function toNodeRequest(res, nodeRes) {
116
- nodeRes.statusCode = res.status;
117
- nodeRes.statusMessage = res.statusText;
118
- let cookiesStrings = [];
119
- for (let [name, value] of res.headers) {
120
- if (name === "set-cookie") {
121
- cookiesStrings.push(...(0, import_set_cookie_parser.splitCookiesString)(value));
122
- } else nodeRes.setHeader(name, value);
123
- }
124
- if (cookiesStrings.length) {
125
- nodeRes.setHeader("set-cookie", cookiesStrings);
126
- }
127
- if (res.body) {
128
- let responseBody = res.body;
129
- let readable = import_node_stream.Readable.from(responseBody);
130
- readable.pipe(nodeRes);
131
- await (0, import_node_events.once)(readable, "end");
132
- } else {
133
- nodeRes.end();
134
- }
135
- }
136
-
137
- // vite/styles.ts
138
- var path2 = __toESM(require("path"));
139
- var import_react_router = require("react-router");
140
-
141
- // vite/resolve-file-url.ts
142
- var path = __toESM(require("path"));
143
-
144
83
  // vite/import-vite-esm-sync.ts
145
84
  var vite;
146
85
  async function preloadViteEsm() {
@@ -151,464 +90,241 @@ function importViteEsmSync() {
151
90
  return vite;
152
91
  }
153
92
 
154
- // vite/resolve-file-url.ts
155
- var resolveFileUrl = ({ rootDirectory }, filePath) => {
156
- let vite2 = importViteEsmSync();
157
- let relativePath = path.relative(rootDirectory, filePath);
158
- let isWithinRoot = !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
159
- if (!isWithinRoot) {
160
- return path.posix.join("/@fs", vite2.normalizePath(filePath));
161
- }
162
- return "/" + vite2.normalizePath(relativePath);
163
- };
93
+ // vite/vite-node.ts
94
+ async function createContext(viteConfig = {}) {
95
+ await preloadViteEsm();
96
+ const vite2 = importViteEsmSync();
97
+ const devServer = await vite2.createServer(
98
+ vite2.mergeConfig(
99
+ {
100
+ server: {
101
+ preTransformRequests: false,
102
+ hmr: false
103
+ },
104
+ optimizeDeps: {
105
+ noDiscovery: true
106
+ },
107
+ configFile: false,
108
+ envFile: false,
109
+ plugins: []
110
+ },
111
+ viteConfig
112
+ )
113
+ );
114
+ await devServer.pluginContainer.buildStart({});
115
+ const server = new import_server.ViteNodeServer(devServer);
116
+ (0, import_source_map.installSourcemapsSupport)({
117
+ getSourceMap: (source) => server.getSourceMap(source)
118
+ });
119
+ const runner = new import_client.ViteNodeRunner({
120
+ root: devServer.config.root,
121
+ base: devServer.config.base,
122
+ fetchModule(id2) {
123
+ return server.fetchModule(id2);
124
+ },
125
+ resolveId(id2, importer) {
126
+ return server.resolveId(id2, importer);
127
+ }
128
+ });
129
+ return { devServer, server, runner };
130
+ }
164
131
 
165
- // vite/styles.ts
166
- var cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
167
- var cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
168
- var isCssFile = (file) => cssFileRegExp.test(file);
169
- var isCssModulesFile = (file) => cssModulesRegExp.test(file);
170
- var cssUrlParamsWithoutSideEffects = ["url", "inline", "raw", "inline-css"];
171
- var isCssUrlWithoutSideEffects = (url3) => {
172
- let queryString = url3.split("?")[1];
173
- if (!queryString) {
174
- return false;
132
+ // config/config.ts
133
+ var import_pathe = __toESM(require("pathe"));
134
+ var import_chokidar = __toESM(require("chokidar"));
135
+ var import_picocolors = __toESM(require("picocolors"));
136
+ var import_pick2 = __toESM(require("lodash/pick"));
137
+ var import_omit = __toESM(require("lodash/omit"));
138
+ var import_cloneDeep = __toESM(require("lodash/cloneDeep"));
139
+ var import_isEqual = __toESM(require("lodash/isEqual"));
140
+
141
+ // config/routes.ts
142
+ var Path = __toESM(require("pathe"));
143
+ var v = __toESM(require("valibot"));
144
+ var import_pick = __toESM(require("lodash/pick"));
145
+ function setAppDirectory(directory) {
146
+ globalThis.__reactRouterAppDirectory = directory;
147
+ }
148
+ var routeConfigEntrySchema = v.pipe(
149
+ v.custom((value) => {
150
+ return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
151
+ }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
152
+ v.object({
153
+ id: v.optional(v.string()),
154
+ path: v.optional(v.string()),
155
+ index: v.optional(v.boolean()),
156
+ caseSensitive: v.optional(v.boolean()),
157
+ file: v.string(),
158
+ children: v.optional(v.array(v.lazy(() => routeConfigEntrySchema)))
159
+ })
160
+ );
161
+ var resolvedRouteConfigSchema = v.array(routeConfigEntrySchema);
162
+ function validateRouteConfig({
163
+ routeConfigFile,
164
+ routeConfig
165
+ }) {
166
+ if (!routeConfig) {
167
+ return {
168
+ valid: false,
169
+ message: `Route config must be the default export in "${routeConfigFile}".`
170
+ };
175
171
  }
176
- let params = new URLSearchParams(queryString);
177
- for (let paramWithoutSideEffects of cssUrlParamsWithoutSideEffects) {
178
- if (
179
- // Parameter is blank and not explicitly set, i.e. "?url", not "?url="
180
- params.get(paramWithoutSideEffects) === "" && !url3.includes(`?${paramWithoutSideEffects}=`) && !url3.includes(`&${paramWithoutSideEffects}=`)
181
- ) {
182
- return true;
183
- }
172
+ if (!Array.isArray(routeConfig)) {
173
+ return {
174
+ valid: false,
175
+ message: `Route config in "${routeConfigFile}" must be an array.`
176
+ };
184
177
  }
185
- return false;
186
- };
187
- var getStylesForFiles = async ({
188
- viteDevServer,
189
- rootDirectory,
190
- cssModulesManifest,
191
- files
192
- }) => {
193
- let styles = {};
194
- let deps = /* @__PURE__ */ new Set();
195
- try {
196
- for (let file of files) {
197
- let normalizedPath = path2.resolve(rootDirectory, file).replace(/\\/g, "/");
198
- let node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
199
- if (!node) {
200
- try {
201
- await viteDevServer.transformRequest(
202
- resolveFileUrl({ rootDirectory }, normalizedPath)
203
- );
204
- } catch (err) {
205
- console.error(err);
206
- }
207
- node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
208
- }
209
- if (!node) {
210
- console.log(`Could not resolve module for file: ${file}`);
211
- continue;
212
- }
213
- await findDeps(viteDevServer, node, deps);
214
- }
215
- } catch (err) {
216
- console.error(err);
178
+ let { issues } = v.safeParse(resolvedRouteConfigSchema, routeConfig);
179
+ if (issues?.length) {
180
+ let { root, nested } = v.flatten(issues);
181
+ return {
182
+ valid: false,
183
+ message: [
184
+ `Route config in "${routeConfigFile}" is invalid.`,
185
+ root ? `${root}` : [],
186
+ nested ? Object.entries(nested).map(
187
+ ([path5, message]) => `Path: routes.${path5}
188
+ ${message}`
189
+ ) : []
190
+ ].flat().join("\n\n")
191
+ };
217
192
  }
218
- for (let dep of deps) {
219
- if (dep.file && isCssFile(dep.file) && !isCssUrlWithoutSideEffects(dep.url)) {
220
- try {
221
- let css = isCssModulesFile(dep.file) ? cssModulesManifest[dep.file] : (await viteDevServer.ssrLoadModule(dep.url)).default;
222
- if (css === void 0) {
223
- throw new Error();
224
- }
225
- styles[dep.url] = css;
226
- } catch {
227
- console.warn(`Could not load ${dep.file}`);
193
+ return { valid: true };
194
+ }
195
+ function configRoutesToRouteManifest(appDirectory, routes, rootId = "root") {
196
+ let routeManifest = {};
197
+ function walk(route, parentId) {
198
+ let id2 = route.id || createRouteId(route.file);
199
+ let manifestItem = {
200
+ id: id2,
201
+ parentId,
202
+ file: Path.isAbsolute(route.file) ? Path.relative(appDirectory, route.file) : route.file,
203
+ path: route.path,
204
+ index: route.index,
205
+ caseSensitive: route.caseSensitive
206
+ };
207
+ if (routeManifest.hasOwnProperty(id2)) {
208
+ throw new Error(
209
+ `Unable to define routes with duplicate route id: "${id2}"`
210
+ );
211
+ }
212
+ routeManifest[id2] = manifestItem;
213
+ if (route.children) {
214
+ for (let child of route.children) {
215
+ walk(child, id2);
228
216
  }
229
217
  }
230
218
  }
231
- return Object.entries(styles).map(([fileName, css], i) => [
232
- `
233
- /* ${fileName.replace(/\/\*/g, "/\\*").replace(/\*\//g, "*\\/")} */`,
234
- css
235
- ]).flat().join("\n") || void 0;
236
- };
237
- var findDeps = async (vite2, node, deps) => {
238
- let branches = [];
239
- async function addFromNode(node2) {
240
- if (!deps.has(node2)) {
241
- deps.add(node2);
242
- await findDeps(vite2, node2, deps);
243
- }
244
- }
245
- async function addFromUrl(url3) {
246
- let node2 = await vite2.moduleGraph.getModuleByUrl(url3);
247
- if (node2) {
248
- await addFromNode(node2);
249
- }
250
- }
251
- if (node.ssrTransformResult) {
252
- if (node.ssrTransformResult.deps) {
253
- node.ssrTransformResult.deps.forEach(
254
- (url3) => branches.push(addFromUrl(url3))
255
- );
256
- }
257
- } else {
258
- node.importedModules.forEach((node2) => branches.push(addFromNode(node2)));
219
+ for (let route of routes) {
220
+ walk(route, rootId);
259
221
  }
260
- await Promise.all(branches);
261
- };
262
- var groupRoutesByParentId = (manifest) => {
263
- let routes = {};
264
- Object.values(manifest).forEach((route) => {
265
- if (route) {
266
- let parentId = route.parentId || "";
267
- if (!routes[parentId]) {
268
- routes[parentId] = [];
269
- }
270
- routes[parentId].push(route);
271
- }
272
- });
273
- return routes;
274
- };
275
- var createRoutes = (manifest, parentId = "", routesByParentId = groupRoutesByParentId(manifest)) => {
276
- return (routesByParentId[parentId] || []).map((route) => ({
277
- ...route,
278
- children: createRoutes(manifest, route.id, routesByParentId)
279
- }));
280
- };
281
- var getStylesForUrl = async ({
282
- viteDevServer,
283
- rootDirectory,
284
- reactRouterConfig,
285
- entryClientFilePath,
286
- cssModulesManifest,
287
- build,
288
- url: url3
289
- }) => {
290
- if (url3 === void 0 || url3.includes("?_data=")) {
222
+ return routeManifest;
223
+ }
224
+ function createRouteId(file) {
225
+ return Path.normalize(stripFileExtension(file));
226
+ }
227
+ function stripFileExtension(file) {
228
+ return file.replace(/\.[a-z0-9]+$/i, "");
229
+ }
230
+
231
+ // cli/detectPackageManager.ts
232
+ var detectPackageManager = () => {
233
+ let { npm_config_user_agent } = process.env;
234
+ if (!npm_config_user_agent) return void 0;
235
+ try {
236
+ let pkgManager = npm_config_user_agent.split("/")[0];
237
+ if (pkgManager === "npm") return "npm";
238
+ if (pkgManager === "pnpm") return "pnpm";
239
+ if (pkgManager === "yarn") return "yarn";
240
+ if (pkgManager === "bun") return "bun";
241
+ return void 0;
242
+ } catch {
291
243
  return void 0;
292
244
  }
293
- let routes = createRoutes(build.routes);
294
- let appPath = path2.relative(process.cwd(), reactRouterConfig.appDirectory);
295
- let documentRouteFiles = (0, import_react_router.matchRoutes)(routes, url3, build.basename)?.map(
296
- (match) => path2.resolve(appPath, reactRouterConfig.routes[match.route.id].file)
297
- ) ?? [];
298
- let styles = await getStylesForFiles({
299
- viteDevServer,
300
- rootDirectory,
301
- cssModulesManifest,
302
- files: [
303
- // Always include the client entry file when crawling the module graph for CSS
304
- path2.relative(rootDirectory, entryClientFilePath),
305
- // Then include any styles from the matched routes
306
- ...documentRouteFiles
307
- ]
308
- });
309
- return styles;
310
245
  };
311
246
 
312
- // vite/vmod.ts
313
- var id = (name) => `virtual:react-router/${name}`;
314
- var resolve2 = (id2) => `\0${id2}`;
315
- var url = (id2) => `/@id/__x00__${id2}`;
316
-
317
- // vite/combine-urls.ts
318
- function combineURLs(baseURL, relativeURL) {
319
- return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
320
- }
321
-
322
- // vite/remove-exports.ts
323
- var import_babel_dead_code_elimination = require("babel-dead-code-elimination");
324
- var removeExports = (ast, exportsToRemove) => {
325
- let previouslyReferencedIdentifiers = (0, import_babel_dead_code_elimination.findReferencedIdentifiers)(ast);
326
- let exportsFiltered = false;
327
- let markedForRemoval = /* @__PURE__ */ new Set();
328
- traverse(ast, {
329
- ExportDeclaration(path5) {
330
- if (path5.node.type === "ExportNamedDeclaration") {
331
- if (path5.node.specifiers.length) {
332
- path5.node.specifiers = path5.node.specifiers.filter((specifier) => {
333
- if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
334
- if (exportsToRemove.includes(specifier.exported.name)) {
335
- exportsFiltered = true;
336
- return false;
337
- }
338
- }
339
- return true;
340
- });
341
- if (path5.node.specifiers.length === 0) {
342
- markedForRemoval.add(path5);
343
- }
344
- }
345
- if (path5.node.declaration?.type === "VariableDeclaration") {
346
- let declaration = path5.node.declaration;
347
- declaration.declarations = declaration.declarations.filter(
348
- (declaration2) => {
349
- if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
350
- exportsFiltered = true;
351
- return false;
352
- }
353
- if (declaration2.id.type === "ArrayPattern" || declaration2.id.type === "ObjectPattern") {
354
- validateDestructuredExports(declaration2.id, exportsToRemove);
355
- }
356
- return true;
357
- }
358
- );
359
- if (declaration.declarations.length === 0) {
360
- markedForRemoval.add(path5);
361
- }
362
- }
363
- if (path5.node.declaration?.type === "FunctionDeclaration") {
364
- let id2 = path5.node.declaration.id;
365
- if (id2 && exportsToRemove.includes(id2.name)) {
366
- markedForRemoval.add(path5);
367
- }
247
+ // config/config.ts
248
+ var excludedConfigPresetKeys = ["presets"];
249
+ var mergeReactRouterConfig = (...configs) => {
250
+ let reducer = (configA, configB) => {
251
+ let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
252
+ return {
253
+ ...configA,
254
+ ...configB,
255
+ ...mergeRequired("buildEnd") ? {
256
+ buildEnd: async (...args) => {
257
+ await Promise.all([
258
+ configA.buildEnd?.(...args),
259
+ configB.buildEnd?.(...args)
260
+ ]);
368
261
  }
369
- if (path5.node.declaration?.type === "ClassDeclaration") {
370
- let id2 = path5.node.declaration.id;
371
- if (id2 && exportsToRemove.includes(id2.name)) {
372
- markedForRemoval.add(path5);
373
- }
262
+ } : {},
263
+ ...mergeRequired("future") ? {
264
+ future: {
265
+ ...configA.future,
266
+ ...configB.future
374
267
  }
375
- }
376
- if (path5.node.type === "ExportDefaultDeclaration" && exportsToRemove.includes("default")) {
377
- markedForRemoval.add(path5);
378
- }
268
+ } : {},
269
+ ...mergeRequired("presets") ? {
270
+ presets: [...configA.presets ?? [], ...configB.presets ?? []]
271
+ } : {}
272
+ };
273
+ };
274
+ return configs.reduce(reducer, {});
275
+ };
276
+ var deepFreeze = (o) => {
277
+ Object.freeze(o);
278
+ let oIsFunction = typeof o === "function";
279
+ let hasOwnProp = Object.prototype.hasOwnProperty;
280
+ Object.getOwnPropertyNames(o).forEach(function(prop) {
281
+ if (hasOwnProp.call(o, prop) && (oIsFunction ? prop !== "caller" && prop !== "callee" && prop !== "arguments" : true) && o[prop] !== null && (typeof o[prop] === "object" || typeof o[prop] === "function") && !Object.isFrozen(o[prop])) {
282
+ deepFreeze(o[prop]);
379
283
  }
380
284
  });
381
- if (markedForRemoval.size > 0 || exportsFiltered) {
382
- for (let path5 of markedForRemoval) {
383
- path5.remove();
384
- }
385
- (0, import_babel_dead_code_elimination.deadCodeElimination)(ast, previouslyReferencedIdentifiers);
386
- }
285
+ return o;
387
286
  };
388
- function validateDestructuredExports(id2, exportsToRemove) {
389
- if (id2.type === "ArrayPattern") {
390
- for (let element of id2.elements) {
391
- if (!element) {
392
- continue;
393
- }
394
- if (element.type === "Identifier" && exportsToRemove.includes(element.name)) {
395
- throw invalidDestructureError(element.name);
287
+ function ok(value) {
288
+ return { ok: true, value };
289
+ }
290
+ function err(error) {
291
+ return { ok: false, error };
292
+ }
293
+ async function resolveConfig({
294
+ root,
295
+ viteNodeContext,
296
+ reactRouterConfigFile
297
+ }) {
298
+ let reactRouterUserConfig = {};
299
+ if (reactRouterConfigFile) {
300
+ try {
301
+ if (!import_node_fs.default.existsSync(reactRouterConfigFile)) {
302
+ return err(`${reactRouterConfigFile} no longer exists`);
396
303
  }
397
- if (element.type === "RestElement" && element.argument.type === "Identifier" && exportsToRemove.includes(element.argument.name)) {
398
- throw invalidDestructureError(element.argument.name);
304
+ let configModule = await viteNodeContext.runner.executeFile(
305
+ reactRouterConfigFile
306
+ );
307
+ if (configModule.default === void 0) {
308
+ return err(`${reactRouterConfigFile} must provide a default export`);
399
309
  }
400
- if (element.type === "ArrayPattern" || element.type === "ObjectPattern") {
401
- validateDestructuredExports(element, exportsToRemove);
310
+ if (typeof configModule.default !== "object") {
311
+ return err(`${reactRouterConfigFile} must export a config`);
402
312
  }
313
+ reactRouterUserConfig = configModule.default;
314
+ } catch (error) {
315
+ return err(`Error loading ${reactRouterConfigFile}: ${error}`);
403
316
  }
404
317
  }
405
- if (id2.type === "ObjectPattern") {
406
- for (let property of id2.properties) {
407
- if (!property) {
408
- continue;
409
- }
410
- if (property.type === "ObjectProperty" && property.key.type === "Identifier") {
411
- if (property.value.type === "Identifier" && exportsToRemove.includes(property.value.name)) {
412
- throw invalidDestructureError(property.value.name);
413
- }
414
- if (property.value.type === "ArrayPattern" || property.value.type === "ObjectPattern") {
415
- validateDestructuredExports(property.value, exportsToRemove);
416
- }
318
+ reactRouterUserConfig = deepFreeze((0, import_cloneDeep.default)(reactRouterUserConfig));
319
+ let presets = (await Promise.all(
320
+ (reactRouterUserConfig.presets ?? []).map(async (preset) => {
321
+ if (!preset.name) {
322
+ throw new Error(
323
+ "React Router presets must have a `name` property defined."
324
+ );
417
325
  }
418
- if (property.type === "RestElement" && property.argument.type === "Identifier" && exportsToRemove.includes(property.argument.name)) {
419
- throw invalidDestructureError(property.argument.name);
420
- }
421
- }
422
- }
423
- }
424
- function invalidDestructureError(name) {
425
- return new Error(`Cannot remove destructured export "${name}"`);
426
- }
427
-
428
- // vite/config.ts
429
- var import_node_child_process = require("child_process");
430
- var import_node_path2 = __toESM(require("path"));
431
- var import_fs_extra = __toESM(require("fs-extra"));
432
- var import_picocolors = __toESM(require("picocolors"));
433
- var import_pick2 = __toESM(require("lodash/pick"));
434
- var import_omit = __toESM(require("lodash/omit"));
435
- var import_package_json = __toESM(require("@npmcli/package-json"));
436
-
437
- // config/routes.ts
438
- var import_node_path = require("path");
439
- var v = __toESM(require("valibot"));
440
- var import_pick = __toESM(require("lodash/pick"));
441
- function setAppDirectory(directory) {
442
- globalThis.__reactRouterAppDirectory = directory;
443
- }
444
- var routeConfigEntrySchema = v.pipe(
445
- v.custom((value) => {
446
- return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
447
- }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
448
- v.object({
449
- id: v.optional(v.string()),
450
- path: v.optional(v.string()),
451
- index: v.optional(v.boolean()),
452
- caseSensitive: v.optional(v.boolean()),
453
- file: v.string(),
454
- children: v.optional(v.array(v.lazy(() => routeConfigEntrySchema)))
455
- })
456
- );
457
- var resolvedRouteConfigSchema = v.array(routeConfigEntrySchema);
458
- function validateRouteConfig({
459
- routeConfigFile,
460
- routeConfig
461
- }) {
462
- if (!routeConfig) {
463
- return {
464
- valid: false,
465
- message: `No "routes" export defined in "${routeConfigFile}.`
466
- };
467
- }
468
- if (!Array.isArray(routeConfig)) {
469
- return {
470
- valid: false,
471
- message: `Route config in "${routeConfigFile}" must be an array.`
472
- };
473
- }
474
- let { issues } = v.safeParse(resolvedRouteConfigSchema, routeConfig);
475
- if (issues?.length) {
476
- let { root, nested } = v.flatten(issues);
477
- return {
478
- valid: false,
479
- message: [
480
- `Route config in "${routeConfigFile}" is invalid.`,
481
- root ? `${root}` : [],
482
- nested ? Object.entries(nested).map(
483
- ([path5, message]) => `Path: routes.${path5}
484
- ${message}`
485
- ) : []
486
- ].flat().join("\n\n")
487
- };
488
- }
489
- return { valid: true };
490
- }
491
- function configRoutesToRouteManifest(routes, rootId = "root") {
492
- let routeManifest = {};
493
- function walk(route, parentId) {
494
- let id2 = route.id || createRouteId(route.file);
495
- let manifestItem = {
496
- id: id2,
497
- parentId,
498
- file: route.file,
499
- path: route.path,
500
- index: route.index,
501
- caseSensitive: route.caseSensitive
502
- };
503
- if (routeManifest.hasOwnProperty(id2)) {
504
- throw new Error(
505
- `Unable to define routes with duplicate route id: "${id2}"`
506
- );
507
- }
508
- routeManifest[id2] = manifestItem;
509
- if (route.children) {
510
- for (let child of route.children) {
511
- walk(child, id2);
512
- }
513
- }
514
- }
515
- for (let route of routes) {
516
- walk(route, rootId);
517
- }
518
- return routeManifest;
519
- }
520
- function createRouteId(file) {
521
- return normalizeSlashes(stripFileExtension(file));
522
- }
523
- function normalizeSlashes(file) {
524
- return file.split(import_node_path.win32.sep).join("/");
525
- }
526
- function stripFileExtension(file) {
527
- return file.replace(/\.[a-z0-9]+$/i, "");
528
- }
529
-
530
- // cli/detectPackageManager.ts
531
- var detectPackageManager = () => {
532
- let { npm_config_user_agent } = process.env;
533
- if (!npm_config_user_agent) return void 0;
534
- try {
535
- let pkgManager = npm_config_user_agent.split("/")[0];
536
- if (pkgManager === "npm") return "npm";
537
- if (pkgManager === "pnpm") return "pnpm";
538
- if (pkgManager === "yarn") return "yarn";
539
- if (pkgManager === "bun") return "bun";
540
- return void 0;
541
- } catch {
542
- return void 0;
543
- }
544
- };
545
-
546
- // vite/config.ts
547
- var excludedConfigPresetKeys = ["presets"];
548
- var mergeReactRouterConfig = (...configs) => {
549
- let reducer = (configA, configB) => {
550
- let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
551
- return {
552
- ...configA,
553
- ...configB,
554
- ...mergeRequired("buildEnd") ? {
555
- buildEnd: async (...args) => {
556
- await Promise.all([
557
- configA.buildEnd?.(...args),
558
- configB.buildEnd?.(...args)
559
- ]);
560
- }
561
- } : {},
562
- ...mergeRequired("future") ? {
563
- future: {
564
- ...configA.future,
565
- ...configB.future
566
- }
567
- } : {},
568
- ...mergeRequired("presets") ? {
569
- presets: [...configA.presets ?? [], ...configB.presets ?? []]
570
- } : {}
571
- };
572
- };
573
- return configs.reduce(reducer, {});
574
- };
575
- var deepFreeze = (o) => {
576
- Object.freeze(o);
577
- let oIsFunction = typeof o === "function";
578
- let hasOwnProp = Object.prototype.hasOwnProperty;
579
- Object.getOwnPropertyNames(o).forEach(function(prop) {
580
- if (hasOwnProp.call(o, prop) && (oIsFunction ? prop !== "caller" && prop !== "callee" && prop !== "arguments" : true) && o[prop] !== null && (typeof o[prop] === "object" || typeof o[prop] === "function") && !Object.isFrozen(o[prop])) {
581
- deepFreeze(o[prop]);
582
- }
583
- });
584
- return o;
585
- };
586
- function resolvePublicPath(viteUserConfig) {
587
- return viteUserConfig.base ?? "/";
588
- }
589
- var isFirstLoad = true;
590
- var lastValidRoutes = {};
591
- async function resolveReactRouterConfig({
592
- rootDirectory,
593
- reactRouterUserConfig,
594
- routeConfigChanged,
595
- viteUserConfig,
596
- viteCommand,
597
- routesViteNodeContext
598
- }) {
599
- let vite2 = importViteEsmSync();
600
- let logger = vite2.createLogger(viteUserConfig.logLevel, {
601
- prefix: "[react-router]"
602
- });
603
- let presets = (await Promise.all(
604
- (reactRouterUserConfig.presets ?? []).map(async (preset) => {
605
- if (!preset.name) {
606
- throw new Error(
607
- "React Router presets must have a `name` property defined."
608
- );
609
- }
610
- if (!preset.reactRouterConfig) {
611
- return null;
326
+ if (!preset.reactRouterConfig) {
327
+ return null;
612
328
  }
613
329
  let configPreset = (0, import_omit.default)(
614
330
  await preset.reactRouterConfig({ reactRouterUserConfig }),
@@ -642,194 +358,786 @@ async function resolveReactRouterConfig({
642
358
  ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
643
359
  };
644
360
  if (!ssr && serverBundles) {
645
- console.warn(
646
- import_picocolors.default.yellow(
647
- import_picocolors.default.bold("\u26A0\uFE0F SPA Mode: ") + "the `serverBundles` config is invalid with `ssr:false` and will be ignored`"
648
- )
649
- );
650
361
  serverBundles = void 0;
651
362
  }
652
363
  let isValidPrerenderConfig = prerender == null || typeof prerender === "boolean" || Array.isArray(prerender) || typeof prerender === "function";
653
364
  if (!isValidPrerenderConfig) {
654
- logger.error(
655
- import_picocolors.default.red(
656
- "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
657
- )
658
- );
659
- process.exit(1);
660
- }
661
- let appDirectory = import_node_path2.default.resolve(rootDirectory, userAppDirectory || "app");
662
- let buildDirectory = import_node_path2.default.resolve(rootDirectory, userBuildDirectory);
663
- let publicPath = resolvePublicPath(viteUserConfig);
664
- if (basename2 !== "/" && viteCommand === "serve" && !viteUserConfig.server?.middlewareMode && !basename2.startsWith(publicPath)) {
665
- logger.error(
666
- import_picocolors.default.red(
667
- "When using the React Router `basename` and the Vite `base` config, the `basename` config must begin with `base` for the default Vite dev server."
668
- )
365
+ return err(
366
+ "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
669
367
  );
670
- process.exit(1);
671
368
  }
369
+ let appDirectory = import_pathe.default.resolve(root, userAppDirectory || "app");
370
+ let buildDirectory = import_pathe.default.resolve(root, userBuildDirectory);
672
371
  let rootRouteFile = findEntry(appDirectory, "root");
673
372
  if (!rootRouteFile) {
674
- let rootRouteDisplayPath = import_node_path2.default.relative(
675
- rootDirectory,
676
- import_node_path2.default.join(appDirectory, "root.tsx")
373
+ let rootRouteDisplayPath = import_pathe.default.relative(
374
+ root,
375
+ import_pathe.default.join(appDirectory, "root.tsx")
677
376
  );
678
- logger.error(
679
- import_picocolors.default.red(
680
- `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
681
- )
377
+ return err(
378
+ `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
682
379
  );
683
- process.exit(1);
684
380
  }
685
381
  let routes = {
686
382
  root: { path: "", id: "root", file: rootRouteFile }
687
383
  };
688
384
  let routeConfigFile = findEntry(appDirectory, "routes");
689
- class FriendlyError extends Error {
690
- }
691
385
  try {
692
386
  if (!routeConfigFile) {
693
- let routeConfigDisplayPath = vite2.normalizePath(
694
- import_node_path2.default.relative(rootDirectory, import_node_path2.default.join(appDirectory, "routes.ts"))
695
- );
696
- throw new FriendlyError(
697
- `Route config file not found at "${routeConfigDisplayPath}".`
387
+ let routeConfigDisplayPath = import_pathe.default.relative(
388
+ root,
389
+ import_pathe.default.join(appDirectory, "routes.ts")
698
390
  );
391
+ return err(`Route config file not found at "${routeConfigDisplayPath}".`);
699
392
  }
700
393
  setAppDirectory(appDirectory);
701
- let routeConfigExport = (await routesViteNodeContext.runner.executeFile(
702
- import_node_path2.default.join(appDirectory, routeConfigFile)
703
- )).routes;
394
+ let routeConfigExport = (await viteNodeContext.runner.executeFile(
395
+ import_pathe.default.join(appDirectory, routeConfigFile)
396
+ )).default;
704
397
  let routeConfig = await routeConfigExport;
705
398
  let result = validateRouteConfig({
706
399
  routeConfigFile,
707
400
  routeConfig
708
401
  });
709
402
  if (!result.valid) {
710
- throw new FriendlyError(result.message);
711
- }
712
- routes = { ...routes, ...configRoutesToRouteManifest(routeConfig) };
713
- lastValidRoutes = routes;
714
- if (routeConfigChanged) {
715
- logger.info(import_picocolors.default.green("Route config changed."), {
716
- clear: true,
717
- timestamp: true
718
- });
403
+ return err(result.message);
719
404
  }
405
+ routes = {
406
+ ...routes,
407
+ ...configRoutesToRouteManifest(appDirectory, routeConfig)
408
+ };
720
409
  } catch (error) {
721
- logger.error(
722
- error instanceof FriendlyError ? import_picocolors.default.red(error.message) : [
410
+ return err(
411
+ [
723
412
  import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
724
413
  "",
725
414
  error.loc?.file && error.loc?.column && error.frame ? [
726
- import_node_path2.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
415
+ import_pathe.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
727
416
  error.frame.trim?.()
728
417
  ] : error.stack
729
- ].flat().join("\n") + "\n",
730
- {
731
- error,
732
- clear: !isFirstLoad,
733
- timestamp: !isFirstLoad
418
+ ].flat().join("\n")
419
+ );
420
+ }
421
+ let future = {
422
+ unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
423
+ };
424
+ let reactRouterConfig = deepFreeze({
425
+ appDirectory,
426
+ basename: basename2,
427
+ buildDirectory,
428
+ buildEnd,
429
+ future,
430
+ prerender,
431
+ routes,
432
+ serverBuildFile,
433
+ serverBundles,
434
+ serverModuleFormat,
435
+ ssr
436
+ });
437
+ for (let preset of reactRouterUserConfig.presets ?? []) {
438
+ await preset.reactRouterConfigResolved?.({ reactRouterConfig });
439
+ }
440
+ return ok(reactRouterConfig);
441
+ }
442
+ async function createConfigLoader({
443
+ rootDirectory: root,
444
+ watch: watch2
445
+ }) {
446
+ root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
447
+ let viteNodeContext = await createContext({
448
+ root,
449
+ mode: watch2 ? "development" : "production",
450
+ server: !watch2 ? { watch: null } : {},
451
+ ssr: {
452
+ external: ssrExternals
453
+ }
454
+ });
455
+ let reactRouterConfigFile = findEntry(root, "react-router.config", {
456
+ absolute: true
457
+ });
458
+ let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
459
+ let appDirectory;
460
+ let initialConfigResult = await getConfig();
461
+ if (!initialConfigResult.ok) {
462
+ throw new Error(initialConfigResult.error);
463
+ }
464
+ appDirectory = initialConfigResult.value.appDirectory;
465
+ let lastConfig = initialConfigResult.value;
466
+ let fsWatcher;
467
+ let changeHandlers = [];
468
+ return {
469
+ getConfig,
470
+ onChange: (handler) => {
471
+ if (!watch2) {
472
+ throw new Error(
473
+ "onChange is not supported when watch mode is disabled"
474
+ );
475
+ }
476
+ changeHandlers.push(handler);
477
+ if (!fsWatcher) {
478
+ fsWatcher = import_chokidar.default.watch(
479
+ [
480
+ ...reactRouterConfigFile ? [reactRouterConfigFile] : [],
481
+ appDirectory
482
+ ],
483
+ { ignoreInitial: true }
484
+ );
485
+ fsWatcher.on("all", async (...args) => {
486
+ let [event, rawFilepath] = args;
487
+ let filepath = import_pathe.default.normalize(rawFilepath);
488
+ let appFileAddedOrRemoved = appDirectory && (event === "add" || event === "unlink") && filepath.startsWith(import_pathe.default.normalize(appDirectory));
489
+ let configCodeUpdated = Boolean(
490
+ viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
491
+ );
492
+ if (configCodeUpdated || appFileAddedOrRemoved) {
493
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
494
+ viteNodeContext.runner?.moduleCache.clear();
495
+ }
496
+ if (appFileAddedOrRemoved || configCodeUpdated) {
497
+ let result = await getConfig();
498
+ let configChanged = result.ok && !(0, import_isEqual.default)(lastConfig, result.value);
499
+ let routeConfigChanged = result.ok && !(0, import_isEqual.default)(lastConfig?.routes, result.value.routes);
500
+ for (let handler2 of changeHandlers) {
501
+ handler2({
502
+ result,
503
+ configCodeUpdated,
504
+ configChanged,
505
+ routeConfigChanged,
506
+ path: filepath,
507
+ event
508
+ });
509
+ }
510
+ if (result.ok) {
511
+ lastConfig = result.value;
512
+ }
513
+ }
514
+ });
515
+ }
516
+ return () => {
517
+ changeHandlers = changeHandlers.filter(
518
+ (changeHandler) => changeHandler !== handler
519
+ );
520
+ };
521
+ },
522
+ close: async () => {
523
+ changeHandlers = [];
524
+ await viteNodeContext.devServer.close();
525
+ await fsWatcher?.close();
526
+ }
527
+ };
528
+ }
529
+ async function resolveEntryFiles({
530
+ rootDirectory,
531
+ reactRouterConfig
532
+ }) {
533
+ let { appDirectory } = reactRouterConfig;
534
+ let defaultsDirectory = import_pathe.default.resolve(
535
+ import_pathe.default.dirname(require.resolve("@react-router/dev/package.json")),
536
+ "dist",
537
+ "config",
538
+ "defaults"
539
+ );
540
+ let userEntryClientFile = findEntry(appDirectory, "entry.client");
541
+ let userEntryServerFile = findEntry(appDirectory, "entry.server");
542
+ let entryServerFile;
543
+ let entryClientFile = userEntryClientFile || "entry.client.tsx";
544
+ let pkgJson = await import_package_json.default.load(rootDirectory);
545
+ let deps = pkgJson.content.dependencies ?? {};
546
+ if (userEntryServerFile) {
547
+ entryServerFile = userEntryServerFile;
548
+ } else {
549
+ if (!deps["@react-router/node"]) {
550
+ throw new Error(
551
+ `Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
552
+ );
553
+ }
554
+ if (!deps["isbot"]) {
555
+ console.log(
556
+ "adding `isbot@5` to your package.json, you should commit this change"
557
+ );
558
+ pkgJson.update({
559
+ dependencies: {
560
+ ...pkgJson.content.dependencies,
561
+ isbot: "^5"
562
+ }
563
+ });
564
+ await pkgJson.save();
565
+ let packageManager = detectPackageManager() ?? "npm";
566
+ (0, import_node_child_process.execSync)(`${packageManager} install`, {
567
+ cwd: rootDirectory,
568
+ stdio: "inherit"
569
+ });
570
+ }
571
+ entryServerFile = `entry.server.node.tsx`;
572
+ }
573
+ let entryClientFilePath = userEntryClientFile ? import_pathe.default.resolve(reactRouterConfig.appDirectory, userEntryClientFile) : import_pathe.default.resolve(defaultsDirectory, entryClientFile);
574
+ let entryServerFilePath = userEntryServerFile ? import_pathe.default.resolve(reactRouterConfig.appDirectory, userEntryServerFile) : import_pathe.default.resolve(defaultsDirectory, entryServerFile);
575
+ return { entryClientFilePath, entryServerFilePath };
576
+ }
577
+ var ssrExternals = isInReactRouterMonorepo() ? [
578
+ // This is only needed within this repo because these packages
579
+ // are linked to a directory outside of node_modules so Vite
580
+ // treats them as internal code by default.
581
+ "react-router",
582
+ "react-router-dom",
583
+ "@react-router/architect",
584
+ "@react-router/cloudflare",
585
+ "@react-router/dev",
586
+ "@react-router/express",
587
+ "@react-router/node",
588
+ "@react-router/serve"
589
+ ] : void 0;
590
+ function isInReactRouterMonorepo() {
591
+ let serverRuntimePath = import_pathe.default.dirname(
592
+ require.resolve("@react-router/node/package.json")
593
+ );
594
+ let serverRuntimeParentDir = import_pathe.default.basename(
595
+ import_pathe.default.resolve(serverRuntimePath, "..")
596
+ );
597
+ return serverRuntimeParentDir === "packages";
598
+ }
599
+ var entryExts = [".js", ".jsx", ".ts", ".tsx"];
600
+ function findEntry(dir, basename2, options) {
601
+ for (let ext of entryExts) {
602
+ let file = import_pathe.default.resolve(dir, basename2 + ext);
603
+ if (import_node_fs.default.existsSync(file)) {
604
+ return options?.absolute ?? false ? file : import_pathe.default.relative(dir, file);
605
+ }
606
+ }
607
+ return void 0;
608
+ }
609
+
610
+ // typegen/generate.ts
611
+ var import_dedent = __toESM(require("dedent"));
612
+ var Path3 = __toESM(require("pathe"));
613
+ var Pathe2 = __toESM(require("pathe/utils"));
614
+
615
+ // typegen/paths.ts
616
+ var Path2 = __toESM(require("pathe"));
617
+ var Pathe = __toESM(require("pathe/utils"));
618
+ function getTypesDir(ctx) {
619
+ return Path2.join(ctx.rootDirectory, ".react-router/types");
620
+ }
621
+ function getTypesPath(ctx, route) {
622
+ return Path2.join(
623
+ getTypesDir(ctx),
624
+ Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
625
+ Path2.dirname(route.file),
626
+ "+types/" + Pathe.filename(route.file) + ".ts"
627
+ );
628
+ }
629
+
630
+ // typegen/generate.ts
631
+ function generate(ctx, route) {
632
+ const lineage = getRouteLineage(ctx.config.routes, route);
633
+ const urlpath = lineage.map((route2) => route2.path).join("/");
634
+ const typesPath = getTypesPath(ctx, route);
635
+ const parents = lineage.slice(0, -1);
636
+ const parentTypeImports = parents.map((parent, i) => {
637
+ const rel = Path3.relative(
638
+ Path3.dirname(typesPath),
639
+ getTypesPath(ctx, parent)
640
+ );
641
+ const indent = i === 0 ? "" : " ".repeat(2);
642
+ let source = noExtension(rel);
643
+ if (!source.startsWith("../")) source = "./" + source;
644
+ return `${indent}import type { Info as Parent${i} } from "${source}"`;
645
+ }).join("\n");
646
+ return import_dedent.default`
647
+ // React Router generated types for route:
648
+ // ${route.file}
649
+
650
+ import type * as T from "react-router/route-module"
651
+
652
+ ${parentTypeImports}
653
+
654
+ type Module = typeof import("../${Pathe2.filename(route.file)}")
655
+
656
+ export type Info = {
657
+ parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
658
+ id: "${route.id}"
659
+ file: "${route.file}"
660
+ path: "${route.path}"
661
+ params: {${formatParamProperties(urlpath)}}
662
+ module: Module
663
+ loaderData: T.CreateLoaderData<Module>
664
+ actionData: T.CreateActionData<Module>
665
+ }
666
+
667
+ export namespace Route {
668
+ export type LinkDescriptors = T.LinkDescriptors
669
+ export type LinksFunction = () => LinkDescriptors
670
+
671
+ export type MetaArgs = T.CreateMetaArgs<Info>
672
+ export type MetaDescriptors = T.MetaDescriptors
673
+ export type MetaFunction = (args: MetaArgs) => MetaDescriptors
674
+
675
+ export type HeadersArgs = T.HeadersArgs
676
+ export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
677
+
678
+ export type LoaderArgs = T.CreateServerLoaderArgs<Info>
679
+ export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
680
+ export type ActionArgs = T.CreateServerActionArgs<Info>
681
+ export type ClientActionArgs = T.CreateClientActionArgs<Info>
682
+
683
+ export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Info>
684
+ export type ComponentProps = T.CreateComponentProps<Info>
685
+ export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Info>
686
+ }
687
+ `;
688
+ }
689
+ var noExtension = (path5) => Path3.join(Path3.dirname(path5), Pathe2.filename(path5));
690
+ function getRouteLineage(routes, route) {
691
+ const result = [];
692
+ while (route) {
693
+ result.push(route);
694
+ if (!route.parentId) break;
695
+ route = routes[route.parentId];
696
+ }
697
+ result.reverse();
698
+ return result;
699
+ }
700
+ function formatParamProperties(urlpath) {
701
+ const params = parseParams(urlpath);
702
+ const properties = Object.entries(params).map(([name, values]) => {
703
+ if (values.length === 1) {
704
+ const isOptional = values[0];
705
+ return isOptional ? `"${name}"?: string` : `"${name}": string`;
706
+ }
707
+ const items = values.map(
708
+ (isOptional) => isOptional ? "string | undefined" : "string"
709
+ );
710
+ return `"${name}": [${items.join(", ")}]`;
711
+ });
712
+ return properties.join("; ");
713
+ }
714
+ function parseParams(urlpath) {
715
+ const result = {};
716
+ let segments = urlpath.split("/");
717
+ segments.forEach((segment) => {
718
+ const match = segment.match(/^:([\w-]+)(\?)?/);
719
+ if (!match) return;
720
+ const param = match[1];
721
+ const isOptional = match[2] !== void 0;
722
+ result[param] ??= [];
723
+ result[param].push(isOptional);
724
+ return;
725
+ });
726
+ const hasSplat = segments.at(-1) === "*";
727
+ if (hasSplat) result["*"] = [false];
728
+ return result;
729
+ }
730
+
731
+ // typegen/index.ts
732
+ async function watch(rootDirectory, { logger } = {}) {
733
+ const ctx = await createContext2({ rootDirectory, watch: true });
734
+ await writeAll(ctx);
735
+ logger?.info(import_picocolors2.default.green("generated types"), { timestamp: true, clear: true });
736
+ ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
737
+ if (!result.ok) {
738
+ logger?.error(import_picocolors2.default.red(result.error), { timestamp: true, clear: true });
739
+ return;
740
+ }
741
+ ctx.config = result.value;
742
+ if (routeConfigChanged) {
743
+ await writeAll(ctx);
744
+ logger?.info(import_picocolors2.default.green("regenerated types"), {
745
+ timestamp: true,
746
+ clear: true
747
+ });
748
+ }
749
+ });
750
+ }
751
+ async function createContext2({
752
+ rootDirectory,
753
+ watch: watch2
754
+ }) {
755
+ const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
756
+ const configResult = await configLoader.getConfig();
757
+ if (!configResult.ok) {
758
+ throw new Error(configResult.error);
759
+ }
760
+ const config = configResult.value;
761
+ return {
762
+ configLoader,
763
+ rootDirectory,
764
+ config
765
+ };
766
+ }
767
+ async function writeAll(ctx) {
768
+ const typegenDir = getTypesDir(ctx);
769
+ import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
770
+ Object.values(ctx.config.routes).forEach((route) => {
771
+ const typesPath = getTypesPath(ctx, route);
772
+ const content = generate(ctx, route);
773
+ import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
774
+ import_node_fs2.default.writeFileSync(typesPath, content);
775
+ });
776
+ }
777
+
778
+ // vite/babel.ts
779
+ var import_parser = require("@babel/parser");
780
+ var t = __toESM(require("@babel/types"));
781
+ var traverse = require("@babel/traverse").default;
782
+ var generate2 = require("@babel/generator").default;
783
+
784
+ // vite/node-adapter.ts
785
+ var import_node_events = require("events");
786
+ var import_node_stream = require("stream");
787
+ var import_set_cookie_parser = require("set-cookie-parser");
788
+ var import_node = require("@react-router/node");
789
+ function fromNodeHeaders(nodeHeaders) {
790
+ let headers = new Headers();
791
+ for (let [key, values] of Object.entries(nodeHeaders)) {
792
+ if (values) {
793
+ if (Array.isArray(values)) {
794
+ for (let value of values) {
795
+ headers.append(key, value);
796
+ }
797
+ } else {
798
+ headers.set(key, values);
799
+ }
800
+ }
801
+ }
802
+ return headers;
803
+ }
804
+ function fromNodeRequest(nodeReq, nodeRes) {
805
+ let origin = nodeReq.headers.origin && "null" !== nodeReq.headers.origin ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
806
+ invariant(
807
+ nodeReq.originalUrl,
808
+ "Expected `nodeReq.originalUrl` to be defined"
809
+ );
810
+ let url3 = new URL(nodeReq.originalUrl, origin);
811
+ let controller = new AbortController();
812
+ let init = {
813
+ method: nodeReq.method,
814
+ headers: fromNodeHeaders(nodeReq.headers),
815
+ signal: controller.signal
816
+ };
817
+ nodeRes.on("finish", () => controller = null);
818
+ nodeRes.on("close", () => controller?.abort());
819
+ if (nodeReq.method !== "GET" && nodeReq.method !== "HEAD") {
820
+ init.body = (0, import_node.createReadableStreamFromReadable)(nodeReq);
821
+ init.duplex = "half";
822
+ }
823
+ return new Request(url3.href, init);
824
+ }
825
+ async function toNodeRequest(res, nodeRes) {
826
+ nodeRes.statusCode = res.status;
827
+ nodeRes.statusMessage = res.statusText;
828
+ let cookiesStrings = [];
829
+ for (let [name, value] of res.headers) {
830
+ if (name === "set-cookie") {
831
+ cookiesStrings.push(...(0, import_set_cookie_parser.splitCookiesString)(value));
832
+ } else nodeRes.setHeader(name, value);
833
+ }
834
+ if (cookiesStrings.length) {
835
+ nodeRes.setHeader("set-cookie", cookiesStrings);
836
+ }
837
+ if (res.body) {
838
+ let responseBody = res.body;
839
+ let readable = import_node_stream.Readable.from(responseBody);
840
+ readable.pipe(nodeRes);
841
+ await (0, import_node_events.once)(readable, "end");
842
+ } else {
843
+ nodeRes.end();
844
+ }
845
+ }
846
+
847
+ // vite/styles.ts
848
+ var path3 = __toESM(require("path"));
849
+ var import_react_router = require("react-router");
850
+
851
+ // vite/resolve-file-url.ts
852
+ var path2 = __toESM(require("path"));
853
+ var resolveFileUrl = ({ rootDirectory }, filePath) => {
854
+ let vite2 = importViteEsmSync();
855
+ let relativePath = path2.relative(rootDirectory, filePath);
856
+ let isWithinRoot = !relativePath.startsWith("..") && !path2.isAbsolute(relativePath);
857
+ if (!isWithinRoot) {
858
+ return path2.posix.join("/@fs", vite2.normalizePath(filePath));
859
+ }
860
+ return "/" + vite2.normalizePath(relativePath);
861
+ };
862
+
863
+ // vite/styles.ts
864
+ var cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
865
+ var cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
866
+ var isCssFile = (file) => cssFileRegExp.test(file);
867
+ var isCssModulesFile = (file) => cssModulesRegExp.test(file);
868
+ var cssUrlParamsWithoutSideEffects = ["url", "inline", "raw", "inline-css"];
869
+ var isCssUrlWithoutSideEffects = (url3) => {
870
+ let queryString = url3.split("?")[1];
871
+ if (!queryString) {
872
+ return false;
873
+ }
874
+ let params = new URLSearchParams(queryString);
875
+ for (let paramWithoutSideEffects of cssUrlParamsWithoutSideEffects) {
876
+ if (
877
+ // Parameter is blank and not explicitly set, i.e. "?url", not "?url="
878
+ params.get(paramWithoutSideEffects) === "" && !url3.includes(`?${paramWithoutSideEffects}=`) && !url3.includes(`&${paramWithoutSideEffects}=`)
879
+ ) {
880
+ return true;
881
+ }
882
+ }
883
+ return false;
884
+ };
885
+ var getStylesForFiles = async ({
886
+ viteDevServer,
887
+ rootDirectory,
888
+ cssModulesManifest,
889
+ files
890
+ }) => {
891
+ let styles = {};
892
+ let deps = /* @__PURE__ */ new Set();
893
+ try {
894
+ for (let file of files) {
895
+ let normalizedPath = path3.resolve(rootDirectory, file).replace(/\\/g, "/");
896
+ let node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
897
+ if (!node) {
898
+ try {
899
+ await viteDevServer.transformRequest(
900
+ resolveFileUrl({ rootDirectory }, normalizedPath)
901
+ );
902
+ } catch (err2) {
903
+ console.error(err2);
904
+ }
905
+ node = await viteDevServer.moduleGraph.getModuleById(normalizedPath);
906
+ }
907
+ if (!node) {
908
+ console.log(`Could not resolve module for file: ${file}`);
909
+ continue;
910
+ }
911
+ await findDeps(viteDevServer, node, deps);
912
+ }
913
+ } catch (err2) {
914
+ console.error(err2);
915
+ }
916
+ for (let dep of deps) {
917
+ if (dep.file && isCssFile(dep.file) && !isCssUrlWithoutSideEffects(dep.url)) {
918
+ try {
919
+ let css = isCssModulesFile(dep.file) ? cssModulesManifest[dep.file] : (await viteDevServer.ssrLoadModule(dep.url)).default;
920
+ if (css === void 0) {
921
+ throw new Error();
922
+ }
923
+ styles[dep.url] = css;
924
+ } catch {
925
+ console.warn(`Could not load ${dep.file}`);
926
+ }
927
+ }
928
+ }
929
+ return Object.entries(styles).map(([fileName, css], i) => [
930
+ `
931
+ /* ${fileName.replace(/\/\*/g, "/\\*").replace(/\*\//g, "*\\/")} */`,
932
+ css
933
+ ]).flat().join("\n") || void 0;
934
+ };
935
+ var findDeps = async (vite2, node, deps) => {
936
+ let branches = [];
937
+ async function addFromNode(node2) {
938
+ if (!deps.has(node2)) {
939
+ deps.add(node2);
940
+ await findDeps(vite2, node2, deps);
941
+ }
942
+ }
943
+ async function addFromUrl(url3) {
944
+ let node2 = await vite2.moduleGraph.getModuleByUrl(url3);
945
+ if (node2) {
946
+ await addFromNode(node2);
947
+ }
948
+ }
949
+ if (node.ssrTransformResult) {
950
+ if (node.ssrTransformResult.deps) {
951
+ node.ssrTransformResult.deps.forEach(
952
+ (url3) => branches.push(addFromUrl(url3))
953
+ );
954
+ }
955
+ } else {
956
+ node.importedModules.forEach((node2) => branches.push(addFromNode(node2)));
957
+ }
958
+ await Promise.all(branches);
959
+ };
960
+ var groupRoutesByParentId = (manifest) => {
961
+ let routes = {};
962
+ Object.values(manifest).forEach((route) => {
963
+ if (route) {
964
+ let parentId = route.parentId || "";
965
+ if (!routes[parentId]) {
966
+ routes[parentId] = [];
967
+ }
968
+ routes[parentId].push(route);
969
+ }
970
+ });
971
+ return routes;
972
+ };
973
+ var createRoutes = (manifest, parentId = "", routesByParentId = groupRoutesByParentId(manifest)) => {
974
+ return (routesByParentId[parentId] || []).map((route) => ({
975
+ ...route,
976
+ children: createRoutes(manifest, route.id, routesByParentId)
977
+ }));
978
+ };
979
+ var getStylesForUrl = async ({
980
+ viteDevServer,
981
+ rootDirectory,
982
+ reactRouterConfig,
983
+ entryClientFilePath,
984
+ cssModulesManifest,
985
+ build,
986
+ url: url3
987
+ }) => {
988
+ if (url3 === void 0 || url3.includes("?_data=")) {
989
+ return void 0;
990
+ }
991
+ let routes = createRoutes(build.routes);
992
+ let appPath = path3.relative(process.cwd(), reactRouterConfig.appDirectory);
993
+ let documentRouteFiles = (0, import_react_router.matchRoutes)(routes, url3, build.basename)?.map(
994
+ (match) => path3.resolve(appPath, reactRouterConfig.routes[match.route.id].file)
995
+ ) ?? [];
996
+ let styles = await getStylesForFiles({
997
+ viteDevServer,
998
+ rootDirectory,
999
+ cssModulesManifest,
1000
+ files: [
1001
+ // Always include the client entry file when crawling the module graph for CSS
1002
+ path3.relative(rootDirectory, entryClientFilePath),
1003
+ // Then include any styles from the matched routes
1004
+ ...documentRouteFiles
1005
+ ]
1006
+ });
1007
+ return styles;
1008
+ };
1009
+
1010
+ // vite/vmod.ts
1011
+ var id = (name) => `virtual:react-router/${name}`;
1012
+ var resolve3 = (id2) => `\0${id2}`;
1013
+ var url = (id2) => `/@id/__x00__${id2}`;
1014
+
1015
+ // vite/combine-urls.ts
1016
+ function combineURLs(baseURL, relativeURL) {
1017
+ return relativeURL ? baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "") : baseURL;
1018
+ }
1019
+
1020
+ // vite/remove-exports.ts
1021
+ var import_babel_dead_code_elimination = require("babel-dead-code-elimination");
1022
+ var removeExports = (ast, exportsToRemove) => {
1023
+ let previouslyReferencedIdentifiers = (0, import_babel_dead_code_elimination.findReferencedIdentifiers)(ast);
1024
+ let exportsFiltered = false;
1025
+ let markedForRemoval = /* @__PURE__ */ new Set();
1026
+ traverse(ast, {
1027
+ ExportDeclaration(path5) {
1028
+ if (path5.node.type === "ExportNamedDeclaration") {
1029
+ if (path5.node.specifiers.length) {
1030
+ path5.node.specifiers = path5.node.specifiers.filter((specifier) => {
1031
+ if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
1032
+ if (exportsToRemove.includes(specifier.exported.name)) {
1033
+ exportsFiltered = true;
1034
+ return false;
1035
+ }
1036
+ }
1037
+ return true;
1038
+ });
1039
+ if (path5.node.specifiers.length === 0) {
1040
+ markedForRemoval.add(path5);
1041
+ }
1042
+ }
1043
+ if (path5.node.declaration?.type === "VariableDeclaration") {
1044
+ let declaration = path5.node.declaration;
1045
+ declaration.declarations = declaration.declarations.filter(
1046
+ (declaration2) => {
1047
+ if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
1048
+ exportsFiltered = true;
1049
+ return false;
1050
+ }
1051
+ if (declaration2.id.type === "ArrayPattern" || declaration2.id.type === "ObjectPattern") {
1052
+ validateDestructuredExports(declaration2.id, exportsToRemove);
1053
+ }
1054
+ return true;
1055
+ }
1056
+ );
1057
+ if (declaration.declarations.length === 0) {
1058
+ markedForRemoval.add(path5);
1059
+ }
1060
+ }
1061
+ if (path5.node.declaration?.type === "FunctionDeclaration") {
1062
+ let id2 = path5.node.declaration.id;
1063
+ if (id2 && exportsToRemove.includes(id2.name)) {
1064
+ markedForRemoval.add(path5);
1065
+ }
1066
+ }
1067
+ if (path5.node.declaration?.type === "ClassDeclaration") {
1068
+ let id2 = path5.node.declaration.id;
1069
+ if (id2 && exportsToRemove.includes(id2.name)) {
1070
+ markedForRemoval.add(path5);
1071
+ }
1072
+ }
1073
+ }
1074
+ if (path5.node.type === "ExportDefaultDeclaration" && exportsToRemove.includes("default")) {
1075
+ markedForRemoval.add(path5);
734
1076
  }
735
- );
736
- if (isFirstLoad) {
737
- process.exit(1);
738
1077
  }
739
- routes = lastValidRoutes;
740
- }
741
- let future = {};
742
- let reactRouterConfig = deepFreeze({
743
- appDirectory,
744
- basename: basename2,
745
- buildDirectory,
746
- buildEnd,
747
- future,
748
- prerender,
749
- routes,
750
- serverBuildFile,
751
- serverBundles,
752
- serverModuleFormat,
753
- ssr
754
1078
  });
755
- for (let preset of reactRouterUserConfig.presets ?? []) {
756
- await preset.reactRouterConfigResolved?.({ reactRouterConfig });
1079
+ if (markedForRemoval.size > 0 || exportsFiltered) {
1080
+ for (let path5 of markedForRemoval) {
1081
+ path5.remove();
1082
+ }
1083
+ (0, import_babel_dead_code_elimination.deadCodeElimination)(ast, previouslyReferencedIdentifiers);
757
1084
  }
758
- isFirstLoad = false;
759
- return reactRouterConfig;
760
- }
761
- async function resolveEntryFiles({
762
- rootDirectory,
763
- reactRouterConfig
764
- }) {
765
- let { appDirectory } = reactRouterConfig;
766
- let defaultsDirectory = import_node_path2.default.resolve(
767
- import_node_path2.default.dirname(require.resolve("@react-router/dev/package.json")),
768
- "dist",
769
- "config",
770
- "defaults"
771
- );
772
- let userEntryClientFile = findEntry(appDirectory, "entry.client");
773
- let userEntryServerFile = findEntry(appDirectory, "entry.server");
774
- let entryServerFile;
775
- let entryClientFile = userEntryClientFile || "entry.client.tsx";
776
- let pkgJson = await import_package_json.default.load(rootDirectory);
777
- let deps = pkgJson.content.dependencies ?? {};
778
- if (userEntryServerFile) {
779
- entryServerFile = userEntryServerFile;
780
- } else {
781
- if (!deps["@react-router/node"]) {
782
- throw new Error(
783
- `Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
784
- );
1085
+ };
1086
+ function validateDestructuredExports(id2, exportsToRemove) {
1087
+ if (id2.type === "ArrayPattern") {
1088
+ for (let element of id2.elements) {
1089
+ if (!element) {
1090
+ continue;
1091
+ }
1092
+ if (element.type === "Identifier" && exportsToRemove.includes(element.name)) {
1093
+ throw invalidDestructureError(element.name);
1094
+ }
1095
+ if (element.type === "RestElement" && element.argument.type === "Identifier" && exportsToRemove.includes(element.argument.name)) {
1096
+ throw invalidDestructureError(element.argument.name);
1097
+ }
1098
+ if (element.type === "ArrayPattern" || element.type === "ObjectPattern") {
1099
+ validateDestructuredExports(element, exportsToRemove);
1100
+ }
785
1101
  }
786
- if (!deps["isbot"]) {
787
- console.log(
788
- "adding `isbot@5` to your package.json, you should commit this change"
789
- );
790
- pkgJson.update({
791
- dependencies: {
792
- ...pkgJson.content.dependencies,
793
- isbot: "^5"
1102
+ }
1103
+ if (id2.type === "ObjectPattern") {
1104
+ for (let property of id2.properties) {
1105
+ if (!property) {
1106
+ continue;
1107
+ }
1108
+ if (property.type === "ObjectProperty" && property.key.type === "Identifier") {
1109
+ if (property.value.type === "Identifier" && exportsToRemove.includes(property.value.name)) {
1110
+ throw invalidDestructureError(property.value.name);
794
1111
  }
795
- });
796
- await pkgJson.save();
797
- let packageManager = detectPackageManager() ?? "npm";
798
- (0, import_node_child_process.execSync)(`${packageManager} install`, {
799
- cwd: rootDirectory,
800
- stdio: "inherit"
801
- });
1112
+ if (property.value.type === "ArrayPattern" || property.value.type === "ObjectPattern") {
1113
+ validateDestructuredExports(property.value, exportsToRemove);
1114
+ }
1115
+ }
1116
+ if (property.type === "RestElement" && property.argument.type === "Identifier" && exportsToRemove.includes(property.argument.name)) {
1117
+ throw invalidDestructureError(property.argument.name);
1118
+ }
802
1119
  }
803
- entryServerFile = `entry.server.node.tsx`;
804
1120
  }
805
- let entryClientFilePath = userEntryClientFile ? import_node_path2.default.resolve(reactRouterConfig.appDirectory, userEntryClientFile) : import_node_path2.default.resolve(defaultsDirectory, entryClientFile);
806
- let entryServerFilePath = userEntryServerFile ? import_node_path2.default.resolve(reactRouterConfig.appDirectory, userEntryServerFile) : import_node_path2.default.resolve(defaultsDirectory, entryServerFile);
807
- return { entryClientFilePath, entryServerFilePath };
808
1121
  }
809
- var entryExts = [".js", ".jsx", ".ts", ".tsx"];
810
- function findEntry(dir, basename2) {
811
- for (let ext of entryExts) {
812
- let file = import_node_path2.default.resolve(dir, basename2 + ext);
813
- if (import_fs_extra.default.existsSync(file)) return import_node_path2.default.relative(dir, file);
814
- }
815
- return void 0;
1122
+ function invalidDestructureError(name) {
1123
+ return new Error(`Cannot remove destructured export "${name}"`);
816
1124
  }
817
1125
 
818
1126
  // vite/with-props.ts
819
- var import_dedent = __toESM(require("dedent"));
1127
+ var import_dedent2 = __toESM(require("dedent"));
820
1128
  var vmodId = id("with-props");
821
1129
  var NAMED_COMPONENT_EXPORTS = ["HydrateFallback", "ErrorBoundary"];
822
1130
  var plugin = {
823
1131
  name: "react-router-with-props",
824
1132
  enforce: "pre",
825
1133
  resolveId(id2) {
826
- if (id2 === vmodId) return resolve2(vmodId);
1134
+ if (id2 === vmodId) return resolve3(vmodId);
827
1135
  },
828
1136
  async load(id2) {
829
- if (id2 !== resolve2(vmodId)) return;
830
- return import_dedent.default`
1137
+ if (id2 !== resolve3(vmodId)) return;
1138
+ return import_dedent2.default`
831
1139
  import { createElement as h } from "react";
832
- import { useActionData, useLoaderData, useParams } from "react-router";
1140
+ import { useActionData, useLoaderData, useMatches, useParams } from "react-router";
833
1141
 
834
1142
  export function withComponentProps(Component) {
835
1143
  return function Wrapped() {
@@ -837,6 +1145,7 @@ var plugin = {
837
1145
  params: useParams(),
838
1146
  loaderData: useLoaderData(),
839
1147
  actionData: useActionData(),
1148
+ matches: useMatches(),
840
1149
  };
841
1150
  return h(Component, props);
842
1151
  };
@@ -937,48 +1246,6 @@ function toFunctionExpression(decl) {
937
1246
  );
938
1247
  }
939
1248
 
940
- // vite/vite-node.ts
941
- var import_server = require("vite-node/server");
942
- var import_client = require("vite-node/client");
943
- var import_source_map = require("vite-node/source-map");
944
- async function createContext(viteConfig = {}) {
945
- await preloadViteEsm();
946
- const vite2 = importViteEsmSync();
947
- const devServer = await vite2.createServer(
948
- vite2.mergeConfig(
949
- {
950
- server: {
951
- preTransformRequests: false,
952
- hmr: false
953
- },
954
- optimizeDeps: {
955
- noDiscovery: true
956
- },
957
- configFile: false,
958
- envFile: false,
959
- plugins: []
960
- },
961
- viteConfig
962
- )
963
- );
964
- await devServer.pluginContainer.buildStart({});
965
- const server = new import_server.ViteNodeServer(devServer);
966
- (0, import_source_map.installSourcemapsSupport)({
967
- getSourceMap: (source) => server.getSourceMap(source)
968
- });
969
- const runner = new import_client.ViteNodeRunner({
970
- root: devServer.config.root,
971
- base: devServer.config.base,
972
- fetchModule(id2) {
973
- return server.fetchModule(id2);
974
- },
975
- resolveId(id2, importer) {
976
- return server.resolveId(id2, importer);
977
- }
978
- });
979
- return { devServer, server, runner };
980
- }
981
-
982
1249
  // vite/plugin.ts
983
1250
  var SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "headers"];
984
1251
  var CLIENT_ROUTE_EXPORTS = [
@@ -1012,7 +1279,7 @@ var vmods = [serverBuildId, serverManifestId, browserManifestId];
1012
1279
  var invalidateVirtualModules = (viteDevServer) => {
1013
1280
  vmods.forEach((vmod) => {
1014
1281
  let mod = viteDevServer.moduleGraph.getModuleById(
1015
- resolve2(vmod)
1282
+ resolve3(vmod)
1016
1283
  );
1017
1284
  if (mod) {
1018
1285
  viteDevServer.moduleGraph.invalidateModule(mod);
@@ -1078,8 +1345,8 @@ function dedupe(array2) {
1078
1345
  return [...new Set(array2)];
1079
1346
  }
1080
1347
  var writeFileSafe = async (file, contents) => {
1081
- await fse2.ensureDir(path4.dirname(file));
1082
- await fse2.writeFile(file, contents);
1348
+ await fse.ensureDir(path4.dirname(file));
1349
+ await fse.writeFile(file, contents);
1083
1350
  };
1084
1351
  var getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
1085
1352
  let entries = await Promise.all(
@@ -1109,7 +1376,7 @@ var getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteF
1109
1376
  };
1110
1377
  let [id2, code] = await Promise.all([
1111
1378
  resolveId(),
1112
- readRouteFile?.() ?? fse2.readFile(routePath, "utf-8"),
1379
+ readRouteFile?.() ?? fse.readFile(routePath, "utf-8"),
1113
1380
  // pluginContainer.transform(...) fails if we don't do this first:
1114
1381
  moduleGraph.ensureEntryFromUrl(url3, ssr)
1115
1382
  ]);
@@ -1136,68 +1403,53 @@ var defaultEntriesDir = path4.resolve(
1136
1403
  "config",
1137
1404
  "defaults"
1138
1405
  );
1139
- var defaultEntries = fse2.readdirSync(defaultEntriesDir).map((filename) => path4.join(defaultEntriesDir, filename));
1406
+ var defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path4.join(defaultEntriesDir, filename3));
1140
1407
  invariant(defaultEntries.length > 0, "No default entries found");
1141
1408
  var reactRouterDevLoadContext = () => ({});
1142
- var deepFreeze2 = (o) => {
1143
- Object.freeze(o);
1144
- let oIsFunction = typeof o === "function";
1145
- let hasOwnProp = Object.prototype.hasOwnProperty;
1146
- Object.getOwnPropertyNames(o).forEach(function(prop) {
1147
- if (hasOwnProp.call(o, prop) && (oIsFunction ? prop !== "caller" && prop !== "callee" && prop !== "arguments" : true) && o[prop] !== null && (typeof o[prop] === "object" || typeof o[prop] === "function") && !Object.isFrozen(o[prop])) {
1148
- deepFreeze2(o[prop]);
1149
- }
1150
- });
1151
- return o;
1152
- };
1153
- var reactRouterVitePlugin = (_config) => {
1154
- let reactRouterUserConfig = _config ?? {};
1155
- reactRouterUserConfig = deepFreeze2(reactRouterUserConfig);
1409
+ var reactRouterVitePlugin = () => {
1410
+ let rootDirectory;
1156
1411
  let viteCommand;
1157
1412
  let viteUserConfig;
1158
1413
  let viteConfigEnv;
1159
1414
  let viteConfig;
1160
1415
  let cssModulesManifest = {};
1161
1416
  let viteChildCompiler = null;
1162
- let routesViteNodeContext = null;
1163
- let ssrExternals = isInReactRouterMonorepo() ? [
1164
- // This is only needed within this repo because these packages
1165
- // are linked to a directory outside of node_modules so Vite
1166
- // treats them as internal code by default.
1167
- "react-router",
1168
- "react-router-dom",
1169
- "@react-router/architect",
1170
- "@react-router/cloudflare",
1171
- "@react-router/dev",
1172
- "@react-router/express",
1173
- "@react-router/node",
1174
- "@react-router/serve"
1175
- ] : void 0;
1417
+ let reactRouterConfigLoader;
1418
+ let logger;
1419
+ let firstLoad = true;
1176
1420
  let ctx;
1177
- let updatePluginContext = async ({
1178
- routeConfigChanged = false
1179
- } = {}) => {
1180
- let rootDirectory = viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
1181
- invariant(routesViteNodeContext);
1182
- let reactRouterConfig = await resolveReactRouterConfig({
1183
- rootDirectory,
1184
- reactRouterUserConfig,
1185
- routeConfigChanged,
1186
- viteUserConfig,
1187
- viteCommand,
1188
- routesViteNodeContext
1189
- });
1421
+ let updatePluginContext = async () => {
1422
+ let reactRouterConfig;
1423
+ let reactRouterConfigResult = await reactRouterConfigLoader.getConfig();
1424
+ if (reactRouterConfigResult.ok) {
1425
+ reactRouterConfig = reactRouterConfigResult.value;
1426
+ } else {
1427
+ logger.error(reactRouterConfigResult.error);
1428
+ if (firstLoad) {
1429
+ process.exit(1);
1430
+ }
1431
+ return;
1432
+ }
1190
1433
  let { entryClientFilePath, entryServerFilePath } = await resolveEntryFiles({
1191
1434
  rootDirectory,
1192
1435
  reactRouterConfig
1193
1436
  });
1194
- let publicPath = resolvePublicPath(viteUserConfig);
1437
+ let publicPath = viteUserConfig.base ?? "/";
1438
+ if (reactRouterConfig.basename !== "/" && viteCommand === "serve" && !viteUserConfig.server?.middlewareMode && !reactRouterConfig.basename.startsWith(publicPath)) {
1439
+ logger.error(
1440
+ import_picocolors3.default.red(
1441
+ "When using the React Router `basename` and the Vite `base` config, the `basename` config must begin with `base` for the default Vite dev server."
1442
+ )
1443
+ );
1444
+ process.exit(1);
1445
+ }
1195
1446
  let viteManifestEnabled = viteUserConfig.build?.manifest === true;
1196
1447
  let ssrBuildCtx = viteConfigEnv.isSsrBuild && viteCommand === "build" ? {
1197
1448
  isSsrBuild: true,
1198
1449
  getReactRouterServerManifest: async () => (await generateReactRouterManifestsForBuild()).reactRouterServerManifest,
1199
1450
  serverBundleBuildConfig: getServerBundleBuildConfig(viteUserConfig)
1200
1451
  } : { isSsrBuild: false };
1452
+ firstLoad = false;
1201
1453
  ctx = {
1202
1454
  reactRouterConfig,
1203
1455
  rootDirectory,
@@ -1262,7 +1514,7 @@ var reactRouterVitePlugin = (_config) => {
1262
1514
  };`;
1263
1515
  };
1264
1516
  let loadViteManifest = async (directory) => {
1265
- let manifestContents = await fse2.readFile(
1517
+ let manifestContents = await fse.readFile(
1266
1518
  path4.resolve(directory, ".vite", "manifest.json"),
1267
1519
  "utf-8"
1268
1520
  );
@@ -1271,7 +1523,7 @@ var reactRouterVitePlugin = (_config) => {
1271
1523
  let hasDependency = (name) => {
1272
1524
  try {
1273
1525
  return Boolean(require.resolve(name, { paths: [ctx.rootDirectory] }));
1274
- } catch (err) {
1526
+ } catch (err2) {
1275
1527
  return false;
1276
1528
  }
1277
1529
  };
@@ -1416,15 +1668,19 @@ var reactRouterVitePlugin = (_config) => {
1416
1668
  viteUserConfig = _viteUserConfig;
1417
1669
  viteConfigEnv = _viteConfigEnv;
1418
1670
  viteCommand = viteConfigEnv.command;
1419
- routesViteNodeContext = await createContext({
1420
- root: viteUserConfig.root,
1421
- mode: viteConfigEnv.mode,
1422
- server: {
1423
- watch: viteCommand === "build" ? null : void 0
1424
- },
1425
- ssr: {
1426
- external: ssrExternals
1427
- }
1671
+ logger = vite2.createLogger(viteUserConfig.logLevel, {
1672
+ prefix: "[react-router]"
1673
+ });
1674
+ rootDirectory = viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
1675
+ if (viteCommand === "serve") {
1676
+ watch(rootDirectory, {
1677
+ // ignore `info` logs from typegen since they are redundant when Vite plugin logs are active
1678
+ logger: vite2.createLogger("warn", { prefix: "[react-router]" })
1679
+ });
1680
+ }
1681
+ reactRouterConfigLoader = await createConfigLoader({
1682
+ rootDirectory,
1683
+ watch: viteCommand === "serve"
1428
1684
  });
1429
1685
  await updatePluginContext();
1430
1686
  Object.assign(
@@ -1459,9 +1715,19 @@ var reactRouterVitePlugin = (_config) => {
1459
1715
  __reactRouterPluginContext: ctx,
1460
1716
  appType: viteCommand === "serve" && viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr === false ? "spa" : "custom",
1461
1717
  ssr: {
1462
- external: ssrExternals
1718
+ external: ssrExternals,
1719
+ resolve: {
1720
+ conditions: viteCommand === "build" ? [] : ["development"],
1721
+ externalConditions: viteCommand === "build" ? [] : ["development"]
1722
+ }
1463
1723
  },
1464
1724
  optimizeDeps: {
1725
+ entries: ctx.reactRouterConfig.future.unstable_optimizeDeps ? [
1726
+ ctx.entryClientFilePath,
1727
+ ...Object.values(ctx.reactRouterConfig.routes).map(
1728
+ (route) => path4.join(ctx.reactRouterConfig.appDirectory, route.file)
1729
+ )
1730
+ ] : [],
1465
1731
  include: [
1466
1732
  // Pre-bundle React dependencies to avoid React duplicates,
1467
1733
  // even if React dependencies are not direct dependencies.
@@ -1492,7 +1758,8 @@ var reactRouterVitePlugin = (_config) => {
1492
1758
  "react-router",
1493
1759
  "react-router/dom",
1494
1760
  "react-router-dom"
1495
- ]
1761
+ ],
1762
+ conditions: viteCommand === "build" ? [] : ["development"]
1496
1763
  },
1497
1764
  base: viteUserConfig.base,
1498
1765
  // When consumer provides an allow list for files that can be read by
@@ -1614,8 +1881,8 @@ var reactRouterVitePlugin = (_config) => {
1614
1881
  invariant(viteConfig);
1615
1882
  if (viteCommand === "build" && viteConfig.mode === "production" && !viteConfig.build.ssr && viteConfig.build.sourcemap) {
1616
1883
  viteConfig.logger.warn(
1617
- import_picocolors2.default.yellow(
1618
- "\n" + import_picocolors2.default.bold(" \u26A0\uFE0F Source maps are enabled in production\n") + [
1884
+ import_picocolors3.default.yellow(
1885
+ "\n" + import_picocolors3.default.bold(" \u26A0\uFE0F Source maps are enabled in production\n") + [
1619
1886
  "This makes your server code publicly",
1620
1887
  "visible in the browser. This is highly",
1621
1888
  "discouraged! If you insist, ensure that",
@@ -1650,31 +1917,38 @@ var reactRouterVitePlugin = (_config) => {
1650
1917
  }
1651
1918
  }
1652
1919
  });
1653
- viteDevServer.watcher.on("all", async (eventName, rawFilepath) => {
1654
- let { normalizePath } = importViteEsmSync();
1655
- let filepath = normalizePath(rawFilepath);
1656
- let appFileAddedOrRemoved = (eventName === "add" || eventName === "unlink") && filepath.startsWith(
1657
- normalizePath(ctx.reactRouterConfig.appDirectory)
1658
- );
1659
- invariant(viteConfig?.configFile);
1660
- let viteConfigChanged = eventName === "change" && filepath === normalizePath(viteConfig.configFile);
1661
- let routeConfigChanged = Boolean(
1662
- routesViteNodeContext?.devServer?.moduleGraph.getModuleById(
1663
- filepath
1664
- )
1665
- );
1666
- if (routeConfigChanged || appFileAddedOrRemoved) {
1667
- routesViteNodeContext?.devServer?.moduleGraph.invalidateAll();
1668
- routesViteNodeContext?.runner?.moduleCache.clear();
1669
- }
1670
- if (appFileAddedOrRemoved || viteConfigChanged || routeConfigChanged) {
1671
- let lastReactRouterConfig = ctx.reactRouterConfig;
1672
- await updatePluginContext({ routeConfigChanged });
1673
- if (!isEqualJson(lastReactRouterConfig, ctx.reactRouterConfig)) {
1920
+ reactRouterConfigLoader.onChange(
1921
+ async ({
1922
+ result,
1923
+ configCodeUpdated,
1924
+ configChanged,
1925
+ routeConfigChanged
1926
+ }) => {
1927
+ if (!result.ok) {
1928
+ invalidateVirtualModules(viteDevServer);
1929
+ logger.error(result.error, {
1930
+ clear: true,
1931
+ timestamp: true
1932
+ });
1933
+ return;
1934
+ }
1935
+ if (routeConfigChanged) {
1936
+ logger.info(import_picocolors3.default.green("Route config changed."), {
1937
+ clear: true,
1938
+ timestamp: true
1939
+ });
1940
+ } else if (configCodeUpdated) {
1941
+ logger.info(import_picocolors3.default.green("Config updated."), {
1942
+ clear: true,
1943
+ timestamp: true
1944
+ });
1945
+ }
1946
+ await updatePluginContext();
1947
+ if (configChanged) {
1674
1948
  invalidateVirtualModules(viteDevServer);
1675
1949
  }
1676
1950
  }
1677
- });
1951
+ );
1678
1952
  return () => {
1679
1953
  if (!viteDevServer.config.server.middlewareMode) {
1680
1954
  viteDevServer.middlewares.use(async (req, res, next) => {
@@ -1717,11 +1991,11 @@ var reactRouterVitePlugin = (_config) => {
1717
1991
  for (let ssrAssetPath of ssrAssetPaths) {
1718
1992
  let src = path4.join(serverBuildDirectory, ssrAssetPath);
1719
1993
  let dest = path4.join(clientBuildDirectory, ssrAssetPath);
1720
- if (!fse2.existsSync(dest)) {
1721
- await fse2.move(src, dest);
1994
+ if (!fse.existsSync(dest)) {
1995
+ await fse.move(src, dest);
1722
1996
  movedAssetPaths.push(dest);
1723
1997
  } else {
1724
- await fse2.remove(src);
1998
+ await fse.remove(src);
1725
1999
  }
1726
2000
  }
1727
2001
  let ssrCssPaths = Object.values(ssrViteManifest).flatMap(
@@ -1729,16 +2003,16 @@ var reactRouterVitePlugin = (_config) => {
1729
2003
  );
1730
2004
  await Promise.all(
1731
2005
  ssrCssPaths.map(
1732
- (cssPath) => fse2.remove(path4.join(serverBuildDirectory, cssPath))
2006
+ (cssPath) => fse.remove(path4.join(serverBuildDirectory, cssPath))
1733
2007
  )
1734
2008
  );
1735
2009
  if (movedAssetPaths.length) {
1736
2010
  viteConfig.logger.info(
1737
2011
  [
1738
2012
  "",
1739
- `${import_picocolors2.default.green("\u2713")} ${movedAssetPaths.length} asset${movedAssetPaths.length > 1 ? "s" : ""} moved from React Router server build to client assets.`,
2013
+ `${import_picocolors3.default.green("\u2713")} ${movedAssetPaths.length} asset${movedAssetPaths.length > 1 ? "s" : ""} moved from React Router server build to client assets.`,
1740
2014
  ...movedAssetPaths.map(
1741
- (movedAssetPath) => import_picocolors2.default.dim(path4.relative(ctx.rootDirectory, movedAssetPath))
2015
+ (movedAssetPath) => import_picocolors3.default.dim(path4.relative(ctx.rootDirectory, movedAssetPath))
1742
2016
  ),
1743
2017
  ""
1744
2018
  ].join("\n")
@@ -1751,7 +2025,8 @@ var reactRouterVitePlugin = (_config) => {
1751
2025
  serverBuildDirectory,
1752
2026
  clientBuildDirectory
1753
2027
  );
1754
- } else if (!ctx.reactRouterConfig.ssr) {
2028
+ }
2029
+ if (!ctx.reactRouterConfig.ssr) {
1755
2030
  await handleSpaMode(
1756
2031
  viteConfig,
1757
2032
  ctx.reactRouterConfig,
@@ -1763,17 +2038,17 @@ var reactRouterVitePlugin = (_config) => {
1763
2038
  viteConfig.logger.info(
1764
2039
  [
1765
2040
  "Removing the server build in",
1766
- import_picocolors2.default.green(serverBuildDirectory),
2041
+ import_picocolors3.default.green(serverBuildDirectory),
1767
2042
  "due to ssr:false"
1768
2043
  ].join(" ")
1769
2044
  );
1770
- fse2.removeSync(serverBuildDirectory);
2045
+ fse.removeSync(serverBuildDirectory);
1771
2046
  }
1772
2047
  }
1773
2048
  },
1774
2049
  async buildEnd() {
1775
2050
  await viteChildCompiler?.close();
1776
- await routesViteNodeContext?.devServer?.close();
2051
+ await reactRouterConfigLoader.close();
1777
2052
  }
1778
2053
  },
1779
2054
  {
@@ -1798,20 +2073,20 @@ var reactRouterVitePlugin = (_config) => {
1798
2073
  name: "react-router-virtual-modules",
1799
2074
  enforce: "pre",
1800
2075
  resolveId(id2) {
1801
- if (vmods.includes(id2)) return resolve2(id2);
2076
+ if (vmods.includes(id2)) return resolve3(id2);
1802
2077
  },
1803
2078
  async load(id2) {
1804
2079
  switch (id2) {
1805
- case resolve2(serverBuildId): {
2080
+ case resolve3(serverBuildId): {
1806
2081
  return await getServerEntry();
1807
2082
  }
1808
- case resolve2(serverManifestId): {
2083
+ case resolve3(serverManifestId): {
1809
2084
  let reactRouterManifest = ctx.isSsrBuild ? await ctx.getReactRouterServerManifest() : await getReactRouterManifestForDev();
1810
2085
  return `export default ${(0, import_jsesc.default)(reactRouterManifest, {
1811
2086
  es6: true
1812
2087
  })};`;
1813
2088
  }
1814
- case resolve2(browserManifestId): {
2089
+ case resolve3(browserManifestId): {
1815
2090
  if (viteCommand === "build") {
1816
2091
  throw new Error("This module only exists in development");
1817
2092
  }
@@ -1854,7 +2129,7 @@ var reactRouterVitePlugin = (_config) => {
1854
2129
  ).join(", ");
1855
2130
  throw Error(
1856
2131
  [
1857
- import_picocolors2.default.red(`Server-only module referenced by client`),
2132
+ import_picocolors3.default.red(`Server-only module referenced by client`),
1858
2133
  "",
1859
2134
  ` '${id2}' imported by route '${importerShort}'`,
1860
2135
  "",
@@ -1870,7 +2145,7 @@ var reactRouterVitePlugin = (_config) => {
1870
2145
  }
1871
2146
  throw Error(
1872
2147
  [
1873
- import_picocolors2.default.red(`Server-only module referenced by client`),
2148
+ import_picocolors3.default.red(`Server-only module referenced by client`),
1874
2149
  "",
1875
2150
  ` '${id2}' imported by '${importerShort}'`,
1876
2151
  "",
@@ -1924,7 +2199,7 @@ var reactRouterVitePlugin = (_config) => {
1924
2199
  removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
1925
2200
  }
1926
2201
  transform(ast);
1927
- return generate(ast, {
2202
+ return generate2(ast, {
1928
2203
  sourceMaps: true,
1929
2204
  filename: id2,
1930
2205
  sourceFileName: filepath
@@ -1936,10 +2211,10 @@ var reactRouterVitePlugin = (_config) => {
1936
2211
  enforce: "pre",
1937
2212
  resolveId(id2) {
1938
2213
  if (id2 === injectHmrRuntimeId)
1939
- return resolve2(injectHmrRuntimeId);
2214
+ return resolve3(injectHmrRuntimeId);
1940
2215
  },
1941
2216
  async load(id2) {
1942
- if (id2 !== resolve2(injectHmrRuntimeId)) return;
2217
+ if (id2 !== resolve3(injectHmrRuntimeId)) return;
1943
2218
  return [
1944
2219
  `import RefreshRuntime from "${hmrRuntimeId}"`,
1945
2220
  "RefreshRuntime.injectIntoGlobalHook(window)",
@@ -1953,10 +2228,10 @@ var reactRouterVitePlugin = (_config) => {
1953
2228
  name: "react-router-hmr-runtime",
1954
2229
  enforce: "pre",
1955
2230
  resolveId(id2) {
1956
- if (id2 === hmrRuntimeId) return resolve2(hmrRuntimeId);
2231
+ if (id2 === hmrRuntimeId) return resolve3(hmrRuntimeId);
1957
2232
  },
1958
2233
  async load(id2) {
1959
- if (id2 !== resolve2(hmrRuntimeId)) return;
2234
+ if (id2 !== resolve3(hmrRuntimeId)) return;
1960
2235
  let reactRefreshDir = path4.dirname(
1961
2236
  require.resolve("react-refresh/package.json")
1962
2237
  );
@@ -1966,8 +2241,8 @@ var reactRouterVitePlugin = (_config) => {
1966
2241
  );
1967
2242
  return [
1968
2243
  "const exports = {}",
1969
- await fse2.readFile(reactRefreshRuntimePath, "utf8"),
1970
- await fse2.readFile(
2244
+ await fse.readFile(reactRefreshRuntimePath, "utf8"),
2245
+ await fse.readFile(
1971
2246
  require.resolve("./static/refresh-utils.cjs"),
1972
2247
  "utf8"
1973
2248
  ),
@@ -2047,18 +2322,6 @@ var reactRouterVitePlugin = (_config) => {
2047
2322
  }
2048
2323
  ];
2049
2324
  };
2050
- function isInReactRouterMonorepo() {
2051
- let serverRuntimePath = path4.dirname(
2052
- require.resolve("@react-router/node/package.json")
2053
- );
2054
- let serverRuntimeParentDir = path4.basename(
2055
- path4.resolve(serverRuntimePath, "..")
2056
- );
2057
- return serverRuntimeParentDir === "packages";
2058
- }
2059
- function isEqualJson(v1, v2) {
2060
- return JSON.stringify(v1) === JSON.stringify(v2);
2061
- }
2062
2325
  function addRefreshWrapper(reactRouterConfig, code, id2) {
2063
2326
  let route = getRoute(reactRouterConfig, id2);
2064
2327
  let acceptExports = route || isRouteEntry(id2) ? [
@@ -2191,9 +2454,9 @@ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory
2191
2454
  let html = await response.text();
2192
2455
  validatePrerenderedResponse(response, html, "SPA Mode", "/");
2193
2456
  validatePrerenderedHtml(html, "SPA Mode");
2194
- await fse2.writeFile(path4.join(clientBuildDirectory, "index.html"), html);
2457
+ await fse.writeFile(path4.join(clientBuildDirectory, "index.html"), html);
2195
2458
  viteConfig.logger.info(
2196
- "SPA Mode: index.html has been written to your " + import_picocolors2.default.bold(path4.relative(process.cwd(), clientBuildDirectory)) + " directory"
2459
+ "SPA Mode: index.html has been written to your " + import_picocolors3.default.bold(path4.relative(process.cwd(), clientBuildDirectory)) + " directory"
2197
2460
  );
2198
2461
  }
2199
2462
  async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirectory, clientBuildDirectory) {
@@ -2311,9 +2574,9 @@ async function prerenderData(handler, prerenderPath, clientBuildDirectory, react
2311
2574
  validatePrerenderedResponse(response, data, "Prerender", normalizedPath);
2312
2575
  let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2313
2576
  let outfile = path4.join(outdir, ...normalizedPath.split("/"));
2314
- await fse2.ensureDir(path4.dirname(outfile));
2315
- await fse2.outputFile(outfile, data);
2316
- viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2577
+ await fse.ensureDir(path4.dirname(outfile));
2578
+ await fse.outputFile(outfile, data);
2579
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
2317
2580
  return data;
2318
2581
  }
2319
2582
  async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
@@ -2330,9 +2593,9 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
2330
2593
  }
2331
2594
  let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2332
2595
  let outfile = path4.join(outdir, ...normalizedPath.split("/"), "index.html");
2333
- await fse2.ensureDir(path4.dirname(outfile));
2334
- await fse2.outputFile(outfile, html);
2335
- viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2596
+ await fse.ensureDir(path4.dirname(outfile));
2597
+ await fse.outputFile(outfile, html);
2598
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
2336
2599
  }
2337
2600
  async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
2338
2601
  let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
@@ -2342,9 +2605,9 @@ async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirecto
2342
2605
  validatePrerenderedResponse(response, text, "Prerender", normalizedPath);
2343
2606
  let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2344
2607
  let outfile = path4.join(outdir, ...normalizedPath.split("/"));
2345
- await fse2.ensureDir(path4.dirname(outfile));
2346
- await fse2.outputFile(outfile, text);
2347
- viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2608
+ await fse.ensureDir(path4.dirname(outfile));
2609
+ await fse.outputFile(outfile, text);
2610
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
2348
2611
  }
2349
2612
  async function prerenderManifest(build, clientBuildDirectory, reactRouterConfig, viteConfig) {
2350
2613
  let normalizedPath = `${reactRouterConfig.basename}/__manifest`.replace(
@@ -2353,10 +2616,10 @@ async function prerenderManifest(build, clientBuildDirectory, reactRouterConfig,
2353
2616
  );
2354
2617
  let outdir = path4.relative(process.cwd(), clientBuildDirectory);
2355
2618
  let outfile = path4.join(outdir, ...normalizedPath.split("/"));
2356
- await fse2.ensureDir(path4.dirname(outfile));
2619
+ await fse.ensureDir(path4.dirname(outfile));
2357
2620
  let manifestData = JSON.stringify(build.assets.routes);
2358
- await fse2.outputFile(outfile, manifestData);
2359
- viteConfig.logger.info(`Prerender: Generated ${import_picocolors2.default.bold(outfile)}`);
2621
+ await fse.outputFile(outfile, manifestData);
2622
+ viteConfig.logger.info(`Prerender: Generated ${import_picocolors3.default.bold(outfile)}`);
2360
2623
  }
2361
2624
  function validatePrerenderedResponse(response, html, prefix, path5) {
2362
2625
  if (response.status !== 200) {