@valbuild/shared 0.124.0 → 0.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,91 @@
1
1
  # @valbuild/shared
2
2
 
3
+ ## 0.125.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#638](https://github.com/valbuild/val/pull/638) [`c390397`](https://github.com/valbuild/val/commit/c390397cb5e203eb1bedae3a6fab15726e850b90) Thanks [@freekh](https://github.com/freekh)! - Val now runs on TanStack Start.
8
+
9
+ `@valbuild/tanstack` is a new package with everything `@valbuild/next` has: Val
10
+ Studio at `/val`, the on-page overlay and canvas, draft mode, the client hooks,
11
+ server-side content reads, images, and the MCP tools.
12
+
13
+ ```sh
14
+ npm install @valbuild/tanstack
15
+ ```
16
+
17
+ ```ts
18
+ // val.config.ts
19
+ import { initVal } from "@valbuild/tanstack";
20
+ const { s, c, config, tanstackRouter } = initVal({ project: "org/project" });
21
+ ```
22
+
23
+ **Routes are first class.** A Val module for a route is named after the route
24
+ file it sits beside — `src/routes/posts.$postId.tsx` is served content by
25
+ `src/routes/posts.$postId.val.ts` — and its keys are the URLs that route serves:
26
+
27
+ ```ts
28
+ export default c.define(
29
+ "/src/routes/posts.$postId.val.ts",
30
+ s.router(tanstackRouter, s.object({ title: s.string() })),
31
+ { "/posts/hello-world": { title: "Hello world" } },
32
+ );
33
+ ```
34
+
35
+ `.` and `/` both separate segments, `$param` is a parameter, `$` is a splat, and
36
+ `index`, `route`, `(groups)` and `_pathless` layouts add no URL segment — the
37
+ same rules TanStack Router uses for the route file itself. Val validates every
38
+ key against that pattern, and Val Studio shows these modules as a sitemap under
39
+ **Pages**, where an editor can add a page.
40
+
41
+ Point the route generator away from your content files, in `vite.config.ts` and
42
+ `tsr.config.json`:
43
+
44
+ ```ts
45
+ tanstackStart({ router: { routeFileIgnorePattern: "\\.val\\.[tj]sx?$" } });
46
+ ```
47
+
48
+ See the [README](https://github.com/valbuild/val/blob/main/packages/tanstack/README.md)
49
+ for the full wiring, and `examples/tanstack` for a working app.
50
+
51
+ **Also fixed, for everyone:** `Internal.VERSION.core` was `null` in any ESM
52
+ bundle — it was read with `require("../package.json")` inside a `try`, so the
53
+ failure was silent. That version goes into every remote file ref and proxy mode
54
+ refuses to start without it. Every package now reads its version through a
55
+ static JSON import, which is inlined at build time.
56
+
57
+ Two smaller fixes that came out of running the whole toolchain against a
58
+ TanStack project:
59
+
60
+ - `val versions` reports `@valbuild/tanstack`, and `val debug` writes a snapshot
61
+ that names whichever framework package the captured project actually has.
62
+ - `@valbuild/eslint-plugin` reads a `tsconfig.json` that has comments in it. A
63
+ tsconfig is JSONC, and `JSON.parse` is not — so on any project whose tsconfig
64
+ carries a comment (the TanStack starter's does) the
65
+ `module-in-val-modules` rule threw `Expected double-quoted property name in
66
+ JSON` on the first file and took the whole lint run with it.
67
+
68
+ Three fixes found by driving the Studio against a real TanStack app:
69
+
70
+ - **A draft image now loads on the page.** The source the Studio pushes to the
71
+ host page carries `patch_id` for any file whose bytes are still in a patch, so
72
+ the page asks `/api/val/files/...?patch_id=` rather than a `/public` path that
73
+ nothing has written yet. This was silent — the image just did not appear — and
74
+ it affects any page that reads media through the hooks rather than on the
75
+ server, `@valbuild/next` included.
76
+ - **A splat route no longer logs an error on every render.** TanStack returns
77
+ both `_splat` and `*` for the same parameter; Val reported the second as a
78
+ parameter it could not place in the path.
79
+ - The TanStack example and starter render a 404 page instead of throwing
80
+ `notFound()` from a component, which escaped to the error boundary and logged
81
+ `Error in renderToReadableStream` (and, with no not-found component
82
+ configured, aborted the response) on every miss.
83
+
84
+ ### Patch Changes
85
+
86
+ - Updated dependencies [[`c390397`](https://github.com/valbuild/val/commit/c390397cb5e203eb1bedae3a6fab15726e850b90)]:
87
+ - @valbuild/core@0.125.0
88
+
3
89
  ## 0.124.0
4
90
 
5
91
  ### Minor Changes
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-a0c9a0e3.cjs.dev.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-d1977d3e.cjs.dev.js');
6
6
  require('@valbuild/core');
7
7
 
8
8
 
@@ -12,9 +12,12 @@ exports.VAL_CANVAS_MESSAGE = getSitemapTree.VAL_CANVAS_MESSAGE;
12
12
  exports.VAL_CANVAS_PARAM = getSitemapTree.VAL_CANVAS_PARAM;
13
13
  exports.VAL_CONFIG_SESSION_STORAGE_KEY = getSitemapTree.VAL_CONFIG_SESSION_STORAGE_KEY;
14
14
  exports.VAL_THEME_SESSION_STORAGE_KEY = getSitemapTree.VAL_THEME_SESSION_STORAGE_KEY;
15
- exports.getNextAppRouterSitemapTree = getSitemapTree.getNextAppRouterSitemapTree;
16
15
  exports.getNextAppRouterSourceFolder = getSitemapTree.getNextAppRouterSourceFolder;
16
+ exports.getPageRouterSitemapTree = getSitemapTree.getPageRouterSitemapTree;
17
+ exports.getPageRouterSourceFolder = getSitemapTree.getPageRouterSourceFolder;
17
18
  exports.getPatternFromModuleFilePath = getSitemapTree.getPatternFromModuleFilePath;
19
+ exports.getTanStackRouterSourceFolder = getSitemapTree.getTanStackRouterSourceFolder;
20
+ exports.isTanStackRoutesFolder = getSitemapTree.isTanStackRoutesFolder;
18
21
  exports.isValCanvasFrame = getSitemapTree.isValCanvasFrame;
19
22
  exports.isValCanvasPageMessage = getSitemapTree.isValCanvasPageMessage;
20
23
  exports.isValCanvasStudioMessage = getSitemapTree.isValCanvasStudioMessage;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var getSitemapTree = require('../../dist/getSitemapTree-77b1203a.cjs.prod.js');
5
+ var getSitemapTree = require('../../dist/getSitemapTree-b320d033.cjs.prod.js');
6
6
  require('@valbuild/core');
7
7
 
8
8
 
@@ -12,9 +12,12 @@ exports.VAL_CANVAS_MESSAGE = getSitemapTree.VAL_CANVAS_MESSAGE;
12
12
  exports.VAL_CANVAS_PARAM = getSitemapTree.VAL_CANVAS_PARAM;
13
13
  exports.VAL_CONFIG_SESSION_STORAGE_KEY = getSitemapTree.VAL_CONFIG_SESSION_STORAGE_KEY;
14
14
  exports.VAL_THEME_SESSION_STORAGE_KEY = getSitemapTree.VAL_THEME_SESSION_STORAGE_KEY;
15
- exports.getNextAppRouterSitemapTree = getSitemapTree.getNextAppRouterSitemapTree;
16
15
  exports.getNextAppRouterSourceFolder = getSitemapTree.getNextAppRouterSourceFolder;
16
+ exports.getPageRouterSitemapTree = getSitemapTree.getPageRouterSitemapTree;
17
+ exports.getPageRouterSourceFolder = getSitemapTree.getPageRouterSourceFolder;
17
18
  exports.getPatternFromModuleFilePath = getSitemapTree.getPatternFromModuleFilePath;
19
+ exports.getTanStackRouterSourceFolder = getSitemapTree.getTanStackRouterSourceFolder;
20
+ exports.isTanStackRoutesFolder = getSitemapTree.isTanStackRoutesFolder;
18
21
  exports.isValCanvasFrame = getSitemapTree.isValCanvasFrame;
19
22
  exports.isValCanvasPageMessage = getSitemapTree.isValCanvasPageMessage;
20
23
  exports.isValCanvasStudioMessage = getSitemapTree.isValCanvasStudioMessage;
@@ -1,2 +1,2 @@
1
- export { b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, h as getNextAppRouterSitemapTree, g as getNextAppRouterSourceFolder, j as getPatternFromModuleFilePath, f as isValCanvasFrame, i as isValCanvasPageMessage, e as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-d3e98a2e.esm.js';
1
+ export { b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, g as getNextAppRouterSourceFolder, l as getPageRouterSitemapTree, j as getPageRouterSourceFolder, m as getPatternFromModuleFilePath, h as getTanStackRouterSourceFolder, k as isTanStackRoutesFolder, f as isValCanvasFrame, i as isValCanvasPageMessage, e as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-a6cb37cb.esm.js';
2
2
  import '@valbuild/core';
@@ -1,2 +1,26 @@
1
1
  import { ModuleFilePath } from "@valbuild/core";
2
2
  export declare function getNextAppRouterSourceFolder(moduleFilePath: ModuleFilePath): "/app" | "/src/app" | null;
3
+ /**
4
+ * The folder a TanStack Router app keeps its route files in.
5
+ *
6
+ * The same question as above for the other convention: `routes/` at the project
7
+ * root, or under `src/`. A Val module for a route lives beside the route file
8
+ * and is named the same way, so this is the prefix to strip before reading the
9
+ * route pattern out of the rest.
10
+ */
11
+ export declare function getTanStackRouterSourceFolder(moduleFilePath: ModuleFilePath): "/routes" | "/src/routes" | null;
12
+ /**
13
+ * The route folder of whichever page router this module belongs to.
14
+ *
15
+ * The two conventions have disjoint prefixes — `app/` versus `routes/` — so a
16
+ * module file path answers this on its own, which is what the Studio needs: it
17
+ * walks every schema in the project and has no framework to ask.
18
+ */
19
+ export declare function getPageRouterSourceFolder(moduleFilePath: ModuleFilePath): "/app" | "/src/app" | "/routes" | "/src/routes" | null;
20
+ /**
21
+ * Whether a route folder is a TanStack Router one.
22
+ *
23
+ * Exported so the pattern derivation and the source-folder detection cannot
24
+ * drift apart about what `/src/routes` means.
25
+ */
26
+ export declare function isTanStackRoutesFolder(srcFolder: string): boolean;
@@ -23,8 +23,17 @@ export type SitemapNode = {
23
23
  moduleFilePath?: ModuleFilePath;
24
24
  sourcePath?: SourcePath | ModuleFilePath;
25
25
  };
26
- export declare function getNextAppRouterSitemapTree(srcFolder: string, paths: {
26
+ export declare function getPageRouterSitemapTree(srcFolder: string, paths: {
27
27
  urlPath: string;
28
28
  moduleFilePath: string;
29
29
  }[]): SitemapNode;
30
+ /**
31
+ * The route pattern a page-router module serves, e.g. `/blogs/[blog]`.
32
+ *
33
+ * Written in Next's vocabulary for both routers on purpose: the pattern is read
34
+ * by `parseRoutePattern`, the sitemap and the Studio's key inputs, none of which
35
+ * should have to know which framework the project uses. The TanStack branch
36
+ * translates that framework's conventions into it; see
37
+ * `tanStackSegmentsOfRoutePath` in `@valbuild/core` for the rules.
38
+ */
30
39
  export declare function getPatternFromModuleFilePath(moduleFilePath: string, srcFolder: string): string;
@@ -1,4 +1,4 @@
1
- import { Internal } from '@valbuild/core';
1
+ import { Internal, tanStackSegmentsOfRoutePath } from '@valbuild/core';
2
2
 
3
3
  var VAL_CONFIG_SESSION_STORAGE_KEY = "val-config";
4
4
  var VAL_THEME_SESSION_STORAGE_KEY = "val-theme";
@@ -135,6 +135,45 @@ function getNextAppRouterSourceFolder(moduleFilePath) {
135
135
  return null;
136
136
  }
137
137
 
138
+ /**
139
+ * The folder a TanStack Router app keeps its route files in.
140
+ *
141
+ * The same question as above for the other convention: `routes/` at the project
142
+ * root, or under `src/`. A Val module for a route lives beside the route file
143
+ * and is named the same way, so this is the prefix to strip before reading the
144
+ * route pattern out of the rest.
145
+ */
146
+ function getTanStackRouterSourceFolder(moduleFilePath) {
147
+ if (moduleFilePath.startsWith("/routes/")) {
148
+ return "/routes";
149
+ } else if (moduleFilePath.startsWith("/src/routes/")) {
150
+ return "/src/routes";
151
+ }
152
+ return null;
153
+ }
154
+
155
+ /**
156
+ * The route folder of whichever page router this module belongs to.
157
+ *
158
+ * The two conventions have disjoint prefixes — `app/` versus `routes/` — so a
159
+ * module file path answers this on its own, which is what the Studio needs: it
160
+ * walks every schema in the project and has no framework to ask.
161
+ */
162
+ function getPageRouterSourceFolder(moduleFilePath) {
163
+ var _getNextAppRouterSour;
164
+ return (_getNextAppRouterSour = getNextAppRouterSourceFolder(moduleFilePath)) !== null && _getNextAppRouterSour !== void 0 ? _getNextAppRouterSour : getTanStackRouterSourceFolder(moduleFilePath);
165
+ }
166
+
167
+ /**
168
+ * Whether a route folder is a TanStack Router one.
169
+ *
170
+ * Exported so the pattern derivation and the source-folder detection cannot
171
+ * drift apart about what `/src/routes` means.
172
+ */
173
+ function isTanStackRoutesFolder(srcFolder) {
174
+ return srcFolder === "/routes" || srcFolder === "/src/routes";
175
+ }
176
+
138
177
  function _toPrimitive(t, r) {
139
178
  if ("object" != typeof t || !t) return t;
140
179
  var e = t[Symbol.toPrimitive];
@@ -245,8 +284,14 @@ function _createForOfIteratorHelper(r, e) {
245
284
  };
246
285
  }
247
286
 
248
- // Strictly speaking this should be in the next package but it's shared, because we want to use it in the ui package. We want to resolve that somehow
249
- function getNextAppRouterSitemapTree(srcFolder, paths) {
287
+ // Strictly speaking this should be in the framework packages but it's shared,
288
+ // because we want to use it in the ui package. We want to resolve that somehow.
289
+ //
290
+ // It is one function for both page routers because the tree it builds is made
291
+ // of URL paths, which is the same thing in either: only `srcFolder` and the
292
+ // pattern derivation differ, and both of those are arguments (or the one call
293
+ // below).
294
+ function getPageRouterSitemapTree(srcFolder, paths) {
250
295
  var root = {
251
296
  type: "node",
252
297
  name: "/",
@@ -358,7 +403,24 @@ function getNextAppRouterSitemapTree(srcFolder, paths) {
358
403
  }
359
404
  return root;
360
405
  }
406
+
407
+ /**
408
+ * The route pattern a page-router module serves, e.g. `/blogs/[blog]`.
409
+ *
410
+ * Written in Next's vocabulary for both routers on purpose: the pattern is read
411
+ * by `parseRoutePattern`, the sitemap and the Studio's key inputs, none of which
412
+ * should have to know which framework the project uses. The TanStack branch
413
+ * translates that framework's conventions into it; see
414
+ * `tanStackSegmentsOfRoutePath` in `@valbuild/core` for the rules.
415
+ */
361
416
  function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
417
+ if (isTanStackRoutesFolder(srcFolder)) {
418
+ var routePath = moduleFilePath.slice(srcFolder.length).replace(/\.val\.[tj]sx?$/, "");
419
+ var segments = tanStackSegmentsOfRoutePath(routePath);
420
+ // "" rather than "/" for the root, so it matches what the Next branch
421
+ // returns for `/app/page.val.ts` — `parseRoutePattern` reads both as [].
422
+ return segments.length === 0 ? "" : "/".concat(segments.join("/"));
423
+ }
362
424
  return moduleFilePath.replace(srcFolder, "")
363
425
  // TODO: hacky!
364
426
  // remove route groups
@@ -366,4 +428,4 @@ function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
366
428
  .replace("/page.val.ts", "").replace("/page.val.js", "");
367
429
  }
368
430
 
369
- export { VAL_CONFIG_SESSION_STORAGE_KEY as V, _createForOfIteratorHelper as _, VAL_THEME_SESSION_STORAGE_KEY as a, VAL_AI_SESSION_STORAGE_KEY as b, VAL_CANVAS_PARAM as c, VAL_CANVAS_MESSAGE as d, isValCanvasStudioMessage as e, isValCanvasFrame as f, getNextAppRouterSourceFolder as g, getNextAppRouterSitemapTree as h, isValCanvasPageMessage as i, getPatternFromModuleFilePath as j, _objectSpread2 as k, _arrayLikeToArray as l, _unsupportedIterableToArray as m, _defineProperty as n, _typeof as o, parseRoutePattern as p, withValCanvasParam as w };
431
+ export { VAL_CONFIG_SESSION_STORAGE_KEY as V, _createForOfIteratorHelper as _, VAL_THEME_SESSION_STORAGE_KEY as a, VAL_AI_SESSION_STORAGE_KEY as b, VAL_CANVAS_PARAM as c, VAL_CANVAS_MESSAGE as d, isValCanvasStudioMessage as e, isValCanvasFrame as f, getNextAppRouterSourceFolder as g, getTanStackRouterSourceFolder as h, isValCanvasPageMessage as i, getPageRouterSourceFolder as j, isTanStackRoutesFolder as k, getPageRouterSitemapTree as l, getPatternFromModuleFilePath as m, _objectSpread2 as n, _arrayLikeToArray as o, parseRoutePattern as p, _unsupportedIterableToArray as q, _defineProperty as r, _typeof as s, withValCanvasParam as w };
@@ -137,6 +137,45 @@ function getNextAppRouterSourceFolder(moduleFilePath) {
137
137
  return null;
138
138
  }
139
139
 
140
+ /**
141
+ * The folder a TanStack Router app keeps its route files in.
142
+ *
143
+ * The same question as above for the other convention: `routes/` at the project
144
+ * root, or under `src/`. A Val module for a route lives beside the route file
145
+ * and is named the same way, so this is the prefix to strip before reading the
146
+ * route pattern out of the rest.
147
+ */
148
+ function getTanStackRouterSourceFolder(moduleFilePath) {
149
+ if (moduleFilePath.startsWith("/routes/")) {
150
+ return "/routes";
151
+ } else if (moduleFilePath.startsWith("/src/routes/")) {
152
+ return "/src/routes";
153
+ }
154
+ return null;
155
+ }
156
+
157
+ /**
158
+ * The route folder of whichever page router this module belongs to.
159
+ *
160
+ * The two conventions have disjoint prefixes — `app/` versus `routes/` — so a
161
+ * module file path answers this on its own, which is what the Studio needs: it
162
+ * walks every schema in the project and has no framework to ask.
163
+ */
164
+ function getPageRouterSourceFolder(moduleFilePath) {
165
+ var _getNextAppRouterSour;
166
+ return (_getNextAppRouterSour = getNextAppRouterSourceFolder(moduleFilePath)) !== null && _getNextAppRouterSour !== void 0 ? _getNextAppRouterSour : getTanStackRouterSourceFolder(moduleFilePath);
167
+ }
168
+
169
+ /**
170
+ * Whether a route folder is a TanStack Router one.
171
+ *
172
+ * Exported so the pattern derivation and the source-folder detection cannot
173
+ * drift apart about what `/src/routes` means.
174
+ */
175
+ function isTanStackRoutesFolder(srcFolder) {
176
+ return srcFolder === "/routes" || srcFolder === "/src/routes";
177
+ }
178
+
140
179
  function _toPrimitive(t, r) {
141
180
  if ("object" != typeof t || !t) return t;
142
181
  var e = t[Symbol.toPrimitive];
@@ -247,8 +286,14 @@ function _createForOfIteratorHelper(r, e) {
247
286
  };
248
287
  }
249
288
 
250
- // Strictly speaking this should be in the next package but it's shared, because we want to use it in the ui package. We want to resolve that somehow
251
- function getNextAppRouterSitemapTree(srcFolder, paths) {
289
+ // Strictly speaking this should be in the framework packages but it's shared,
290
+ // because we want to use it in the ui package. We want to resolve that somehow.
291
+ //
292
+ // It is one function for both page routers because the tree it builds is made
293
+ // of URL paths, which is the same thing in either: only `srcFolder` and the
294
+ // pattern derivation differ, and both of those are arguments (or the one call
295
+ // below).
296
+ function getPageRouterSitemapTree(srcFolder, paths) {
252
297
  var root = {
253
298
  type: "node",
254
299
  name: "/",
@@ -360,7 +405,24 @@ function getNextAppRouterSitemapTree(srcFolder, paths) {
360
405
  }
361
406
  return root;
362
407
  }
408
+
409
+ /**
410
+ * The route pattern a page-router module serves, e.g. `/blogs/[blog]`.
411
+ *
412
+ * Written in Next's vocabulary for both routers on purpose: the pattern is read
413
+ * by `parseRoutePattern`, the sitemap and the Studio's key inputs, none of which
414
+ * should have to know which framework the project uses. The TanStack branch
415
+ * translates that framework's conventions into it; see
416
+ * `tanStackSegmentsOfRoutePath` in `@valbuild/core` for the rules.
417
+ */
363
418
  function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
419
+ if (isTanStackRoutesFolder(srcFolder)) {
420
+ var routePath = moduleFilePath.slice(srcFolder.length).replace(/\.val\.[tj]sx?$/, "");
421
+ var segments = core.tanStackSegmentsOfRoutePath(routePath);
422
+ // "" rather than "/" for the root, so it matches what the Next branch
423
+ // returns for `/app/page.val.ts` — `parseRoutePattern` reads both as [].
424
+ return segments.length === 0 ? "" : "/".concat(segments.join("/"));
425
+ }
364
426
  return moduleFilePath.replace(srcFolder, "")
365
427
  // TODO: hacky!
366
428
  // remove route groups
@@ -379,9 +441,12 @@ exports._defineProperty = _defineProperty;
379
441
  exports._objectSpread2 = _objectSpread2;
380
442
  exports._typeof = _typeof;
381
443
  exports._unsupportedIterableToArray = _unsupportedIterableToArray;
382
- exports.getNextAppRouterSitemapTree = getNextAppRouterSitemapTree;
383
444
  exports.getNextAppRouterSourceFolder = getNextAppRouterSourceFolder;
445
+ exports.getPageRouterSitemapTree = getPageRouterSitemapTree;
446
+ exports.getPageRouterSourceFolder = getPageRouterSourceFolder;
384
447
  exports.getPatternFromModuleFilePath = getPatternFromModuleFilePath;
448
+ exports.getTanStackRouterSourceFolder = getTanStackRouterSourceFolder;
449
+ exports.isTanStackRoutesFolder = isTanStackRoutesFolder;
385
450
  exports.isValCanvasFrame = isValCanvasFrame;
386
451
  exports.isValCanvasPageMessage = isValCanvasPageMessage;
387
452
  exports.isValCanvasStudioMessage = isValCanvasStudioMessage;
@@ -137,6 +137,45 @@ function getNextAppRouterSourceFolder(moduleFilePath) {
137
137
  return null;
138
138
  }
139
139
 
140
+ /**
141
+ * The folder a TanStack Router app keeps its route files in.
142
+ *
143
+ * The same question as above for the other convention: `routes/` at the project
144
+ * root, or under `src/`. A Val module for a route lives beside the route file
145
+ * and is named the same way, so this is the prefix to strip before reading the
146
+ * route pattern out of the rest.
147
+ */
148
+ function getTanStackRouterSourceFolder(moduleFilePath) {
149
+ if (moduleFilePath.startsWith("/routes/")) {
150
+ return "/routes";
151
+ } else if (moduleFilePath.startsWith("/src/routes/")) {
152
+ return "/src/routes";
153
+ }
154
+ return null;
155
+ }
156
+
157
+ /**
158
+ * The route folder of whichever page router this module belongs to.
159
+ *
160
+ * The two conventions have disjoint prefixes — `app/` versus `routes/` — so a
161
+ * module file path answers this on its own, which is what the Studio needs: it
162
+ * walks every schema in the project and has no framework to ask.
163
+ */
164
+ function getPageRouterSourceFolder(moduleFilePath) {
165
+ var _getNextAppRouterSour;
166
+ return (_getNextAppRouterSour = getNextAppRouterSourceFolder(moduleFilePath)) !== null && _getNextAppRouterSour !== void 0 ? _getNextAppRouterSour : getTanStackRouterSourceFolder(moduleFilePath);
167
+ }
168
+
169
+ /**
170
+ * Whether a route folder is a TanStack Router one.
171
+ *
172
+ * Exported so the pattern derivation and the source-folder detection cannot
173
+ * drift apart about what `/src/routes` means.
174
+ */
175
+ function isTanStackRoutesFolder(srcFolder) {
176
+ return srcFolder === "/routes" || srcFolder === "/src/routes";
177
+ }
178
+
140
179
  function _toPrimitive(t, r) {
141
180
  if ("object" != typeof t || !t) return t;
142
181
  var e = t[Symbol.toPrimitive];
@@ -247,8 +286,14 @@ function _createForOfIteratorHelper(r, e) {
247
286
  };
248
287
  }
249
288
 
250
- // Strictly speaking this should be in the next package but it's shared, because we want to use it in the ui package. We want to resolve that somehow
251
- function getNextAppRouterSitemapTree(srcFolder, paths) {
289
+ // Strictly speaking this should be in the framework packages but it's shared,
290
+ // because we want to use it in the ui package. We want to resolve that somehow.
291
+ //
292
+ // It is one function for both page routers because the tree it builds is made
293
+ // of URL paths, which is the same thing in either: only `srcFolder` and the
294
+ // pattern derivation differ, and both of those are arguments (or the one call
295
+ // below).
296
+ function getPageRouterSitemapTree(srcFolder, paths) {
252
297
  var root = {
253
298
  type: "node",
254
299
  name: "/",
@@ -360,7 +405,24 @@ function getNextAppRouterSitemapTree(srcFolder, paths) {
360
405
  }
361
406
  return root;
362
407
  }
408
+
409
+ /**
410
+ * The route pattern a page-router module serves, e.g. `/blogs/[blog]`.
411
+ *
412
+ * Written in Next's vocabulary for both routers on purpose: the pattern is read
413
+ * by `parseRoutePattern`, the sitemap and the Studio's key inputs, none of which
414
+ * should have to know which framework the project uses. The TanStack branch
415
+ * translates that framework's conventions into it; see
416
+ * `tanStackSegmentsOfRoutePath` in `@valbuild/core` for the rules.
417
+ */
363
418
  function getPatternFromModuleFilePath(moduleFilePath, srcFolder) {
419
+ if (isTanStackRoutesFolder(srcFolder)) {
420
+ var routePath = moduleFilePath.slice(srcFolder.length).replace(/\.val\.[tj]sx?$/, "");
421
+ var segments = core.tanStackSegmentsOfRoutePath(routePath);
422
+ // "" rather than "/" for the root, so it matches what the Next branch
423
+ // returns for `/app/page.val.ts` — `parseRoutePattern` reads both as [].
424
+ return segments.length === 0 ? "" : "/".concat(segments.join("/"));
425
+ }
364
426
  return moduleFilePath.replace(srcFolder, "")
365
427
  // TODO: hacky!
366
428
  // remove route groups
@@ -379,9 +441,12 @@ exports._defineProperty = _defineProperty;
379
441
  exports._objectSpread2 = _objectSpread2;
380
442
  exports._typeof = _typeof;
381
443
  exports._unsupportedIterableToArray = _unsupportedIterableToArray;
382
- exports.getNextAppRouterSitemapTree = getNextAppRouterSitemapTree;
383
444
  exports.getNextAppRouterSourceFolder = getNextAppRouterSourceFolder;
445
+ exports.getPageRouterSitemapTree = getPageRouterSitemapTree;
446
+ exports.getPageRouterSourceFolder = getPageRouterSourceFolder;
384
447
  exports.getPatternFromModuleFilePath = getPatternFromModuleFilePath;
448
+ exports.getTanStackRouterSourceFolder = getTanStackRouterSourceFolder;
449
+ exports.isTanStackRoutesFolder = isTanStackRoutesFolder;
385
450
  exports.isValCanvasFrame = isValCanvasFrame;
386
451
  exports.isValCanvasPageMessage = isValCanvasPageMessage;
387
452
  exports.isValCanvasStudioMessage = isValCanvasStudioMessage;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@valbuild/core');
6
- var getSitemapTree = require('../../dist/getSitemapTree-a0c9a0e3.cjs.dev.js');
6
+ var getSitemapTree = require('../../dist/getSitemapTree-d1977d3e.cjs.dev.js');
7
7
  var zod = require('zod');
8
8
  var zodValidationError = require('zod-validation-error');
9
9
  var FlexSearch = require('flexsearch');
@@ -5557,9 +5557,12 @@ exports.VAL_CANVAS_MESSAGE = getSitemapTree.VAL_CANVAS_MESSAGE;
5557
5557
  exports.VAL_CANVAS_PARAM = getSitemapTree.VAL_CANVAS_PARAM;
5558
5558
  exports.VAL_CONFIG_SESSION_STORAGE_KEY = getSitemapTree.VAL_CONFIG_SESSION_STORAGE_KEY;
5559
5559
  exports.VAL_THEME_SESSION_STORAGE_KEY = getSitemapTree.VAL_THEME_SESSION_STORAGE_KEY;
5560
- exports.getNextAppRouterSitemapTree = getSitemapTree.getNextAppRouterSitemapTree;
5561
5560
  exports.getNextAppRouterSourceFolder = getSitemapTree.getNextAppRouterSourceFolder;
5561
+ exports.getPageRouterSitemapTree = getSitemapTree.getPageRouterSitemapTree;
5562
+ exports.getPageRouterSourceFolder = getSitemapTree.getPageRouterSourceFolder;
5562
5563
  exports.getPatternFromModuleFilePath = getSitemapTree.getPatternFromModuleFilePath;
5564
+ exports.getTanStackRouterSourceFolder = getSitemapTree.getTanStackRouterSourceFolder;
5565
+ exports.isTanStackRoutesFolder = getSitemapTree.isTanStackRoutesFolder;
5563
5566
  exports.isValCanvasFrame = getSitemapTree.isValCanvasFrame;
5564
5567
  exports.isValCanvasPageMessage = getSitemapTree.isValCanvasPageMessage;
5565
5568
  exports.isValCanvasStudioMessage = getSitemapTree.isValCanvasStudioMessage;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@valbuild/core');
6
- var getSitemapTree = require('../../dist/getSitemapTree-77b1203a.cjs.prod.js');
6
+ var getSitemapTree = require('../../dist/getSitemapTree-b320d033.cjs.prod.js');
7
7
  var zod = require('zod');
8
8
  var zodValidationError = require('zod-validation-error');
9
9
  var FlexSearch = require('flexsearch');
@@ -5557,9 +5557,12 @@ exports.VAL_CANVAS_MESSAGE = getSitemapTree.VAL_CANVAS_MESSAGE;
5557
5557
  exports.VAL_CANVAS_PARAM = getSitemapTree.VAL_CANVAS_PARAM;
5558
5558
  exports.VAL_CONFIG_SESSION_STORAGE_KEY = getSitemapTree.VAL_CONFIG_SESSION_STORAGE_KEY;
5559
5559
  exports.VAL_THEME_SESSION_STORAGE_KEY = getSitemapTree.VAL_THEME_SESSION_STORAGE_KEY;
5560
- exports.getNextAppRouterSitemapTree = getSitemapTree.getNextAppRouterSitemapTree;
5561
5560
  exports.getNextAppRouterSourceFolder = getSitemapTree.getNextAppRouterSourceFolder;
5561
+ exports.getPageRouterSitemapTree = getSitemapTree.getPageRouterSitemapTree;
5562
+ exports.getPageRouterSourceFolder = getSitemapTree.getPageRouterSourceFolder;
5562
5563
  exports.getPatternFromModuleFilePath = getSitemapTree.getPatternFromModuleFilePath;
5564
+ exports.getTanStackRouterSourceFolder = getSitemapTree.getTanStackRouterSourceFolder;
5565
+ exports.isTanStackRoutesFolder = getSitemapTree.isTanStackRoutesFolder;
5563
5566
  exports.isValCanvasFrame = getSitemapTree.isValCanvasFrame;
5564
5567
  exports.isValCanvasPageMessage = getSitemapTree.isValCanvasPageMessage;
5565
5568
  exports.isValCanvasStudioMessage = getSitemapTree.isValCanvasStudioMessage;
@@ -1,6 +1,6 @@
1
1
  import { Internal, CODE_LANGUAGES, DEFAULT_COLOR_FORMAT } from '@valbuild/core';
2
- import { _ as _createForOfIteratorHelper, k as _objectSpread2, l as _arrayLikeToArray, m as _unsupportedIterableToArray, n as _defineProperty, o as _typeof } from '../../dist/getSitemapTree-d3e98a2e.esm.js';
3
- export { b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, h as getNextAppRouterSitemapTree, g as getNextAppRouterSourceFolder, j as getPatternFromModuleFilePath, f as isValCanvasFrame, i as isValCanvasPageMessage, e as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-d3e98a2e.esm.js';
2
+ import { _ as _createForOfIteratorHelper, n as _objectSpread2, o as _arrayLikeToArray, q as _unsupportedIterableToArray, r as _defineProperty, s as _typeof } from '../../dist/getSitemapTree-a6cb37cb.esm.js';
3
+ export { b as VAL_AI_SESSION_STORAGE_KEY, d as VAL_CANVAS_MESSAGE, c as VAL_CANVAS_PARAM, V as VAL_CONFIG_SESSION_STORAGE_KEY, a as VAL_THEME_SESSION_STORAGE_KEY, g as getNextAppRouterSourceFolder, l as getPageRouterSitemapTree, j as getPageRouterSourceFolder, m as getPatternFromModuleFilePath, h as getTanStackRouterSourceFolder, k as isTanStackRoutesFolder, f as isValCanvasFrame, i as isValCanvasPageMessage, e as isValCanvasStudioMessage, p as parseRoutePattern, w as withValCanvasParam } from '../../dist/getSitemapTree-a6cb37cb.esm.js';
4
4
  import { z } from 'zod';
5
5
  import { fromError } from 'zod-validation-error';
6
6
  import FlexSearch from 'flexsearch';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/shared",
3
- "version": "0.124.0",
3
+ "version": "0.125.0",
4
4
  "private": false,
5
5
  "description": "Val shared types and utilities",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  "flexsearch": "^0.8.212",
38
38
  "zod": "^4.4.3",
39
39
  "zod-validation-error": "^5.0.0",
40
- "@valbuild/core": "0.124.0"
40
+ "@valbuild/core": "0.125.0"
41
41
  },
42
42
  "files": [
43
43
  "CHANGELOG.md",