@react-router/dev 0.0.0-experimental-16086cbff → 0.0.0-experimental-121725374

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/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v0.0.0-experimental-16086cbff
3
+ * @react-router/dev v0.0.0-experimental-121725374
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -55,31 +55,6 @@ var init_invariant = __esm({
55
55
  }
56
56
  });
57
57
 
58
- // vite/babel.ts
59
- var import_parser, t, traverse, generate;
60
- var init_babel = __esm({
61
- "vite/babel.ts"() {
62
- "use strict";
63
- import_parser = require("@babel/parser");
64
- t = __toESM(require("@babel/types"));
65
- traverse = require("@babel/traverse").default;
66
- generate = require("@babel/generator").default;
67
- }
68
- });
69
-
70
- // vite/node-adapter.ts
71
- var import_node_events, import_node_stream, import_set_cookie_parser, import_node;
72
- var init_node_adapter = __esm({
73
- "vite/node-adapter.ts"() {
74
- "use strict";
75
- import_node_events = require("events");
76
- import_node_stream = require("stream");
77
- import_set_cookie_parser = require("set-cookie-parser");
78
- import_node = require("@react-router/node");
79
- init_invariant();
80
- }
81
- });
82
-
83
58
  // vite/import-vite-esm-sync.ts
84
59
  async function preloadViteEsm() {
85
60
  vite = await import("vite");
@@ -96,64 +71,100 @@ var init_import_vite_esm_sync = __esm({
96
71
  }
97
72
  });
98
73
 
99
- // vite/resolve-file-url.ts
100
- var path;
101
- var init_resolve_file_url = __esm({
102
- "vite/resolve-file-url.ts"() {
74
+ // vite/vite-node.ts
75
+ async function createContext(viteConfig = {}) {
76
+ await preloadViteEsm();
77
+ const vite2 = importViteEsmSync();
78
+ const devServer = await vite2.createServer(
79
+ vite2.mergeConfig(
80
+ {
81
+ server: {
82
+ preTransformRequests: false,
83
+ hmr: false
84
+ },
85
+ optimizeDeps: {
86
+ noDiscovery: true
87
+ },
88
+ configFile: false,
89
+ envFile: false,
90
+ plugins: []
91
+ },
92
+ viteConfig
93
+ )
94
+ );
95
+ await devServer.pluginContainer.buildStart({});
96
+ const server = new import_server.ViteNodeServer(devServer);
97
+ (0, import_source_map.installSourcemapsSupport)({
98
+ getSourceMap: (source) => server.getSourceMap(source)
99
+ });
100
+ const runner = new import_client.ViteNodeRunner({
101
+ root: devServer.config.root,
102
+ base: devServer.config.base,
103
+ fetchModule(id2) {
104
+ return server.fetchModule(id2);
105
+ },
106
+ resolveId(id2, importer) {
107
+ return server.resolveId(id2, importer);
108
+ }
109
+ });
110
+ return { devServer, server, runner };
111
+ }
112
+ var import_server, import_client, import_source_map;
113
+ var init_vite_node = __esm({
114
+ "vite/vite-node.ts"() {
103
115
  "use strict";
104
- path = __toESM(require("path"));
116
+ import_server = require("vite-node/server");
117
+ import_client = require("vite-node/client");
118
+ import_source_map = require("vite-node/source-map");
105
119
  init_import_vite_esm_sync();
106
120
  }
107
121
  });
108
122
 
109
- // vite/styles.ts
110
- var path2, import_react_router, cssFileRegExp, cssModulesRegExp;
111
- var init_styles = __esm({
112
- "vite/styles.ts"() {
113
- "use strict";
114
- path2 = __toESM(require("path"));
115
- import_react_router = require("react-router");
116
- init_resolve_file_url();
117
- cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
118
- cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
119
- }
120
- });
121
-
122
- // vite/vmod.ts
123
- var id;
124
- var init_vmod = __esm({
125
- "vite/vmod.ts"() {
126
- "use strict";
127
- id = (name) => `virtual:react-router/${name}`;
123
+ // config/routes.ts
124
+ function setAppDirectory(directory) {
125
+ globalThis.__reactRouterAppDirectory = directory;
126
+ }
127
+ function validateRouteConfig({
128
+ routeConfigFile,
129
+ routeConfig
130
+ }) {
131
+ if (!routeConfig) {
132
+ return {
133
+ valid: false,
134
+ message: `Route config must be the default export in "${routeConfigFile}".`
135
+ };
128
136
  }
129
- });
130
-
131
- // vite/combine-urls.ts
132
- var init_combine_urls = __esm({
133
- "vite/combine-urls.ts"() {
134
- "use strict";
137
+ if (!Array.isArray(routeConfig)) {
138
+ return {
139
+ valid: false,
140
+ message: `Route config in "${routeConfigFile}" must be an array.`
141
+ };
135
142
  }
136
- });
137
-
138
- // vite/remove-exports.ts
139
- var import_babel_dead_code_elimination;
140
- var init_remove_exports = __esm({
141
- "vite/remove-exports.ts"() {
142
- "use strict";
143
- import_babel_dead_code_elimination = require("babel-dead-code-elimination");
144
- init_babel();
143
+ let { issues } = v.safeParse(resolvedRouteConfigSchema, routeConfig);
144
+ if (issues?.length) {
145
+ let { root, nested } = v.flatten(issues);
146
+ return {
147
+ valid: false,
148
+ message: [
149
+ `Route config in "${routeConfigFile}" is invalid.`,
150
+ root ? `${root}` : [],
151
+ nested ? Object.entries(nested).map(
152
+ ([path8, message]) => `Path: routes.${path8}
153
+ ${message}`
154
+ ) : []
155
+ ].flat().join("\n\n")
156
+ };
145
157
  }
146
- });
147
-
148
- // config/routes.ts
149
- function configRoutesToRouteManifest(routes2, rootId = "root") {
158
+ return { valid: true };
159
+ }
160
+ function configRoutesToRouteManifest(appDirectory, routes2, rootId = "root") {
150
161
  let routeManifest = {};
151
162
  function walk(route, parentId) {
152
163
  let id2 = route.id || createRouteId(route.file);
153
164
  let manifestItem = {
154
165
  id: id2,
155
166
  parentId,
156
- file: route.file,
167
+ file: Path.isAbsolute(route.file) ? Path.relative(appDirectory, route.file) : route.file,
157
168
  path: route.path,
158
169
  index: route.index,
159
170
  caseSensitive: route.caseSensitive
@@ -170,146 +181,668 @@ function configRoutesToRouteManifest(routes2, rootId = "root") {
170
181
  }
171
182
  }
172
183
  }
173
- for (let route of routes2) {
174
- walk(route, rootId);
184
+ for (let route of routes2) {
185
+ walk(route, rootId);
186
+ }
187
+ return routeManifest;
188
+ }
189
+ function createRouteId(file) {
190
+ return Path.normalize(stripFileExtension(file));
191
+ }
192
+ function stripFileExtension(file) {
193
+ return file.replace(/\.[a-z0-9]+$/i, "");
194
+ }
195
+ var Path, v, import_pick, routeConfigEntrySchema, resolvedRouteConfigSchema;
196
+ var init_routes = __esm({
197
+ "config/routes.ts"() {
198
+ "use strict";
199
+ Path = __toESM(require("pathe"));
200
+ v = __toESM(require("valibot"));
201
+ import_pick = __toESM(require("lodash/pick"));
202
+ init_invariant();
203
+ routeConfigEntrySchema = v.pipe(
204
+ v.custom((value) => {
205
+ return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
206
+ }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
207
+ v.object({
208
+ id: v.optional(v.string()),
209
+ path: v.optional(v.string()),
210
+ index: v.optional(v.boolean()),
211
+ caseSensitive: v.optional(v.boolean()),
212
+ file: v.string(),
213
+ children: v.optional(v.array(v.lazy(() => routeConfigEntrySchema)))
214
+ })
215
+ );
216
+ resolvedRouteConfigSchema = v.array(routeConfigEntrySchema);
217
+ }
218
+ });
219
+
220
+ // cli/detectPackageManager.ts
221
+ var init_detectPackageManager = __esm({
222
+ "cli/detectPackageManager.ts"() {
223
+ "use strict";
224
+ }
225
+ });
226
+
227
+ // config/config.ts
228
+ function ok(value) {
229
+ return { ok: true, value };
230
+ }
231
+ function err(error) {
232
+ return { ok: false, error };
233
+ }
234
+ async function resolveConfig({
235
+ root,
236
+ viteNodeContext,
237
+ reactRouterConfigFile
238
+ }) {
239
+ let reactRouterUserConfig = {};
240
+ if (reactRouterConfigFile) {
241
+ try {
242
+ if (!import_node_fs.default.existsSync(reactRouterConfigFile)) {
243
+ return err(`${reactRouterConfigFile} no longer exists`);
244
+ }
245
+ let configModule = await viteNodeContext.runner.executeFile(
246
+ reactRouterConfigFile
247
+ );
248
+ if (configModule.default === void 0) {
249
+ return err(`${reactRouterConfigFile} must provide a default export`);
250
+ }
251
+ if (typeof configModule.default !== "object") {
252
+ return err(`${reactRouterConfigFile} must export a config`);
253
+ }
254
+ reactRouterUserConfig = configModule.default;
255
+ } catch (error) {
256
+ return err(`Error loading ${reactRouterConfigFile}: ${error}`);
257
+ }
258
+ }
259
+ reactRouterUserConfig = deepFreeze((0, import_cloneDeep.default)(reactRouterUserConfig));
260
+ let presets = (await Promise.all(
261
+ (reactRouterUserConfig.presets ?? []).map(async (preset) => {
262
+ if (!preset.name) {
263
+ throw new Error(
264
+ "React Router presets must have a `name` property defined."
265
+ );
266
+ }
267
+ if (!preset.reactRouterConfig) {
268
+ return null;
269
+ }
270
+ let configPreset = (0, import_omit.default)(
271
+ await preset.reactRouterConfig({ reactRouterUserConfig }),
272
+ excludedConfigPresetKeys
273
+ );
274
+ return configPreset;
275
+ })
276
+ )).filter(function isNotNull(value) {
277
+ return value !== null;
278
+ });
279
+ let defaults = {
280
+ basename: "/",
281
+ buildDirectory: "build",
282
+ serverBuildFile: "index.js",
283
+ serverModuleFormat: "esm",
284
+ ssr: true
285
+ };
286
+ let {
287
+ appDirectory: userAppDirectory,
288
+ basename: basename2,
289
+ buildDirectory: userBuildDirectory,
290
+ buildEnd,
291
+ prerender,
292
+ serverBuildFile,
293
+ serverBundles,
294
+ serverModuleFormat,
295
+ ssr
296
+ } = {
297
+ ...defaults,
298
+ // Default values should be completely overridden by user/preset config, not merged
299
+ ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
300
+ };
301
+ if (!ssr && serverBundles) {
302
+ serverBundles = void 0;
303
+ }
304
+ let isValidPrerenderConfig = prerender == null || typeof prerender === "boolean" || Array.isArray(prerender) || typeof prerender === "function";
305
+ if (!isValidPrerenderConfig) {
306
+ return err(
307
+ "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
308
+ );
309
+ }
310
+ let appDirectory = import_pathe.default.resolve(root, userAppDirectory || "app");
311
+ let buildDirectory = import_pathe.default.resolve(root, userBuildDirectory);
312
+ let rootRouteFile = findEntry(appDirectory, "root");
313
+ if (!rootRouteFile) {
314
+ let rootRouteDisplayPath = import_pathe.default.relative(
315
+ root,
316
+ import_pathe.default.join(appDirectory, "root.tsx")
317
+ );
318
+ return err(
319
+ `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
320
+ );
321
+ }
322
+ let routes2 = {
323
+ root: { path: "", id: "root", file: rootRouteFile }
324
+ };
325
+ let routeConfigFile = findEntry(appDirectory, "routes");
326
+ try {
327
+ if (!routeConfigFile) {
328
+ let routeConfigDisplayPath = import_pathe.default.relative(
329
+ root,
330
+ import_pathe.default.join(appDirectory, "routes.ts")
331
+ );
332
+ return err(`Route config file not found at "${routeConfigDisplayPath}".`);
333
+ }
334
+ setAppDirectory(appDirectory);
335
+ let routeConfigExport = (await viteNodeContext.runner.executeFile(
336
+ import_pathe.default.join(appDirectory, routeConfigFile)
337
+ )).default;
338
+ let routeConfig = await routeConfigExport;
339
+ let result = validateRouteConfig({
340
+ routeConfigFile,
341
+ routeConfig
342
+ });
343
+ if (!result.valid) {
344
+ return err(result.message);
345
+ }
346
+ routes2 = {
347
+ ...routes2,
348
+ ...configRoutesToRouteManifest(appDirectory, routeConfig)
349
+ };
350
+ } catch (error) {
351
+ return err(
352
+ [
353
+ import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
354
+ "",
355
+ error.loc?.file && error.loc?.column && error.frame ? [
356
+ import_pathe.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
357
+ error.frame.trim?.()
358
+ ] : error.stack
359
+ ].flat().join("\n")
360
+ );
361
+ }
362
+ let future = {
363
+ unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
364
+ };
365
+ let reactRouterConfig = deepFreeze({
366
+ appDirectory,
367
+ basename: basename2,
368
+ buildDirectory,
369
+ buildEnd,
370
+ future,
371
+ prerender,
372
+ routes: routes2,
373
+ serverBuildFile,
374
+ serverBundles,
375
+ serverModuleFormat,
376
+ ssr
377
+ });
378
+ for (let preset of reactRouterUserConfig.presets ?? []) {
379
+ await preset.reactRouterConfigResolved?.({ reactRouterConfig });
380
+ }
381
+ return ok(reactRouterConfig);
382
+ }
383
+ async function createConfigLoader({
384
+ rootDirectory: root,
385
+ watch: watch2
386
+ }) {
387
+ root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
388
+ let viteNodeContext = await createContext({
389
+ root,
390
+ mode: watch2 ? "development" : "production",
391
+ server: !watch2 ? { watch: null } : {},
392
+ ssr: {
393
+ external: ssrExternals
394
+ }
395
+ });
396
+ let reactRouterConfigFile = findEntry(root, "react-router.config", {
397
+ absolute: true
398
+ });
399
+ let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
400
+ let appDirectory;
401
+ let initialConfigResult = await getConfig();
402
+ if (!initialConfigResult.ok) {
403
+ throw new Error(initialConfigResult.error);
404
+ }
405
+ appDirectory = initialConfigResult.value.appDirectory;
406
+ let lastConfig = initialConfigResult.value;
407
+ let fsWatcher;
408
+ let changeHandlers = [];
409
+ return {
410
+ getConfig,
411
+ onChange: (handler) => {
412
+ if (!watch2) {
413
+ throw new Error(
414
+ "onChange is not supported when watch mode is disabled"
415
+ );
416
+ }
417
+ changeHandlers.push(handler);
418
+ if (!fsWatcher) {
419
+ fsWatcher = import_chokidar.default.watch(
420
+ [
421
+ ...reactRouterConfigFile ? [reactRouterConfigFile] : [],
422
+ appDirectory
423
+ ],
424
+ { ignoreInitial: true }
425
+ );
426
+ fsWatcher.on("all", async (...args) => {
427
+ let [event, rawFilepath] = args;
428
+ let filepath = import_pathe.default.normalize(rawFilepath);
429
+ let appFileAddedOrRemoved = appDirectory && (event === "add" || event === "unlink") && filepath.startsWith(import_pathe.default.normalize(appDirectory));
430
+ let configCodeUpdated = Boolean(
431
+ viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
432
+ );
433
+ if (configCodeUpdated || appFileAddedOrRemoved) {
434
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
435
+ viteNodeContext.runner?.moduleCache.clear();
436
+ }
437
+ if (appFileAddedOrRemoved || configCodeUpdated) {
438
+ let result = await getConfig();
439
+ let configChanged = result.ok && !(0, import_isEqual.default)(lastConfig, result.value);
440
+ let routeConfigChanged = result.ok && !(0, import_isEqual.default)(lastConfig?.routes, result.value.routes);
441
+ for (let handler2 of changeHandlers) {
442
+ handler2({
443
+ result,
444
+ configCodeUpdated,
445
+ configChanged,
446
+ routeConfigChanged,
447
+ path: filepath,
448
+ event
449
+ });
450
+ }
451
+ if (result.ok) {
452
+ lastConfig = result.value;
453
+ }
454
+ }
455
+ });
456
+ }
457
+ return () => {
458
+ changeHandlers = changeHandlers.filter(
459
+ (changeHandler) => changeHandler !== handler
460
+ );
461
+ };
462
+ },
463
+ close: async () => {
464
+ changeHandlers = [];
465
+ await viteNodeContext.devServer.close();
466
+ await fsWatcher?.close();
467
+ }
468
+ };
469
+ }
470
+ function isInReactRouterMonorepo() {
471
+ let serverRuntimePath = import_pathe.default.dirname(
472
+ require.resolve("@react-router/node/package.json")
473
+ );
474
+ let serverRuntimeParentDir = import_pathe.default.basename(
475
+ import_pathe.default.resolve(serverRuntimePath, "..")
476
+ );
477
+ return serverRuntimeParentDir === "packages";
478
+ }
479
+ function findEntry(dir, basename2, options) {
480
+ for (let ext of entryExts) {
481
+ let file = import_pathe.default.resolve(dir, basename2 + ext);
482
+ if (import_node_fs.default.existsSync(file)) {
483
+ return options?.absolute ?? false ? file : import_pathe.default.relative(dir, file);
484
+ }
485
+ }
486
+ return void 0;
487
+ }
488
+ var import_node_fs, import_node_child_process, import_package_json, import_pathe, import_chokidar, import_picocolors, import_pick2, import_omit, import_cloneDeep, import_isEqual, excludedConfigPresetKeys, branchRouteProperties, configRouteToBranchRoute, mergeReactRouterConfig, deepFreeze, ssrExternals, entryExts;
489
+ var init_config = __esm({
490
+ "config/config.ts"() {
491
+ "use strict";
492
+ import_node_fs = __toESM(require("fs"));
493
+ import_node_child_process = require("child_process");
494
+ import_package_json = __toESM(require("@npmcli/package-json"));
495
+ init_vite_node();
496
+ import_pathe = __toESM(require("pathe"));
497
+ import_chokidar = __toESM(require("chokidar"));
498
+ import_picocolors = __toESM(require("picocolors"));
499
+ import_pick2 = __toESM(require("lodash/pick"));
500
+ import_omit = __toESM(require("lodash/omit"));
501
+ import_cloneDeep = __toESM(require("lodash/cloneDeep"));
502
+ import_isEqual = __toESM(require("lodash/isEqual"));
503
+ init_routes();
504
+ init_detectPackageManager();
505
+ excludedConfigPresetKeys = ["presets"];
506
+ branchRouteProperties = [
507
+ "id",
508
+ "path",
509
+ "file",
510
+ "index"
511
+ ];
512
+ configRouteToBranchRoute = (configRoute) => (0, import_pick2.default)(configRoute, branchRouteProperties);
513
+ mergeReactRouterConfig = (...configs) => {
514
+ let reducer = (configA, configB) => {
515
+ let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
516
+ return {
517
+ ...configA,
518
+ ...configB,
519
+ ...mergeRequired("buildEnd") ? {
520
+ buildEnd: async (...args) => {
521
+ await Promise.all([
522
+ configA.buildEnd?.(...args),
523
+ configB.buildEnd?.(...args)
524
+ ]);
525
+ }
526
+ } : {},
527
+ ...mergeRequired("future") ? {
528
+ future: {
529
+ ...configA.future,
530
+ ...configB.future
531
+ }
532
+ } : {},
533
+ ...mergeRequired("presets") ? {
534
+ presets: [...configA.presets ?? [], ...configB.presets ?? []]
535
+ } : {}
536
+ };
537
+ };
538
+ return configs.reduce(reducer, {});
539
+ };
540
+ deepFreeze = (o) => {
541
+ Object.freeze(o);
542
+ let oIsFunction = typeof o === "function";
543
+ let hasOwnProp = Object.prototype.hasOwnProperty;
544
+ Object.getOwnPropertyNames(o).forEach(function(prop) {
545
+ 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])) {
546
+ deepFreeze(o[prop]);
547
+ }
548
+ });
549
+ return o;
550
+ };
551
+ ssrExternals = isInReactRouterMonorepo() ? [
552
+ // This is only needed within this repo because these packages
553
+ // are linked to a directory outside of node_modules so Vite
554
+ // treats them as internal code by default.
555
+ "react-router",
556
+ "react-router-dom",
557
+ "@react-router/architect",
558
+ "@react-router/cloudflare",
559
+ "@react-router/dev",
560
+ "@react-router/express",
561
+ "@react-router/node",
562
+ "@react-router/serve"
563
+ ] : void 0;
564
+ entryExts = [".js", ".jsx", ".ts", ".tsx"];
565
+ }
566
+ });
567
+
568
+ // typegen/paths.ts
569
+ function getTypesDir(ctx) {
570
+ return Path2.join(ctx.rootDirectory, ".react-router/types");
571
+ }
572
+ function getTypesPath(ctx, route) {
573
+ return Path2.join(
574
+ getTypesDir(ctx),
575
+ Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
576
+ Path2.dirname(route.file),
577
+ "+types/" + Pathe.filename(route.file) + ".ts"
578
+ );
579
+ }
580
+ var Path2, Pathe;
581
+ var init_paths = __esm({
582
+ "typegen/paths.ts"() {
583
+ "use strict";
584
+ Path2 = __toESM(require("pathe"));
585
+ Pathe = __toESM(require("pathe/utils"));
586
+ }
587
+ });
588
+
589
+ // typegen/generate.ts
590
+ function generate(ctx, route) {
591
+ const lineage = getRouteLineage(ctx.config.routes, route);
592
+ const urlpath = lineage.map((route2) => route2.path).join("/");
593
+ const typesPath = getTypesPath(ctx, route);
594
+ const parents = lineage.slice(0, -1);
595
+ const parentTypeImports = parents.map((parent, i) => {
596
+ const rel = Path3.relative(
597
+ Path3.dirname(typesPath),
598
+ getTypesPath(ctx, parent)
599
+ );
600
+ const indent = i === 0 ? "" : " ".repeat(2);
601
+ let source = noExtension(rel);
602
+ if (!source.startsWith("../")) source = "./" + source;
603
+ return `${indent}import type { Info as Parent${i} } from "${source}"`;
604
+ }).join("\n");
605
+ return import_dedent.default`
606
+ // React Router generated types for route:
607
+ // ${route.file}
608
+
609
+ import type * as T from "react-router/route-module"
610
+
611
+ ${parentTypeImports}
612
+
613
+ type Module = typeof import("../${Pathe2.filename(route.file)}")
614
+
615
+ export type Info = {
616
+ parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
617
+ id: "${route.id}"
618
+ file: "${route.file}"
619
+ path: "${route.path}"
620
+ params: {${formatParamProperties(urlpath)}}
621
+ module: Module
622
+ loaderData: T.CreateLoaderData<Module>
623
+ actionData: T.CreateActionData<Module>
624
+ }
625
+
626
+ export namespace Route {
627
+ export type LinkDescriptors = T.LinkDescriptors
628
+ export type LinksFunction = () => LinkDescriptors
629
+
630
+ export type MetaArgs = T.CreateMetaArgs<Info>
631
+ export type MetaDescriptors = T.MetaDescriptors
632
+ export type MetaFunction = (args: MetaArgs) => MetaDescriptors
633
+
634
+ export type LoaderArgs = T.CreateServerLoaderArgs<Info>
635
+ export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
636
+ export type ActionArgs = T.CreateServerActionArgs<Info>
637
+ export type ClientActionArgs = T.CreateClientActionArgs<Info>
638
+
639
+ export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Info>
640
+ export type ComponentProps = T.CreateComponentProps<Info>
641
+ export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Info>
642
+ }
643
+ `;
644
+ }
645
+ function getRouteLineage(routes2, route) {
646
+ const result = [];
647
+ while (route) {
648
+ result.push(route);
649
+ if (!route.parentId) break;
650
+ route = routes2[route.parentId];
651
+ }
652
+ result.reverse();
653
+ return result;
654
+ }
655
+ function formatParamProperties(urlpath) {
656
+ const params = parseParams(urlpath);
657
+ const properties = Object.entries(params).map(([name, values]) => {
658
+ if (values.length === 1) {
659
+ const isOptional = values[0];
660
+ return isOptional ? `"${name}"?: string` : `"${name}": string`;
661
+ }
662
+ const items = values.map(
663
+ (isOptional) => isOptional ? "string | undefined" : "string"
664
+ );
665
+ return `"${name}": [${items.join(", ")}]`;
666
+ });
667
+ return properties.join("; ");
668
+ }
669
+ function parseParams(urlpath) {
670
+ const result = {};
671
+ let segments = urlpath.split("/");
672
+ segments.forEach((segment) => {
673
+ const match = segment.match(/^:([\w-]+)(\?)?/);
674
+ if (!match) return;
675
+ const param = match[1];
676
+ const isOptional = match[2] !== void 0;
677
+ result[param] ??= [];
678
+ result[param].push(isOptional);
679
+ return;
680
+ });
681
+ const hasSplat = segments.at(-1) === "*";
682
+ if (hasSplat) result["*"] = [false];
683
+ return result;
684
+ }
685
+ var import_dedent, Path3, Pathe2, noExtension;
686
+ var init_generate = __esm({
687
+ "typegen/generate.ts"() {
688
+ "use strict";
689
+ import_dedent = __toESM(require("dedent"));
690
+ Path3 = __toESM(require("pathe"));
691
+ Pathe2 = __toESM(require("pathe/utils"));
692
+ init_paths();
693
+ noExtension = (path8) => Path3.join(Path3.dirname(path8), Pathe2.filename(path8));
694
+ }
695
+ });
696
+
697
+ // typegen/index.ts
698
+ async function run(rootDirectory) {
699
+ const ctx = await createContext2({ rootDirectory, watch: false });
700
+ await writeAll(ctx);
701
+ }
702
+ async function watch(rootDirectory, { logger } = {}) {
703
+ const ctx = await createContext2({ rootDirectory, watch: true });
704
+ await writeAll(ctx);
705
+ logger?.info(import_picocolors2.default.green("generated types"), { timestamp: true, clear: true });
706
+ ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
707
+ if (!result.ok) {
708
+ logger?.error(import_picocolors2.default.red(result.error), { timestamp: true, clear: true });
709
+ return;
710
+ }
711
+ ctx.config = result.value;
712
+ if (routeConfigChanged) {
713
+ await writeAll(ctx);
714
+ logger?.info(import_picocolors2.default.green("regenerated types"), {
715
+ timestamp: true,
716
+ clear: true
717
+ });
718
+ }
719
+ });
720
+ }
721
+ async function createContext2({
722
+ rootDirectory,
723
+ watch: watch2
724
+ }) {
725
+ const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
726
+ const configResult = await configLoader.getConfig();
727
+ if (!configResult.ok) {
728
+ throw new Error(configResult.error);
729
+ }
730
+ const config = configResult.value;
731
+ return {
732
+ configLoader,
733
+ rootDirectory,
734
+ config
735
+ };
736
+ }
737
+ async function writeAll(ctx) {
738
+ const typegenDir = getTypesDir(ctx);
739
+ import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
740
+ Object.values(ctx.config.routes).forEach((route) => {
741
+ const typesPath = getTypesPath(ctx, route);
742
+ const content = generate(ctx, route);
743
+ import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
744
+ import_node_fs2.default.writeFileSync(typesPath, content);
745
+ });
746
+ }
747
+ var import_node_fs2, Path4, import_picocolors2;
748
+ var init_typegen = __esm({
749
+ "typegen/index.ts"() {
750
+ "use strict";
751
+ import_node_fs2 = __toESM(require("fs"));
752
+ Path4 = __toESM(require("pathe"));
753
+ import_picocolors2 = __toESM(require("picocolors"));
754
+ init_config();
755
+ init_generate();
756
+ init_paths();
757
+ }
758
+ });
759
+
760
+ // vite/babel.ts
761
+ var import_parser, t, traverse, generate2;
762
+ var init_babel = __esm({
763
+ "vite/babel.ts"() {
764
+ "use strict";
765
+ import_parser = require("@babel/parser");
766
+ t = __toESM(require("@babel/types"));
767
+ traverse = require("@babel/traverse").default;
768
+ generate2 = require("@babel/generator").default;
769
+ }
770
+ });
771
+
772
+ // vite/node-adapter.ts
773
+ var import_node_events, import_node_stream, import_set_cookie_parser, import_node;
774
+ var init_node_adapter = __esm({
775
+ "vite/node-adapter.ts"() {
776
+ "use strict";
777
+ import_node_events = require("events");
778
+ import_node_stream = require("stream");
779
+ import_set_cookie_parser = require("set-cookie-parser");
780
+ import_node = require("@react-router/node");
781
+ init_invariant();
782
+ }
783
+ });
784
+
785
+ // vite/resolve-file-url.ts
786
+ var path2;
787
+ var init_resolve_file_url = __esm({
788
+ "vite/resolve-file-url.ts"() {
789
+ "use strict";
790
+ path2 = __toESM(require("path"));
791
+ init_import_vite_esm_sync();
175
792
  }
176
- return routeManifest;
177
- }
178
- function createRouteId(file) {
179
- return normalizeSlashes(stripFileExtension(file));
180
- }
181
- function normalizeSlashes(file) {
182
- return file.split(import_node_path.win32.sep).join("/");
183
- }
184
- function stripFileExtension(file) {
185
- return file.replace(/\.[a-z0-9]+$/i, "");
186
- }
187
- var import_node_path, v, import_pick, routeConfigEntrySchema, resolvedRouteConfigSchema;
188
- var init_routes = __esm({
189
- "config/routes.ts"() {
793
+ });
794
+
795
+ // vite/styles.ts
796
+ var path3, import_react_router, cssFileRegExp, cssModulesRegExp;
797
+ var init_styles = __esm({
798
+ "vite/styles.ts"() {
190
799
  "use strict";
191
- import_node_path = require("path");
192
- v = __toESM(require("valibot"));
193
- import_pick = __toESM(require("lodash/pick"));
194
- init_invariant();
195
- routeConfigEntrySchema = v.pipe(
196
- v.custom((value) => {
197
- return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
198
- }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
199
- v.object({
200
- id: v.optional(v.string()),
201
- path: v.optional(v.string()),
202
- index: v.optional(v.boolean()),
203
- caseSensitive: v.optional(v.boolean()),
204
- file: v.string(),
205
- children: v.optional(v.array(v.lazy(() => routeConfigEntrySchema)))
206
- })
207
- );
208
- resolvedRouteConfigSchema = v.array(routeConfigEntrySchema);
800
+ path3 = __toESM(require("path"));
801
+ import_react_router = require("react-router");
802
+ init_resolve_file_url();
803
+ cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
804
+ cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
209
805
  }
210
806
  });
211
807
 
212
- // cli/detectPackageManager.ts
213
- var init_detectPackageManager = __esm({
214
- "cli/detectPackageManager.ts"() {
808
+ // vite/vmod.ts
809
+ var id;
810
+ var init_vmod = __esm({
811
+ "vite/vmod.ts"() {
215
812
  "use strict";
813
+ id = (name) => `virtual:react-router/${name}`;
216
814
  }
217
815
  });
218
816
 
219
- // vite/config.ts
220
- function findEntry(dir, basename2) {
221
- for (let ext of entryExts) {
222
- let file = import_node_path2.default.resolve(dir, basename2 + ext);
223
- if (import_fs_extra.default.existsSync(file)) return import_node_path2.default.relative(dir, file);
817
+ // vite/combine-urls.ts
818
+ var init_combine_urls = __esm({
819
+ "vite/combine-urls.ts"() {
820
+ "use strict";
224
821
  }
225
- return void 0;
226
- }
227
- var import_node_child_process, import_node_path2, import_fs_extra, import_picocolors, import_pick2, import_omit, import_package_json, branchRouteProperties, configRouteToBranchRoute, entryExts;
228
- var init_config = __esm({
229
- "vite/config.ts"() {
822
+ });
823
+
824
+ // vite/remove-exports.ts
825
+ var import_babel_dead_code_elimination;
826
+ var init_remove_exports = __esm({
827
+ "vite/remove-exports.ts"() {
230
828
  "use strict";
231
- import_node_child_process = require("child_process");
232
- import_node_path2 = __toESM(require("path"));
233
- import_fs_extra = __toESM(require("fs-extra"));
234
- import_picocolors = __toESM(require("picocolors"));
235
- import_pick2 = __toESM(require("lodash/pick"));
236
- import_omit = __toESM(require("lodash/omit"));
237
- import_package_json = __toESM(require("@npmcli/package-json"));
238
- init_routes();
239
- init_detectPackageManager();
240
- init_import_vite_esm_sync();
241
- branchRouteProperties = [
242
- "id",
243
- "path",
244
- "file",
245
- "index"
246
- ];
247
- configRouteToBranchRoute = (configRoute) => (0, import_pick2.default)(configRoute, branchRouteProperties);
248
- entryExts = [".js", ".jsx", ".ts", ".tsx"];
829
+ import_babel_dead_code_elimination = require("babel-dead-code-elimination");
830
+ init_babel();
249
831
  }
250
832
  });
251
833
 
252
834
  // vite/with-props.ts
253
- var import_dedent, vmodId;
835
+ var import_dedent2, vmodId;
254
836
  var init_with_props = __esm({
255
837
  "vite/with-props.ts"() {
256
838
  "use strict";
257
- import_dedent = __toESM(require("dedent"));
839
+ import_dedent2 = __toESM(require("dedent"));
258
840
  init_babel();
259
841
  init_vmod();
260
842
  vmodId = id("with-props");
261
843
  }
262
844
  });
263
845
 
264
- // vite/vite-node.ts
265
- async function createContext(viteConfig = {}) {
266
- await preloadViteEsm();
267
- const vite2 = importViteEsmSync();
268
- const devServer = await vite2.createServer(
269
- vite2.mergeConfig(
270
- {
271
- server: {
272
- preTransformRequests: false,
273
- hmr: false
274
- },
275
- optimizeDeps: {
276
- noDiscovery: true
277
- },
278
- configFile: false,
279
- envFile: false,
280
- plugins: []
281
- },
282
- viteConfig
283
- )
284
- );
285
- await devServer.pluginContainer.buildStart({});
286
- const server = new import_server.ViteNodeServer(devServer);
287
- (0, import_source_map.installSourcemapsSupport)({
288
- getSourceMap: (source) => server.getSourceMap(source)
289
- });
290
- const runner = new import_client.ViteNodeRunner({
291
- root: devServer.config.root,
292
- base: devServer.config.base,
293
- fetchModule(id2) {
294
- return server.fetchModule(id2);
295
- },
296
- resolveId(id2, importer) {
297
- return server.resolveId(id2, importer);
298
- }
299
- });
300
- return { devServer, server, runner };
301
- }
302
- var import_server, import_client, import_source_map;
303
- var init_vite_node = __esm({
304
- "vite/vite-node.ts"() {
305
- "use strict";
306
- import_server = require("vite-node/server");
307
- import_client = require("vite-node/client");
308
- import_source_map = require("vite-node/source-map");
309
- init_import_vite_esm_sync();
310
- }
311
- });
312
-
313
846
  // vite/plugin.ts
314
847
  async function resolveViteConfig({
315
848
  configFile,
@@ -350,14 +883,14 @@ async function loadPluginContext({
350
883
  ".mjs"
351
884
  ]);
352
885
  if (!configFile) {
353
- console.error(import_picocolors2.default.red("Vite config file not found"));
886
+ console.error(import_picocolors3.default.red("Vite config file not found"));
354
887
  process.exit(1);
355
888
  }
356
889
  let viteConfig = await resolveViteConfig({ configFile, root });
357
890
  let ctx = await extractPluginContext(viteConfig);
358
891
  if (!ctx) {
359
892
  console.error(
360
- import_picocolors2.default.red("React Router Vite plugin not found in Vite config")
893
+ import_picocolors3.default.red("React Router Vite plugin not found in Vite config")
361
894
  );
362
895
  process.exit(1);
363
896
  }
@@ -367,23 +900,24 @@ function findConfig(dir, basename2, extensions) {
367
900
  for (let ext of extensions) {
368
901
  let name = basename2 + ext;
369
902
  let file = path4.join(dir, name);
370
- if (fse2.existsSync(file)) return file;
903
+ if (fse.existsSync(file)) return file;
371
904
  }
372
905
  return void 0;
373
906
  }
374
- var import_node_crypto, path4, url, fse2, babel, import_react_router2, import_es_module_lexer, import_jsesc, import_picocolors2, serverBuildId, serverManifestId, browserManifestId, hmrRuntimeId, injectHmrRuntimeId, getServerBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER, REACT_REFRESH_FOOTER;
907
+ var import_node_crypto, path4, url, fse, babel, import_react_router2, import_es_module_lexer, import_jsesc, import_picocolors3, serverBuildId, serverManifestId, browserManifestId, hmrRuntimeId, injectHmrRuntimeId, getServerBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER, REACT_REFRESH_FOOTER;
375
908
  var init_plugin = __esm({
376
909
  "vite/plugin.ts"() {
377
910
  "use strict";
378
911
  import_node_crypto = require("crypto");
379
912
  path4 = __toESM(require("path"));
380
913
  url = __toESM(require("url"));
381
- fse2 = __toESM(require("fs-extra"));
914
+ fse = __toESM(require("fs-extra"));
382
915
  babel = __toESM(require("@babel/core"));
383
916
  import_react_router2 = require("react-router");
384
917
  import_es_module_lexer = require("es-module-lexer");
385
918
  import_jsesc = __toESM(require("jsesc"));
386
- import_picocolors2 = __toESM(require("picocolors"));
919
+ import_picocolors3 = __toESM(require("picocolors"));
920
+ init_typegen();
387
921
  init_invariant();
388
922
  init_babel();
389
923
  init_node_adapter();
@@ -395,7 +929,6 @@ var init_plugin = __esm({
395
929
  init_import_vite_esm_sync();
396
930
  init_config();
397
931
  init_with_props();
398
- init_vite_node();
399
932
  serverBuildId = id("server-build");
400
933
  serverManifestId = id("server-manifest");
401
934
  browserManifestId = id("browser-manifest");
@@ -412,7 +945,7 @@ var init_plugin = __esm({
412
945
  "config",
413
946
  "defaults"
414
947
  );
415
- defaultEntries = fse2.readdirSync(defaultEntriesDir).map((filename3) => path4.join(defaultEntriesDir, filename3));
948
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path4.join(defaultEntriesDir, filename3));
416
949
  invariant(defaultEntries.length > 0, "No default entries found");
417
950
  REACT_REFRESH_HEADER = `
418
951
  import RefreshRuntime from "${hmrRuntimeId}";
@@ -453,13 +986,13 @@ if (import.meta.hot && !inWebWorker) {
453
986
  });
454
987
 
455
988
  // vite/profiler.ts
456
- var import_node_fs, import_node_path3, import_picocolors3, getSession, start, profileCount, stop;
989
+ var import_node_fs3, import_node_path, import_picocolors4, getSession, start, profileCount, stop;
457
990
  var init_profiler = __esm({
458
991
  "vite/profiler.ts"() {
459
992
  "use strict";
460
- import_node_fs = __toESM(require("fs"));
461
- import_node_path3 = __toESM(require("path"));
462
- import_picocolors3 = __toESM(require("picocolors"));
993
+ import_node_fs3 = __toESM(require("fs"));
994
+ import_node_path = __toESM(require("path"));
995
+ import_picocolors4 = __toESM(require("picocolors"));
463
996
  getSession = () => global.__reactRouter_profile_session;
464
997
  start = async (callback) => {
465
998
  let inspector = await import("inspector").then((r) => r.default);
@@ -470,17 +1003,17 @@ var init_profiler = __esm({
470
1003
  });
471
1004
  };
472
1005
  profileCount = 0;
473
- stop = (log2) => {
1006
+ stop = (log) => {
474
1007
  let session = getSession();
475
1008
  if (!session) return;
476
1009
  return new Promise((res, rej) => {
477
- session.post("Profiler.stop", (err, { profile }) => {
478
- if (err) return rej(err);
479
- let outPath = import_node_path3.default.resolve(`./react-router-${profileCount++}.cpuprofile`);
480
- import_node_fs.default.writeFileSync(outPath, JSON.stringify(profile));
481
- log2(
482
- import_picocolors3.default.yellow(
483
- `CPU profile written to ${import_picocolors3.default.white(import_picocolors3.default.dim(outPath))}`
1010
+ session.post("Profiler.stop", (err2, { profile }) => {
1011
+ if (err2) return rej(err2);
1012
+ let outPath = import_node_path.default.resolve(`./react-router-${profileCount++}.cpuprofile`);
1013
+ import_node_fs3.default.writeFileSync(outPath, JSON.stringify(profile));
1014
+ log(
1015
+ import_picocolors4.default.yellow(
1016
+ `CPU profile written to ${import_picocolors4.default.white(import_picocolors4.default.dim(outPath))}`
484
1017
  )
485
1018
  );
486
1019
  global.__reactRouter_profile_session = void 0;
@@ -537,12 +1070,12 @@ async function getServerBuilds(ctx) {
537
1070
  };
538
1071
  }
539
1072
  let { normalizePath } = await import("vite");
540
- let resolvedAppDirectory = import_node_path4.default.resolve(rootDirectory, appDirectory);
1073
+ let resolvedAppDirectory = import_node_path2.default.resolve(rootDirectory, appDirectory);
541
1074
  let rootRelativeRoutes = Object.fromEntries(
542
1075
  Object.entries(routes2).map(([id2, route]) => {
543
- let filePath = import_node_path4.default.join(resolvedAppDirectory, route.file);
1076
+ let filePath = import_node_path2.default.join(resolvedAppDirectory, route.file);
544
1077
  let rootRelativeFilePath = normalizePath(
545
- import_node_path4.default.relative(rootDirectory, filePath)
1078
+ import_node_path2.default.relative(rootDirectory, filePath)
546
1079
  );
547
1080
  return [id2, { ...route, file: rootRelativeFilePath }];
548
1081
  })
@@ -561,7 +1094,7 @@ async function getServerBuilds(ctx) {
561
1094
  (route2) => configRouteToBranchRoute({
562
1095
  ...route2,
563
1096
  // Ensure absolute paths are passed to the serverBundles function
564
- file: import_node_path4.default.join(resolvedAppDirectory, route2.file)
1097
+ file: import_node_path2.default.join(resolvedAppDirectory, route2.file)
565
1098
  })
566
1099
  )
567
1100
  });
@@ -574,16 +1107,16 @@ async function getServerBuilds(ctx) {
574
1107
  );
575
1108
  }
576
1109
  buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;
577
- let relativeServerBundleDirectory = import_node_path4.default.relative(
1110
+ let relativeServerBundleDirectory = import_node_path2.default.relative(
578
1111
  rootDirectory,
579
- import_node_path4.default.join(serverBuildDirectory, serverBundleId)
1112
+ import_node_path2.default.join(serverBuildDirectory, serverBundleId)
580
1113
  );
581
1114
  let serverBuildConfig = serverBundleBuildConfigById.get(serverBundleId);
582
1115
  if (!serverBuildConfig) {
583
1116
  buildManifest.serverBundles[serverBundleId] = {
584
1117
  id: serverBundleId,
585
1118
  file: normalizePath(
586
- import_node_path4.default.join(relativeServerBundleDirectory, serverBuildFile)
1119
+ import_node_path2.default.join(relativeServerBundleDirectory, serverBuildFile)
587
1120
  )
588
1121
  };
589
1122
  serverBuildConfig = {
@@ -614,15 +1147,15 @@ async function getServerBuilds(ctx) {
614
1147
  async function cleanBuildDirectory(viteConfig, ctx) {
615
1148
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
616
1149
  let isWithinRoot = () => {
617
- let relativePath = import_node_path4.default.relative(ctx.rootDirectory, buildDirectory);
618
- return !relativePath.startsWith("..") && !import_node_path4.default.isAbsolute(relativePath);
1150
+ let relativePath = import_node_path2.default.relative(ctx.rootDirectory, buildDirectory);
1151
+ return !relativePath.startsWith("..") && !import_node_path2.default.isAbsolute(relativePath);
619
1152
  };
620
1153
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
621
- await import_fs_extra2.default.remove(buildDirectory);
1154
+ await import_fs_extra.default.remove(buildDirectory);
622
1155
  }
623
1156
  }
624
1157
  function getViteManifestPaths(ctx, serverBuilds) {
625
- let buildRelative = (pathname) => import_node_path4.default.resolve(ctx.reactRouterConfig.buildDirectory, pathname);
1158
+ let buildRelative = (pathname) => import_node_path2.default.resolve(ctx.reactRouterConfig.buildDirectory, pathname);
626
1159
  let viteManifestPaths = [
627
1160
  "client/.vite/manifest.json",
628
1161
  ...serverBuilds.map(({ serverBundleBuildConfig }) => {
@@ -650,7 +1183,7 @@ async function build(root, {
650
1183
  const ctx = await extractPluginContext(viteConfig);
651
1184
  if (!ctx) {
652
1185
  console.error(
653
- import_picocolors6.default.red("React Router Vite plugin not found in Vite config")
1186
+ import_picocolors5.default.red("React Router Vite plugin not found in Vite config")
654
1187
  );
655
1188
  process.exit(1);
656
1189
  }
@@ -684,15 +1217,15 @@ async function build(root, {
684
1217
  let viteManifestPaths = getViteManifestPaths(ctx, serverBuilds);
685
1218
  await Promise.all(
686
1219
  viteManifestPaths.map(async (viteManifestPath) => {
687
- let manifestExists = await import_fs_extra2.default.pathExists(viteManifestPath);
1220
+ let manifestExists = await import_fs_extra.default.pathExists(viteManifestPath);
688
1221
  if (!manifestExists) return;
689
1222
  if (!ctx.viteManifestEnabled) {
690
- await import_fs_extra2.default.remove(viteManifestPath);
1223
+ await import_fs_extra.default.remove(viteManifestPath);
691
1224
  }
692
- let viteDir = import_node_path4.default.dirname(viteManifestPath);
693
- let viteDirFiles = await import_fs_extra2.default.readdir(viteDir);
1225
+ let viteDir = import_node_path2.default.dirname(viteManifestPath);
1226
+ let viteDirFiles = await import_fs_extra.default.readdir(viteDir);
694
1227
  if (viteDirFiles.length === 0) {
695
- await import_fs_extra2.default.remove(viteDir);
1228
+ await import_fs_extra.default.remove(viteDir);
696
1229
  }
697
1230
  })
698
1231
  );
@@ -702,13 +1235,13 @@ async function build(root, {
702
1235
  viteConfig
703
1236
  });
704
1237
  }
705
- var import_node_path4, import_fs_extra2, import_picocolors6;
1238
+ var import_node_path2, import_fs_extra, import_picocolors5;
706
1239
  var init_build = __esm({
707
1240
  "vite/build.ts"() {
708
1241
  "use strict";
709
- import_node_path4 = __toESM(require("path"));
710
- import_fs_extra2 = __toESM(require("fs-extra"));
711
- import_picocolors6 = __toESM(require("picocolors"));
1242
+ import_node_path2 = __toESM(require("path"));
1243
+ import_fs_extra = __toESM(require("fs-extra"));
1244
+ import_picocolors5 = __toESM(require("picocolors"));
712
1245
  init_plugin();
713
1246
  init_config();
714
1247
  init_invariant();
@@ -746,7 +1279,7 @@ async function dev(root, {
746
1279
  });
747
1280
  if (!server.config.plugins.find((plugin2) => plugin2.name === "react-router")) {
748
1281
  console.error(
749
- import_picocolors7.default.red("React Router Vite plugin not found in Vite config")
1282
+ import_picocolors6.default.red("React Router Vite plugin not found in Vite config")
750
1283
  );
751
1284
  process.exit(1);
752
1285
  }
@@ -769,11 +1302,11 @@ async function dev(root, {
769
1302
  ];
770
1303
  server.bindCLIShortcuts({ print: true, customShortcuts });
771
1304
  }
772
- var import_picocolors7;
1305
+ var import_picocolors6;
773
1306
  var init_dev = __esm({
774
1307
  "vite/dev.ts"() {
775
1308
  "use strict";
776
- import_picocolors7 = __toESM(require("picocolors"));
1309
+ import_picocolors6 = __toESM(require("picocolors"));
777
1310
  init_import_vite_esm_sync();
778
1311
  init_profiler();
779
1312
  }
@@ -782,14 +1315,14 @@ var init_dev = __esm({
782
1315
  // cli/run.ts
783
1316
  var import_arg = __toESM(require("arg"));
784
1317
  var import_semver = __toESM(require("semver"));
785
- var import_picocolors9 = __toESM(require("picocolors"));
1318
+ var import_picocolors8 = __toESM(require("picocolors"));
786
1319
 
787
1320
  // cli/commands.ts
788
1321
  var path7 = __toESM(require("path"));
789
- var import_fs_extra3 = __toESM(require("fs-extra"));
1322
+ var import_fs_extra2 = __toESM(require("fs-extra"));
790
1323
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
791
1324
  var import_exit_hook = __toESM(require("exit-hook"));
792
- var import_picocolors8 = __toESM(require("picocolors"));
1325
+ var import_picocolors7 = __toESM(require("picocolors"));
793
1326
 
794
1327
  // config/format.ts
795
1328
  function formatRoutes(routeManifest, format) {
@@ -870,231 +1403,8 @@ function transpile(tsx, options = {}) {
870
1403
 
871
1404
  // cli/commands.ts
872
1405
  init_profiler();
873
-
874
- // typegen/index.ts
875
- var import_node_fs2 = __toESM(require("fs"));
876
- var import_chokidar = __toESM(require("chokidar"));
877
- var Path = __toESM(require("pathe"));
878
- var Pathe2 = __toESM(require("pathe/utils"));
879
- var import_picocolors5 = __toESM(require("picocolors"));
880
-
881
- // logger.ts
882
- var import_picocolors4 = __toESM(require("picocolors"));
883
- var DATE_TIME_FORMAT = new Intl.DateTimeFormat([], {
884
- hour: "2-digit",
885
- minute: "2-digit",
886
- second: "2-digit",
887
- hour12: false
888
- });
889
- var log = (level) => (body, options = {}) => {
890
- const dest = level === "error" ? process.stderr : process.stdout;
891
- let message = getPrefix(level, options) + " " + body;
892
- if (options.durationMs) {
893
- const duration = options.durationMs < 1e3 ? `${Math.round(options.durationMs)}ms` : `${(options.durationMs / 1e3).toFixed(2)}s`;
894
- message += " " + import_picocolors4.default.dim(duration);
895
- }
896
- dest.write(message + "\n");
897
- };
898
- function getPrefix(level, options) {
899
- const timestamp = `${DATE_TIME_FORMAT.format(/* @__PURE__ */ new Date())}`;
900
- const prefix = [];
901
- if (level === "error" || level === "warn") {
902
- prefix.push(import_picocolors4.default.bold(timestamp));
903
- prefix.push(`[${level.toUpperCase()}]`);
904
- } else {
905
- prefix.push(timestamp);
906
- }
907
- if (options.label) {
908
- prefix.push(`[${options.label}]`);
909
- }
910
- if (level === "error") return import_picocolors4.default.red(prefix.join(" "));
911
- if (level === "warn") return import_picocolors4.default.yellow(prefix.join(" "));
912
- if (prefix.length === 1) return import_picocolors4.default.dim(prefix[0]);
913
- return import_picocolors4.default.dim(prefix[0]) + " " + import_picocolors4.default.blue(prefix.splice(1).join(" "));
914
- }
915
- var info = log("info");
916
- var warn = log("warn");
917
- var error = log("error");
918
-
919
- // typegen/index.ts
920
- init_routes();
921
- init_vite_node();
922
- init_config();
923
- init_plugin();
924
-
925
- // typegen/generate.ts
926
- var import_dedent2 = __toESM(require("dedent"));
927
- var Pathe = __toESM(require("pathe/utils"));
928
- function generate2(routes2, route) {
929
- return import_dedent2.default`
930
- // React Router generated types for route:
931
- // ${route.file}
932
-
933
- import * as T from "react-router/types"
934
-
935
- export type Params = {${formatParamProperties(routes2, route)}}
936
-
937
- type RouteModule = typeof import("./${Pathe.filename(route.file)}")
938
-
939
- export namespace Route {
940
- export type LoaderData = T.CreateLoaderData<RouteModule>
941
- export type ActionData = T.CreateActionData<RouteModule>
942
-
943
- export type LoaderArgs = T.CreateServerLoaderArgs<Params>
944
- export type ClientLoaderArgs = T.CreateClientLoaderArgs<Params, RouteModule>
945
- export type ActionArgs = T.CreateServerActionArgs<Params>
946
- export type ClientActionArgs = T.CreateClientActionArgs<Params, RouteModule>
947
-
948
- export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Params>
949
- export type ComponentProps = T.CreateComponentProps<Params, LoaderData, ActionData>
950
- export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Params, LoaderData, ActionData>
951
- }
952
- `;
953
- }
954
- function formatParamProperties(routes2, route) {
955
- const urlpath = getRouteLineage(routes2, route).map((route2) => route2.path).join("/");
956
- const params = parseParams(urlpath);
957
- const indent = " ".repeat(3);
958
- const properties = Object.entries(params).map(([name, values]) => {
959
- if (values.length === 1) {
960
- const isOptional = values[0];
961
- return indent + (isOptional ? `"${name}"?: string` : `"${name}": string`);
962
- }
963
- const items = values.map(
964
- (isOptional) => isOptional ? "string | undefined" : "string"
965
- );
966
- return indent + `"${name}": [${items.join(", ")}]`;
967
- });
968
- const body = properties.length === 0 ? "" : "\n" + properties.join("\n") + "\n";
969
- return body;
970
- }
971
- function getRouteLineage(routes2, route) {
972
- const result = [];
973
- while (route) {
974
- result.push(route);
975
- if (!route.parentId) break;
976
- route = routes2[route.parentId];
977
- }
978
- result.reverse();
979
- return result;
980
- }
981
- function parseParams(urlpath) {
982
- const result = {};
983
- let segments = urlpath.split("/");
984
- segments.forEach((segment) => {
985
- const match = segment.match(/^:([\w-]+)(\?)?/);
986
- if (!match) return;
987
- const param = match[1];
988
- const isOptional = match[2] !== void 0;
989
- result[param] ??= [];
990
- result[param].push(isOptional);
991
- return;
992
- });
993
- const hasSplat = segments.at(-1) === "*";
994
- if (hasSplat) result["*"] = [false];
995
- return result;
996
- }
997
-
998
- // typegen/index.ts
999
- async function run(rootDirectory, configFile) {
1000
- const ctx = await createContext2(rootDirectory, configFile);
1001
- await writeAll(ctx);
1002
- }
1003
- async function watch(rootDirectory, configFile) {
1004
- const watchStart = performance.now();
1005
- const ctx = await createContext2(rootDirectory, configFile);
1006
- await writeAll(ctx);
1007
- info("generated initial types", {
1008
- durationMs: performance.now() - watchStart
1009
- });
1010
- const watcher = import_chokidar.default.watch(ctx.appDirectory, { ignoreInitial: true });
1011
- watcher.on("all", async (event, path8) => {
1012
- path8 = Path.normalize(path8);
1013
- const eventStart = performance.now();
1014
- const didRouteConfigChange = Boolean(
1015
- ctx.routeConfigEnv.devServer.moduleGraph.getModuleById(path8)
1016
- );
1017
- if (didRouteConfigChange) {
1018
- await writeAll(ctx);
1019
- info("changed route config", {
1020
- durationMs: performance.now() - eventStart
1021
- });
1022
- return;
1023
- }
1024
- ctx.routes = await getRoutes(ctx);
1025
- const route = findRoute(ctx, path8);
1026
- if (route && (event === "add" || event === "unlink")) {
1027
- await writeAll(ctx);
1028
- info(
1029
- `${event === "add" ? "added" : "removed"} route ${import_picocolors5.default.blue(route.file)}`,
1030
- { durationMs: performance.now() - eventStart }
1031
- );
1032
- return;
1033
- }
1034
- });
1035
- }
1036
- async function createContext2(rootDirectory, configFile) {
1037
- const appDirectory = await getAppDirectory(rootDirectory, configFile);
1038
- const routeConfigEnv = await createContext({
1039
- root: rootDirectory
1040
- });
1041
- return {
1042
- rootDirectory,
1043
- appDirectory,
1044
- routeConfigEnv,
1045
- routes: await getRoutes({ rootDirectory, appDirectory, routeConfigEnv })
1046
- };
1047
- }
1048
- async function getAppDirectory(rootDirectory, configFile) {
1049
- const { reactRouterConfig } = await loadPluginContext({
1050
- root: rootDirectory,
1051
- configFile
1052
- });
1053
- return reactRouterConfig.appDirectory;
1054
- }
1055
- function findRoute(ctx, path8) {
1056
- return Object.values(ctx.routes).find(
1057
- (route) => path8 === Path.join(ctx.appDirectory, route.file)
1058
- );
1059
- }
1060
- async function getRoutes(ctx) {
1061
- ctx.routeConfigEnv.devServer.moduleGraph.invalidateAll();
1062
- ctx.routeConfigEnv.runner.moduleCache.clear();
1063
- const routeConfigFile = findEntry(ctx.appDirectory, "routes");
1064
- if (!routeConfigFile) {
1065
- warn(
1066
- `Could not find route config within ${import_picocolors5.default.blue(
1067
- Path.relative(ctx.rootDirectory, ctx.appDirectory)
1068
- )}`
1069
- );
1070
- process.exit(1);
1071
- }
1072
- const routeConfigPath = Path.join(ctx.appDirectory, routeConfigFile);
1073
- const routeConfig = (await ctx.routeConfigEnv.runner.executeFile(routeConfigPath)).routes;
1074
- const routes2 = configRoutesToRouteManifest(await routeConfig);
1075
- const rootRouteFile = findEntry(ctx.appDirectory, "root");
1076
- if (!rootRouteFile) throw new Error("Could not find `root` route");
1077
- routes2.root = { path: "", id: "root", file: rootRouteFile };
1078
- return routes2;
1079
- }
1080
- async function writeAll(ctx) {
1081
- const typegenDir = Path.join(ctx.rootDirectory, ".react-router/types");
1082
- import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
1083
- Object.values(ctx.routes).forEach((route) => {
1084
- if (!import_node_fs2.default.existsSync(Path.join(ctx.appDirectory, route.file))) return;
1085
- const typesPath = Path.join(
1086
- typegenDir,
1087
- Path.relative(ctx.rootDirectory, ctx.appDirectory),
1088
- Path.dirname(route.file),
1089
- "+types." + Pathe2.filename(route.file) + ".d.ts"
1090
- );
1091
- const content = generate2(ctx.routes, route);
1092
- import_node_fs2.default.mkdirSync(Path.dirname(typesPath), { recursive: true });
1093
- import_node_fs2.default.writeFileSync(typesPath, content);
1094
- });
1095
- }
1096
-
1097
- // cli/commands.ts
1406
+ init_typegen();
1407
+ init_import_vite_esm_sync();
1098
1408
  async function routes(reactRouterRoot, flags = {}) {
1099
1409
  let ctx = await loadPluginContext({
1100
1410
  root: reactRouterRoot,
@@ -1102,7 +1412,7 @@ async function routes(reactRouterRoot, flags = {}) {
1102
1412
  });
1103
1413
  if (!ctx) {
1104
1414
  console.error(
1105
- import_picocolors8.default.red("React Router Vite plugin not found in Vite config")
1415
+ import_picocolors7.default.red("React Router Vite plugin not found in Vite config")
1106
1416
  );
1107
1417
  process.exit(1);
1108
1418
  }
@@ -1156,14 +1466,14 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1156
1466
  let entriesArray = Array.from(entries);
1157
1467
  let list = conjunctionListFormat.format(entriesArray);
1158
1468
  console.error(
1159
- import_picocolors8.default.red(`Invalid entry file. Valid entry files are ${list}`)
1469
+ import_picocolors7.default.red(`Invalid entry file. Valid entry files are ${list}`)
1160
1470
  );
1161
1471
  return;
1162
1472
  }
1163
1473
  let pkgJson = await import_package_json2.default.load(rootDirectory);
1164
1474
  let deps = pkgJson.content.dependencies ?? {};
1165
1475
  if (!deps["@react-router/node"]) {
1166
- console.error(import_picocolors8.default.red(`No default server entry detected.`));
1476
+ console.error(import_picocolors7.default.red(`No default server entry detected.`));
1167
1477
  return;
1168
1478
  }
1169
1479
  let defaultsDirectory = path7.resolve(
@@ -1188,12 +1498,12 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1188
1498
  cwd: rootDirectory,
1189
1499
  filename: isServerEntry ? defaultEntryServer : defaultEntryClient
1190
1500
  });
1191
- await import_fs_extra3.default.writeFile(outputFile2, javascript, "utf-8");
1501
+ await import_fs_extra2.default.writeFile(outputFile2, javascript, "utf-8");
1192
1502
  } else {
1193
- await import_fs_extra3.default.writeFile(outputFile2, contents, "utf-8");
1503
+ await import_fs_extra2.default.writeFile(outputFile2, contents, "utf-8");
1194
1504
  }
1195
1505
  console.log(
1196
- import_picocolors8.default.blue(
1506
+ import_picocolors7.default.blue(
1197
1507
  `Entry file ${entry} created at ${path7.relative(
1198
1508
  rootDirectory,
1199
1509
  outputFile2
@@ -1204,45 +1514,48 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1204
1514
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
1205
1515
  for (let entry of entries2) {
1206
1516
  let entryPath = path7.resolve(appDirectory, entry);
1207
- let exists = await import_fs_extra3.default.pathExists(entryPath);
1517
+ let exists = await import_fs_extra2.default.pathExists(entryPath);
1208
1518
  if (exists) {
1209
- let relative6 = path7.relative(rootDirectory, entryPath);
1210
- console.error(import_picocolors8.default.red(`Entry file ${relative6} already exists.`));
1519
+ let relative8 = path7.relative(rootDirectory, entryPath);
1520
+ console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
1211
1521
  return process.exit(1);
1212
1522
  }
1213
1523
  }
1214
1524
  }
1215
1525
  async function createServerEntry(rootDirectory, appDirectory, inputFile) {
1216
1526
  await checkForEntry(rootDirectory, appDirectory, serverEntries);
1217
- let contents = await import_fs_extra3.default.readFile(inputFile, "utf-8");
1527
+ let contents = await import_fs_extra2.default.readFile(inputFile, "utf-8");
1218
1528
  return contents;
1219
1529
  }
1220
1530
  async function createClientEntry(rootDirectory, appDirectory, inputFile) {
1221
1531
  await checkForEntry(rootDirectory, appDirectory, clientEntries);
1222
- let contents = await import_fs_extra3.default.readFile(inputFile, "utf-8");
1532
+ let contents = await import_fs_extra2.default.readFile(inputFile, "utf-8");
1223
1533
  return contents;
1224
1534
  }
1225
1535
  async function typegen(root, flags) {
1226
1536
  root ??= process.cwd();
1227
1537
  if (flags.watch) {
1228
- await watch(root, flags.config);
1538
+ await preloadViteEsm();
1539
+ const vite2 = importViteEsmSync();
1540
+ const logger = vite2.createLogger("info", { prefix: "[react-router]" });
1541
+ await watch(root, { logger });
1229
1542
  await new Promise(() => {
1230
1543
  });
1231
1544
  return;
1232
1545
  }
1233
- await run(root, flags.config);
1546
+ await run(root);
1234
1547
  }
1235
1548
 
1236
1549
  // cli/run.ts
1237
1550
  var helpText = `
1238
- ${import_picocolors9.default.blueBright("react-router")}
1551
+ ${import_picocolors8.default.blueBright("react-router")}
1239
1552
 
1240
- ${import_picocolors9.default.underline("Usage")}:
1241
- $ react-router build [${import_picocolors9.default.yellowBright("projectDir")}]
1242
- $ react-router dev [${import_picocolors9.default.yellowBright("projectDir")}]
1243
- $ react-router routes [${import_picocolors9.default.yellowBright("projectDir")}]
1553
+ ${import_picocolors8.default.underline("Usage")}:
1554
+ $ react-router build [${import_picocolors8.default.yellowBright("projectDir")}]
1555
+ $ react-router dev [${import_picocolors8.default.yellowBright("projectDir")}]
1556
+ $ react-router routes [${import_picocolors8.default.yellowBright("projectDir")}]
1244
1557
 
1245
- ${import_picocolors9.default.underline("Options")}:
1558
+ ${import_picocolors8.default.underline("Options")}:
1246
1559
  --help, -h Print this help message and exit
1247
1560
  --version, -v Print the CLI version and exit
1248
1561
  --no-color Disable ANSI colors in console output
@@ -1276,25 +1589,24 @@ ${import_picocolors9.default.blueBright("react-router")}
1276
1589
  --config, -c Use specified Vite config file (string)
1277
1590
  --no-typescript Generate plain JavaScript files
1278
1591
  \`typegen\` Options:
1279
- --config, -c Use specified Vite config file (string)
1280
1592
  --watch Automatically regenerate types whenever route config (\`routes.ts\`) or route modules change
1281
1593
 
1282
- ${import_picocolors9.default.underline("Build your project")}:
1594
+ ${import_picocolors8.default.underline("Build your project")}:
1283
1595
 
1284
1596
  $ react-router build
1285
1597
 
1286
- ${import_picocolors9.default.underline("Run your project locally in development")}:
1598
+ ${import_picocolors8.default.underline("Run your project locally in development")}:
1287
1599
 
1288
1600
  $ react-router dev
1289
1601
 
1290
- ${import_picocolors9.default.underline("Show all routes in your app")}:
1602
+ ${import_picocolors8.default.underline("Show all routes in your app")}:
1291
1603
 
1292
1604
  $ react-router routes
1293
1605
  $ react-router routes my-app
1294
1606
  $ react-router routes --json
1295
1607
  $ react-router routes --config vite.react-router.config.ts
1296
1608
 
1297
- ${import_picocolors9.default.underline("Reveal the used entry point")}:
1609
+ ${import_picocolors8.default.underline("Reveal the used entry point")}:
1298
1610
 
1299
1611
  $ react-router reveal entry.client
1300
1612
  $ react-router reveal entry.server
@@ -1302,18 +1614,17 @@ ${import_picocolors9.default.blueBright("react-router")}
1302
1614
  $ react-router reveal entry.server --no-typescript
1303
1615
  $ react-router reveal entry.server --config vite.react-router.config.ts
1304
1616
 
1305
- ${import_picocolors9.default.underline("Generate types for route modules")}:
1617
+ ${import_picocolors8.default.underline("Generate types for route modules")}:
1306
1618
 
1307
1619
  $ react-router typegen
1308
1620
  $ react-router typegen --watch
1309
- $ react-router typegen --config vite.react-router.config.ts
1310
1621
  `;
1311
1622
  async function run2(argv = process.argv.slice(2)) {
1312
1623
  let versions = process.versions;
1313
1624
  let MINIMUM_NODE_VERSION = 20;
1314
1625
  if (versions && versions.node && import_semver.default.major(versions.node) < MINIMUM_NODE_VERSION) {
1315
- throw new Error(
1316
- `\uFE0F\u{1F6A8} Oops, Node v${versions.node} detected. react-router requires a Node version greater than ${MINIMUM_NODE_VERSION}.`
1626
+ console.warn(
1627
+ `\uFE0F\u26A0\uFE0F Oops, Node v${versions.node} detected. react-router requires a Node version greater than ${MINIMUM_NODE_VERSION}.`
1317
1628
  );
1318
1629
  }
1319
1630
  let isBooleanFlag = (arg2) => {
@@ -1404,8 +1715,8 @@ run2().then(
1404
1715
  () => {
1405
1716
  process.exit(0);
1406
1717
  },
1407
- (error2) => {
1408
- if (error2) console.error(error2);
1718
+ (error) => {
1719
+ if (error) console.error(error);
1409
1720
  process.exit(1);
1410
1721
  }
1411
1722
  );