@react-router/dev 7.0.0-pre.4 → 7.0.0-pre.6

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,5 +1,6 @@
1
+ #!/usr/bin/env node
1
2
  /**
2
- * @react-router/dev v7.0.0-pre.4
3
+ * @react-router/dev v7.0.0-pre.6
3
4
  *
4
5
  * Copyright (c) Remix Software Inc.
5
6
  *
@@ -54,35 +55,14 @@ var init_invariant = __esm({
54
55
  }
55
56
  });
56
57
 
57
- // vite/babel.ts
58
- var import_parser, t, traverse, generate;
59
- var init_babel = __esm({
60
- "vite/babel.ts"() {
61
- "use strict";
62
- import_parser = require("@babel/parser");
63
- t = __toESM(require("@babel/types"));
64
- traverse = require("@babel/traverse").default;
65
- generate = require("@babel/generator").default;
66
- }
67
- });
68
-
69
- // vite/node-adapter.ts
70
- var import_node_events, import_node_stream, import_set_cookie_parser, import_node;
71
- var init_node_adapter = __esm({
72
- "vite/node-adapter.ts"() {
73
- "use strict";
74
- import_node_events = require("events");
75
- import_node_stream = require("stream");
76
- import_set_cookie_parser = require("set-cookie-parser");
77
- import_node = require("@react-router/node");
78
- init_invariant();
79
- }
80
- });
81
-
82
58
  // vite/import-vite-esm-sync.ts
83
59
  async function preloadViteEsm() {
84
60
  vite = await import("vite");
85
61
  }
62
+ function importViteEsmSync() {
63
+ invariant(vite, "importViteEsmSync() called before preloadViteEsm()");
64
+ return vite;
65
+ }
86
66
  var vite;
87
67
  var init_import_vite_esm_sync = __esm({
88
68
  "vite/import-vite-esm-sync.ts"() {
@@ -91,61 +71,132 @@ var init_import_vite_esm_sync = __esm({
91
71
  }
92
72
  });
93
73
 
94
- // vite/resolve-file-url.ts
95
- var path;
96
- var init_resolve_file_url = __esm({
97
- "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"() {
98
115
  "use strict";
99
- 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");
100
119
  init_import_vite_esm_sync();
101
120
  }
102
121
  });
103
122
 
104
- // vite/styles.ts
105
- var path2, import_react_router, cssFileRegExp, cssModulesRegExp;
106
- var init_styles = __esm({
107
- "vite/styles.ts"() {
108
- "use strict";
109
- path2 = __toESM(require("path"));
110
- import_react_router = require("react-router");
111
- init_resolve_file_url();
112
- cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
113
- cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
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
+ };
114
136
  }
115
- });
116
-
117
- // vite/vmod.ts
118
- var id;
119
- var init_vmod = __esm({
120
- "vite/vmod.ts"() {
121
- "use strict";
122
- id = (name) => `virtual:react-router/${name}`;
137
+ if (!Array.isArray(routeConfig)) {
138
+ return {
139
+ valid: false,
140
+ message: `Route config in "${routeConfigFile}" must be an array.`
141
+ };
123
142
  }
124
- });
125
-
126
- // vite/combine-urls.ts
127
- var init_combine_urls = __esm({
128
- "vite/combine-urls.ts"() {
129
- "use strict";
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
+ };
130
157
  }
131
- });
132
-
133
- // vite/remove-exports.ts
134
- var import_babel_dead_code_elimination;
135
- var init_remove_exports = __esm({
136
- "vite/remove-exports.ts"() {
137
- "use strict";
138
- import_babel_dead_code_elimination = require("babel-dead-code-elimination");
139
- init_babel();
158
+ return { valid: true };
159
+ }
160
+ function configRoutesToRouteManifest(appDirectory, routes2, rootId = "root") {
161
+ let routeManifest = {};
162
+ function walk(route, parentId) {
163
+ let id2 = route.id || createRouteId(route.file);
164
+ let manifestItem = {
165
+ id: id2,
166
+ parentId,
167
+ file: Path.isAbsolute(route.file) ? Path.relative(appDirectory, route.file) : route.file,
168
+ path: route.path,
169
+ index: route.index,
170
+ caseSensitive: route.caseSensitive
171
+ };
172
+ if (routeManifest.hasOwnProperty(id2)) {
173
+ throw new Error(
174
+ `Unable to define routes with duplicate route id: "${id2}"`
175
+ );
176
+ }
177
+ routeManifest[id2] = manifestItem;
178
+ if (route.children) {
179
+ for (let child of route.children) {
180
+ walk(child, id2);
181
+ }
182
+ }
140
183
  }
141
- });
142
-
143
- // config/routes.ts
144
- var import_node_path, v, import_pick, routeConfigEntrySchema, resolvedRouteConfigSchema;
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;
145
196
  var init_routes = __esm({
146
197
  "config/routes.ts"() {
147
198
  "use strict";
148
- import_node_path = require("path");
199
+ Path = __toESM(require("pathe"));
149
200
  v = __toESM(require("valibot"));
150
201
  import_pick = __toESM(require("lodash/pick"));
151
202
  init_invariant();
@@ -173,21 +224,285 @@ var init_detectPackageManager = __esm({
173
224
  }
174
225
  });
175
226
 
176
- // vite/config.ts
177
- var import_node_child_process, import_node_path2, import_fs_extra, import_picocolors, import_pick2, import_omit, import_package_json, branchRouteProperties, configRouteToBranchRoute;
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;
178
489
  var init_config = __esm({
179
- "vite/config.ts"() {
490
+ "config/config.ts"() {
180
491
  "use strict";
492
+ import_node_fs = __toESM(require("fs"));
181
493
  import_node_child_process = require("child_process");
182
- import_node_path2 = __toESM(require("path"));
183
- import_fs_extra = __toESM(require("fs-extra"));
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"));
184
498
  import_picocolors = __toESM(require("picocolors"));
185
499
  import_pick2 = __toESM(require("lodash/pick"));
186
500
  import_omit = __toESM(require("lodash/omit"));
187
- import_package_json = __toESM(require("@npmcli/package-json"));
501
+ import_cloneDeep = __toESM(require("lodash/cloneDeep"));
502
+ import_isEqual = __toESM(require("lodash/isEqual"));
188
503
  init_routes();
189
504
  init_detectPackageManager();
190
- init_import_vite_esm_sync();
505
+ excludedConfigPresetKeys = ["presets"];
191
506
  branchRouteProperties = [
192
507
  "id",
193
508
  "path",
@@ -195,33 +510,339 @@ var init_config = __esm({
195
510
  "index"
196
511
  ];
197
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"];
198
565
  }
199
566
  });
200
567
 
201
- // vite/with-props.ts
202
- var import_dedent, vmodId;
203
- var init_with_props = __esm({
204
- "vite/with-props.ts"() {
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"() {
205
688
  "use strict";
206
689
  import_dedent = __toESM(require("dedent"));
207
- init_babel();
208
- init_vmod();
209
- vmodId = id("with-props");
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));
210
694
  }
211
695
  });
212
696
 
213
- // vite/vite-node.ts
214
- var import_server, import_client, import_source_map;
215
- var init_vite_node = __esm({
216
- "vite/vite-node.ts"() {
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"() {
217
750
  "use strict";
218
- import_server = require("vite-node/server");
219
- import_client = require("vite-node/client");
220
- import_source_map = require("vite-node/source-map");
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"));
221
791
  init_import_vite_esm_sync();
222
792
  }
223
793
  });
224
794
 
795
+ // vite/styles.ts
796
+ var path3, import_react_router, cssFileRegExp, cssModulesRegExp;
797
+ var init_styles = __esm({
798
+ "vite/styles.ts"() {
799
+ "use strict";
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}`);
805
+ }
806
+ });
807
+
808
+ // vite/vmod.ts
809
+ var id;
810
+ var init_vmod = __esm({
811
+ "vite/vmod.ts"() {
812
+ "use strict";
813
+ id = (name) => `virtual:react-router/${name}`;
814
+ }
815
+ });
816
+
817
+ // vite/combine-urls.ts
818
+ var init_combine_urls = __esm({
819
+ "vite/combine-urls.ts"() {
820
+ "use strict";
821
+ }
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"() {
828
+ "use strict";
829
+ import_babel_dead_code_elimination = require("babel-dead-code-elimination");
830
+ init_babel();
831
+ }
832
+ });
833
+
834
+ // vite/with-props.ts
835
+ var import_dedent2, vmodId;
836
+ var init_with_props = __esm({
837
+ "vite/with-props.ts"() {
838
+ "use strict";
839
+ import_dedent2 = __toESM(require("dedent"));
840
+ init_babel();
841
+ init_vmod();
842
+ vmodId = id("with-props");
843
+ }
844
+ });
845
+
225
846
  // vite/plugin.ts
226
847
  async function resolveViteConfig({
227
848
  configFile,
@@ -262,40 +883,41 @@ async function loadPluginContext({
262
883
  ".mjs"
263
884
  ]);
264
885
  if (!configFile) {
265
- console.error(import_picocolors2.default.red("Vite config file not found"));
886
+ console.error(import_picocolors3.default.red("Vite config file not found"));
266
887
  process.exit(1);
267
888
  }
268
889
  let viteConfig = await resolveViteConfig({ configFile, root });
269
890
  let ctx = await extractPluginContext(viteConfig);
270
891
  if (!ctx) {
271
892
  console.error(
272
- 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")
273
894
  );
274
895
  process.exit(1);
275
896
  }
276
897
  return ctx;
277
898
  }
278
- function findConfig(dir, basename3, extensions) {
899
+ function findConfig(dir, basename2, extensions) {
279
900
  for (let ext of extensions) {
280
- let name = basename3 + ext;
901
+ let name = basename2 + ext;
281
902
  let file = path4.join(dir, name);
282
- if (fse2.existsSync(file)) return file;
903
+ if (fse.existsSync(file)) return file;
283
904
  }
284
905
  return void 0;
285
906
  }
286
- 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;
287
908
  var init_plugin = __esm({
288
909
  "vite/plugin.ts"() {
289
910
  "use strict";
290
911
  import_node_crypto = require("crypto");
291
912
  path4 = __toESM(require("path"));
292
913
  url = __toESM(require("url"));
293
- fse2 = __toESM(require("fs-extra"));
914
+ fse = __toESM(require("fs-extra"));
294
915
  babel = __toESM(require("@babel/core"));
295
916
  import_react_router2 = require("react-router");
296
917
  import_es_module_lexer = require("es-module-lexer");
297
918
  import_jsesc = __toESM(require("jsesc"));
298
- import_picocolors2 = __toESM(require("picocolors"));
919
+ import_picocolors3 = __toESM(require("picocolors"));
920
+ init_typegen();
299
921
  init_invariant();
300
922
  init_babel();
301
923
  init_node_adapter();
@@ -307,7 +929,6 @@ var init_plugin = __esm({
307
929
  init_import_vite_esm_sync();
308
930
  init_config();
309
931
  init_with_props();
310
- init_vite_node();
311
932
  serverBuildId = id("server-build");
312
933
  serverManifestId = id("server-manifest");
313
934
  browserManifestId = id("browser-manifest");
@@ -324,7 +945,7 @@ var init_plugin = __esm({
324
945
  "config",
325
946
  "defaults"
326
947
  );
327
- defaultEntries = fse2.readdirSync(defaultEntriesDir).map((filename2) => path4.join(defaultEntriesDir, filename2));
948
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path4.join(defaultEntriesDir, filename3));
328
949
  invariant(defaultEntries.length > 0, "No default entries found");
329
950
  REACT_REFRESH_HEADER = `
330
951
  import RefreshRuntime from "${hmrRuntimeId}";
@@ -365,13 +986,13 @@ if (import.meta.hot && !inWebWorker) {
365
986
  });
366
987
 
367
988
  // vite/profiler.ts
368
- 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;
369
990
  var init_profiler = __esm({
370
991
  "vite/profiler.ts"() {
371
992
  "use strict";
372
- import_node_fs = __toESM(require("fs"));
373
- import_node_path3 = __toESM(require("path"));
374
- 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"));
375
996
  getSession = () => global.__reactRouter_profile_session;
376
997
  start = async (callback) => {
377
998
  let inspector = await import("inspector").then((r) => r.default);
@@ -386,13 +1007,13 @@ var init_profiler = __esm({
386
1007
  let session = getSession();
387
1008
  if (!session) return;
388
1009
  return new Promise((res, rej) => {
389
- session.post("Profiler.stop", (err, { profile }) => {
390
- if (err) return rej(err);
391
- let outPath = import_node_path3.default.resolve(`./react-router-${profileCount++}.cpuprofile`);
392
- import_node_fs.default.writeFileSync(outPath, JSON.stringify(profile));
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));
393
1014
  log(
394
- import_picocolors3.default.yellow(
395
- `CPU profile written to ${import_picocolors3.default.white(import_picocolors3.default.dim(outPath))}`
1015
+ import_picocolors4.default.yellow(
1016
+ `CPU profile written to ${import_picocolors4.default.white(import_picocolors4.default.dim(outPath))}`
396
1017
  )
397
1018
  );
398
1019
  global.__reactRouter_profile_session = void 0;
@@ -449,12 +1070,12 @@ async function getServerBuilds(ctx) {
449
1070
  };
450
1071
  }
451
1072
  let { normalizePath } = await import("vite");
452
- let resolvedAppDirectory = import_node_path4.default.resolve(rootDirectory, appDirectory);
1073
+ let resolvedAppDirectory = import_node_path2.default.resolve(rootDirectory, appDirectory);
453
1074
  let rootRelativeRoutes = Object.fromEntries(
454
1075
  Object.entries(routes2).map(([id2, route]) => {
455
- let filePath = import_node_path4.default.join(resolvedAppDirectory, route.file);
1076
+ let filePath = import_node_path2.default.join(resolvedAppDirectory, route.file);
456
1077
  let rootRelativeFilePath = normalizePath(
457
- import_node_path4.default.relative(rootDirectory, filePath)
1078
+ import_node_path2.default.relative(rootDirectory, filePath)
458
1079
  );
459
1080
  return [id2, { ...route, file: rootRelativeFilePath }];
460
1081
  })
@@ -473,7 +1094,7 @@ async function getServerBuilds(ctx) {
473
1094
  (route2) => configRouteToBranchRoute({
474
1095
  ...route2,
475
1096
  // Ensure absolute paths are passed to the serverBundles function
476
- file: import_node_path4.default.join(resolvedAppDirectory, route2.file)
1097
+ file: import_node_path2.default.join(resolvedAppDirectory, route2.file)
477
1098
  })
478
1099
  )
479
1100
  });
@@ -486,16 +1107,16 @@ async function getServerBuilds(ctx) {
486
1107
  );
487
1108
  }
488
1109
  buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;
489
- let relativeServerBundleDirectory = import_node_path4.default.relative(
1110
+ let relativeServerBundleDirectory = import_node_path2.default.relative(
490
1111
  rootDirectory,
491
- import_node_path4.default.join(serverBuildDirectory, serverBundleId)
1112
+ import_node_path2.default.join(serverBuildDirectory, serverBundleId)
492
1113
  );
493
1114
  let serverBuildConfig = serverBundleBuildConfigById.get(serverBundleId);
494
1115
  if (!serverBuildConfig) {
495
1116
  buildManifest.serverBundles[serverBundleId] = {
496
1117
  id: serverBundleId,
497
1118
  file: normalizePath(
498
- import_node_path4.default.join(relativeServerBundleDirectory, serverBuildFile)
1119
+ import_node_path2.default.join(relativeServerBundleDirectory, serverBuildFile)
499
1120
  )
500
1121
  };
501
1122
  serverBuildConfig = {
@@ -526,15 +1147,15 @@ async function getServerBuilds(ctx) {
526
1147
  async function cleanBuildDirectory(viteConfig, ctx) {
527
1148
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
528
1149
  let isWithinRoot = () => {
529
- let relativePath = import_node_path4.default.relative(ctx.rootDirectory, buildDirectory);
530
- 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);
531
1152
  };
532
1153
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
533
- await import_fs_extra2.default.remove(buildDirectory);
1154
+ await import_fs_extra.default.remove(buildDirectory);
534
1155
  }
535
1156
  }
536
1157
  function getViteManifestPaths(ctx, serverBuilds) {
537
- 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);
538
1159
  let viteManifestPaths = [
539
1160
  "client/.vite/manifest.json",
540
1161
  ...serverBuilds.map(({ serverBundleBuildConfig }) => {
@@ -562,7 +1183,7 @@ async function build(root, {
562
1183
  const ctx = await extractPluginContext(viteConfig);
563
1184
  if (!ctx) {
564
1185
  console.error(
565
- import_picocolors4.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")
566
1187
  );
567
1188
  process.exit(1);
568
1189
  }
@@ -596,15 +1217,15 @@ async function build(root, {
596
1217
  let viteManifestPaths = getViteManifestPaths(ctx, serverBuilds);
597
1218
  await Promise.all(
598
1219
  viteManifestPaths.map(async (viteManifestPath) => {
599
- let manifestExists = await import_fs_extra2.default.pathExists(viteManifestPath);
1220
+ let manifestExists = await import_fs_extra.default.pathExists(viteManifestPath);
600
1221
  if (!manifestExists) return;
601
1222
  if (!ctx.viteManifestEnabled) {
602
- await import_fs_extra2.default.remove(viteManifestPath);
1223
+ await import_fs_extra.default.remove(viteManifestPath);
603
1224
  }
604
- let viteDir = import_node_path4.default.dirname(viteManifestPath);
605
- 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);
606
1227
  if (viteDirFiles.length === 0) {
607
- await import_fs_extra2.default.remove(viteDir);
1228
+ await import_fs_extra.default.remove(viteDir);
608
1229
  }
609
1230
  })
610
1231
  );
@@ -614,13 +1235,13 @@ async function build(root, {
614
1235
  viteConfig
615
1236
  });
616
1237
  }
617
- var import_node_path4, import_fs_extra2, import_picocolors4;
1238
+ var import_node_path2, import_fs_extra, import_picocolors5;
618
1239
  var init_build = __esm({
619
1240
  "vite/build.ts"() {
620
1241
  "use strict";
621
- import_node_path4 = __toESM(require("path"));
622
- import_fs_extra2 = __toESM(require("fs-extra"));
623
- import_picocolors4 = __toESM(require("picocolors"));
1242
+ import_node_path2 = __toESM(require("path"));
1243
+ import_fs_extra = __toESM(require("fs-extra"));
1244
+ import_picocolors5 = __toESM(require("picocolors"));
624
1245
  init_plugin();
625
1246
  init_config();
626
1247
  init_invariant();
@@ -658,7 +1279,7 @@ async function dev(root, {
658
1279
  });
659
1280
  if (!server.config.plugins.find((plugin2) => plugin2.name === "react-router")) {
660
1281
  console.error(
661
- import_picocolors5.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")
662
1283
  );
663
1284
  process.exit(1);
664
1285
  }
@@ -681,11 +1302,11 @@ async function dev(root, {
681
1302
  ];
682
1303
  server.bindCLIShortcuts({ print: true, customShortcuts });
683
1304
  }
684
- var import_picocolors5;
1305
+ var import_picocolors6;
685
1306
  var init_dev = __esm({
686
1307
  "vite/dev.ts"() {
687
1308
  "use strict";
688
- import_picocolors5 = __toESM(require("picocolors"));
1309
+ import_picocolors6 = __toESM(require("picocolors"));
689
1310
  init_import_vite_esm_sync();
690
1311
  init_profiler();
691
1312
  }
@@ -694,34 +1315,14 @@ var init_dev = __esm({
694
1315
  // cli/run.ts
695
1316
  var import_arg = __toESM(require("arg"));
696
1317
  var import_semver = __toESM(require("semver"));
697
-
698
- // colors.ts
699
- var import_chalk = __toESM(require("chalk"));
700
- var useColor = import_chalk.default.supportsColor && !process.env.NO_COLOR;
701
- var identity = (x) => x;
702
- var safe = (style) => useColor ? style : identity;
703
- var heading = safe(import_chalk.default.underline);
704
- var arg = safe(import_chalk.default.yellowBright);
705
- var error = safe(import_chalk.default.red);
706
- var warning = safe(import_chalk.default.yellow);
707
- var hint = safe(import_chalk.default.blue);
708
- var logoBlue = safe(import_chalk.default.blueBright);
709
- var logoGreen = safe(import_chalk.default.greenBright);
710
- var logoYellow = safe(import_chalk.default.yellowBright);
711
- var logoPink = safe(import_chalk.default.magentaBright);
712
- var logoRed = safe(import_chalk.default.redBright);
713
- var bold = safe(import_chalk.default.bold);
714
- var blue = safe(import_chalk.default.blue);
715
- var cyan = safe(import_chalk.default.cyan);
716
- var gray = safe(import_chalk.default.gray);
717
- var red = safe(import_chalk.default.red);
718
- var yellow = safe(import_chalk.default.yellow);
1318
+ var import_picocolors8 = __toESM(require("picocolors"));
719
1319
 
720
1320
  // cli/commands.ts
721
1321
  var path7 = __toESM(require("path"));
722
- var import_fs_extra3 = __toESM(require("fs-extra"));
1322
+ var import_fs_extra2 = __toESM(require("fs-extra"));
723
1323
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
724
1324
  var import_exit_hook = __toESM(require("exit-hook"));
1325
+ var import_picocolors7 = __toESM(require("picocolors"));
725
1326
 
726
1327
  // config/format.ts
727
1328
  function formatRoutes(routeManifest, format) {
@@ -802,106 +1403,8 @@ function transpile(tsx, options = {}) {
802
1403
 
803
1404
  // cli/commands.ts
804
1405
  init_profiler();
805
-
806
- // typescript/typegen.ts
807
- var import_node_fs2 = __toESM(require("fs"));
808
- var import_chokidar = __toESM(require("chokidar"));
809
- var import_dedent2 = __toESM(require("dedent"));
810
- var Path = __toESM(require("pathe"));
811
- var Pathe = __toESM(require("pathe/utils"));
812
- init_routes();
813
- init_vite_node();
814
- init_config();
815
- init_plugin();
816
- function getDirectory(ctx) {
817
- return Path.join(ctx.rootDirectory, ".react-router/types");
818
- }
819
- function getPath(ctx, route) {
820
- return Path.join(
821
- getDirectory(ctx),
822
- Path.basename(ctx.appDirectory),
823
- Path.dirname(route.file),
824
- "+types." + Pathe.filename(route.file) + ".d.ts"
825
- );
826
- }
827
- async function writeAll(ctx) {
828
- import_node_fs2.default.rmSync(getDirectory(ctx), { recursive: true, force: true });
829
- Object.values(ctx.routes).forEach((route) => {
830
- if (!import_node_fs2.default.existsSync(Path.join(ctx.appDirectory, route.file))) return;
831
- const typesPath = getPath(ctx, route);
832
- const content = getModule(ctx.routes, route);
833
- import_node_fs2.default.mkdirSync(Path.dirname(typesPath), { recursive: true });
834
- import_node_fs2.default.writeFileSync(typesPath, content);
835
- });
836
- }
837
- function getModule(routes2, route) {
838
- return import_dedent2.default`
839
- // React Router generated types for route:
840
- // ${route.file}
841
-
842
- import * as T from "react-router/types"
843
-
844
- export type Params = {${formattedParamsProperties(routes2, route)}}
845
-
846
- type Route = typeof import("./${Pathe.filename(route.file)}")
847
-
848
- export type LoaderData = T.CreateLoaderData<Route>
849
- export type ActionData = T.CreateActionData<Route>
850
-
851
- export type LoaderArgs = T.CreateServerLoaderArgs<Params>
852
- export type ClientLoaderArgs = T.CreateClientLoaderArgs<Params, Route>
853
- export type ActionArgs = T.CreateServerActionArgs<Params>
854
- export type ClientActionArgs = T.CreateClientActionArgs<Params, Route>
855
-
856
- export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Params>
857
- export type ComponentProps = T.CreateComponentProps<Params, LoaderData, ActionData>
858
- export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Params, LoaderData, ActionData>
859
- `;
860
- }
861
- function formattedParamsProperties(routes2, route) {
862
- const urlpath = routeLineage(routes2, route).map((route2) => route2.path).join("/");
863
- const params = parseParams(urlpath);
864
- const indent = " ".repeat(3);
865
- const properties = Object.entries(params).map(([name, values]) => {
866
- if (values.length === 1) {
867
- const isOptional = values[0];
868
- return indent + (isOptional ? `${name}?: string` : `${name}: string`);
869
- }
870
- const items = values.map(
871
- (isOptional) => isOptional ? "string | undefined" : "string"
872
- );
873
- return indent + `${name}: [${items.join(", ")}]`;
874
- });
875
- const body = properties.length === 0 ? "" : "\n" + properties.join("\n") + "\n";
876
- return body;
877
- }
878
- function routeLineage(routes2, route) {
879
- const result = [];
880
- while (route) {
881
- result.push(route);
882
- if (!route.parentId) break;
883
- route = routes2[route.parentId];
884
- }
885
- result.reverse();
886
- return result;
887
- }
888
- function parseParams(urlpath) {
889
- const result = {};
890
- let segments = urlpath.split("/");
891
- segments.filter((s) => s.startsWith(":")).forEach((param) => {
892
- param = param.slice(1);
893
- let isOptional = param.endsWith("?");
894
- if (isOptional) {
895
- param = param.slice(0, -1);
896
- }
897
- result[param] ??= [];
898
- result[param].push(isOptional);
899
- return;
900
- });
901
- return result;
902
- }
903
-
904
- // cli/commands.ts
1406
+ init_typegen();
1407
+ init_import_vite_esm_sync();
905
1408
  async function routes(reactRouterRoot, flags = {}) {
906
1409
  let ctx = await loadPluginContext({
907
1410
  root: reactRouterRoot,
@@ -909,7 +1412,7 @@ async function routes(reactRouterRoot, flags = {}) {
909
1412
  });
910
1413
  if (!ctx) {
911
1414
  console.error(
912
- red("React Router Vite plugin not found in Vite config")
1415
+ import_picocolors7.default.red("React Router Vite plugin not found in Vite config")
913
1416
  );
914
1417
  process.exit(1);
915
1418
  }
@@ -963,14 +1466,14 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
963
1466
  let entriesArray = Array.from(entries);
964
1467
  let list = conjunctionListFormat.format(entriesArray);
965
1468
  console.error(
966
- error(`Invalid entry file. Valid entry files are ${list}`)
1469
+ import_picocolors7.default.red(`Invalid entry file. Valid entry files are ${list}`)
967
1470
  );
968
1471
  return;
969
1472
  }
970
1473
  let pkgJson = await import_package_json2.default.load(rootDirectory);
971
1474
  let deps = pkgJson.content.dependencies ?? {};
972
1475
  if (!deps["@react-router/node"]) {
973
- console.error(error(`No default server entry detected.`));
1476
+ console.error(import_picocolors7.default.red(`No default server entry detected.`));
974
1477
  return;
975
1478
  }
976
1479
  let defaultsDirectory = path7.resolve(
@@ -995,12 +1498,12 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
995
1498
  cwd: rootDirectory,
996
1499
  filename: isServerEntry ? defaultEntryServer : defaultEntryClient
997
1500
  });
998
- await import_fs_extra3.default.writeFile(outputFile2, javascript, "utf-8");
1501
+ await import_fs_extra2.default.writeFile(outputFile2, javascript, "utf-8");
999
1502
  } else {
1000
- await import_fs_extra3.default.writeFile(outputFile2, contents, "utf-8");
1503
+ await import_fs_extra2.default.writeFile(outputFile2, contents, "utf-8");
1001
1504
  }
1002
1505
  console.log(
1003
- blue(
1506
+ import_picocolors7.default.blue(
1004
1507
  `Entry file ${entry} created at ${path7.relative(
1005
1508
  rootDirectory,
1006
1509
  outputFile2
@@ -1011,43 +1514,48 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1011
1514
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
1012
1515
  for (let entry of entries2) {
1013
1516
  let entryPath = path7.resolve(appDirectory, entry);
1014
- let exists = await import_fs_extra3.default.pathExists(entryPath);
1517
+ let exists = await import_fs_extra2.default.pathExists(entryPath);
1015
1518
  if (exists) {
1016
- let relative5 = path7.relative(rootDirectory, entryPath);
1017
- console.error(error(`Entry file ${relative5} already exists.`));
1519
+ let relative8 = path7.relative(rootDirectory, entryPath);
1520
+ console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
1018
1521
  return process.exit(1);
1019
1522
  }
1020
1523
  }
1021
1524
  }
1022
1525
  async function createServerEntry(rootDirectory, appDirectory, inputFile) {
1023
1526
  await checkForEntry(rootDirectory, appDirectory, serverEntries);
1024
- let contents = await import_fs_extra3.default.readFile(inputFile, "utf-8");
1527
+ let contents = await import_fs_extra2.default.readFile(inputFile, "utf-8");
1025
1528
  return contents;
1026
1529
  }
1027
1530
  async function createClientEntry(rootDirectory, appDirectory, inputFile) {
1028
1531
  await checkForEntry(rootDirectory, appDirectory, clientEntries);
1029
- let contents = await import_fs_extra3.default.readFile(inputFile, "utf-8");
1532
+ let contents = await import_fs_extra2.default.readFile(inputFile, "utf-8");
1030
1533
  return contents;
1031
1534
  }
1032
- async function typegen(root) {
1033
- let ctx = await loadPluginContext({ root });
1034
- await writeAll({
1035
- rootDirectory: root,
1036
- appDirectory: ctx.reactRouterConfig.appDirectory,
1037
- routes: ctx.reactRouterConfig.routes
1038
- });
1535
+ async function typegen(root, flags) {
1536
+ root ??= process.cwd();
1537
+ if (flags.watch) {
1538
+ await preloadViteEsm();
1539
+ const vite2 = importViteEsmSync();
1540
+ const logger = vite2.createLogger("info", { prefix: "[react-router]" });
1541
+ await watch(root, { logger });
1542
+ await new Promise(() => {
1543
+ });
1544
+ return;
1545
+ }
1546
+ await run(root);
1039
1547
  }
1040
1548
 
1041
1549
  // cli/run.ts
1042
1550
  var helpText = `
1043
- ${logoBlue("react-router")}
1551
+ ${import_picocolors8.default.blueBright("react-router")}
1044
1552
 
1045
- ${heading("Usage")}:
1046
- $ react-router build [${arg("projectDir")}]
1047
- $ react-router dev [${arg("projectDir")}]
1048
- $ react-router routes [${arg("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")}]
1049
1557
 
1050
- ${heading("Options")}:
1558
+ ${import_picocolors8.default.underline("Options")}:
1051
1559
  --help, -h Print this help message and exit
1052
1560
  --version, -v Print the CLI version and exit
1053
1561
  --no-color Disable ANSI colors in console output
@@ -1080,23 +1588,25 @@ ${logoBlue("react-router")}
1080
1588
  \`reveal\` Options:
1081
1589
  --config, -c Use specified Vite config file (string)
1082
1590
  --no-typescript Generate plain JavaScript files
1591
+ \`typegen\` Options:
1592
+ --watch Automatically regenerate types whenever route config (\`routes.ts\`) or route modules change
1083
1593
 
1084
- ${heading("Build your project")}:
1594
+ ${import_picocolors8.default.underline("Build your project")}:
1085
1595
 
1086
1596
  $ react-router build
1087
1597
 
1088
- ${heading("Run your project locally in development")}:
1598
+ ${import_picocolors8.default.underline("Run your project locally in development")}:
1089
1599
 
1090
1600
  $ react-router dev
1091
1601
 
1092
- ${heading("Show all routes in your app")}:
1602
+ ${import_picocolors8.default.underline("Show all routes in your app")}:
1093
1603
 
1094
1604
  $ react-router routes
1095
1605
  $ react-router routes my-app
1096
1606
  $ react-router routes --json
1097
1607
  $ react-router routes --config vite.react-router.config.ts
1098
1608
 
1099
- ${heading("Reveal the used entry point")}:
1609
+ ${import_picocolors8.default.underline("Reveal the used entry point")}:
1100
1610
 
1101
1611
  $ react-router reveal entry.client
1102
1612
  $ react-router reveal entry.server
@@ -1104,20 +1614,21 @@ ${logoBlue("react-router")}
1104
1614
  $ react-router reveal entry.server --no-typescript
1105
1615
  $ react-router reveal entry.server --config vite.react-router.config.ts
1106
1616
 
1107
- ${heading("Generate types for route modules")}:
1617
+ ${import_picocolors8.default.underline("Generate types for route modules")}:
1108
1618
 
1109
1619
  $ react-router typegen
1620
+ $ react-router typegen --watch
1110
1621
  `;
1111
- async function run(argv = process.argv.slice(2)) {
1622
+ async function run2(argv = process.argv.slice(2)) {
1112
1623
  let versions = process.versions;
1113
1624
  let MINIMUM_NODE_VERSION = 20;
1114
1625
  if (versions && versions.node && import_semver.default.major(versions.node) < MINIMUM_NODE_VERSION) {
1115
- throw new Error(
1116
- `\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}.`
1117
1628
  );
1118
1629
  }
1119
- let isBooleanFlag = (arg3) => {
1120
- let index = argv.indexOf(arg3);
1630
+ let isBooleanFlag = (arg2) => {
1631
+ let index = argv.indexOf(arg2);
1121
1632
  let nextArg = argv[index + 1];
1122
1633
  return !nextArg || nextArg.startsWith("-");
1123
1634
  };
@@ -1150,7 +1661,8 @@ async function run(argv = process.argv.slice(2)) {
1150
1661
  "--strictPort": Boolean,
1151
1662
  "--profile": Boolean,
1152
1663
  "--sourcemapClient": isBooleanFlag("--sourcemapClient") ? Boolean : String,
1153
- "--sourcemapServer": isBooleanFlag("--sourcemapServer") ? Boolean : String
1664
+ "--sourcemapServer": isBooleanFlag("--sourcemapServer") ? Boolean : String,
1665
+ "--watch": Boolean
1154
1666
  },
1155
1667
  {
1156
1668
  argv
@@ -1191,7 +1703,7 @@ async function run(argv = process.argv.slice(2)) {
1191
1703
  await dev2(input[1], flags);
1192
1704
  break;
1193
1705
  case "typegen":
1194
- await typegen(input[1]);
1706
+ await typegen(input[1], flags);
1195
1707
  break;
1196
1708
  default:
1197
1709
  await dev2(input[0], flags);
@@ -1199,12 +1711,12 @@ async function run(argv = process.argv.slice(2)) {
1199
1711
  }
1200
1712
 
1201
1713
  // cli/index.ts
1202
- run().then(
1714
+ run2().then(
1203
1715
  () => {
1204
1716
  process.exit(0);
1205
1717
  },
1206
- (error2) => {
1207
- if (error2) console.error(error2);
1718
+ (error) => {
1719
+ if (error) console.error(error);
1208
1720
  process.exit(1);
1209
1721
  }
1210
1722
  );