pagegraph 0.11.0 → 0.12.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.
Files changed (65) hide show
  1. package/README.md +140 -137
  2. package/dist/audit.d.ts +1 -1
  3. package/dist/audit.js +1 -1
  4. package/dist/build-only/audit.d.ts +1 -0
  5. package/dist/build-only/audit.js +6 -0
  6. package/dist/build-only/audit.js.map +1 -0
  7. package/dist/build-only/config.d.ts +1 -0
  8. package/dist/build-only/config.js +6 -0
  9. package/dist/build-only/config.js.map +1 -0
  10. package/dist/build-only/tanstack-start.d.ts +1 -0
  11. package/dist/build-only/tanstack-start.js +6 -0
  12. package/dist/build-only/tanstack-start.js.map +1 -0
  13. package/dist/build-only/vite.d.ts +1 -0
  14. package/dist/build-only/vite.js +6 -0
  15. package/dist/build-only/vite.js.map +1 -0
  16. package/dist/{checks-nk8ZRRIA.js → checks-uZk5Em9A.js} +3 -141
  17. package/dist/checks-uZk5Em9A.js.map +1 -0
  18. package/dist/cli.js +393 -287
  19. package/dist/cli.js.map +1 -1
  20. package/dist/config.d.ts +7 -66
  21. package/dist/config.js +3 -122
  22. package/dist/config.js.map +1 -1
  23. package/dist/{content-DVL2iyGU.d.ts → content-B1cPtL8b.d.ts} +4 -128
  24. package/dist/{content-CB_kHmJ3.js → content-kcEnQdfi.js} +3 -2
  25. package/dist/{content-CB_kHmJ3.js.map → content-kcEnQdfi.js.map} +1 -1
  26. package/dist/declare-D5o7hwmv.js +9 -0
  27. package/dist/declare-D5o7hwmv.js.map +1 -0
  28. package/dist/declare-DVgdEdOL.d.ts +12127 -0
  29. package/dist/graph-Bcsourlv.js +162 -0
  30. package/dist/graph-Bcsourlv.js.map +1 -0
  31. package/dist/graph-BxCY90vq.d.ts +104 -0
  32. package/dist/graph-CBIY71w6.d.ts +57 -0
  33. package/dist/index.d.ts +37 -73
  34. package/dist/index.js +23 -134
  35. package/dist/index.js.map +1 -1
  36. package/dist/message-DT_CjUdt.js +12 -0
  37. package/dist/message-DT_CjUdt.js.map +1 -0
  38. package/dist/page-heads-6y-CARRQ.js +25 -0
  39. package/dist/page-heads-6y-CARRQ.js.map +1 -0
  40. package/dist/page-heads-DNkjMUEN.d.ts +21 -0
  41. package/dist/projections-D0oOFKiY.js +142 -0
  42. package/dist/projections-D0oOFKiY.js.map +1 -0
  43. package/dist/projections-DeEFe7XT.d.ts +78 -0
  44. package/dist/react.d.ts +26 -12051
  45. package/dist/react.js +12 -3
  46. package/dist/react.js.map +1 -1
  47. package/dist/route-config-35ZEzkNC.js +308 -0
  48. package/dist/route-config-35ZEzkNC.js.map +1 -0
  49. package/dist/route-config-wneg6ktn.d.ts +29 -0
  50. package/dist/tanstack-start/index.d.ts +40 -0
  51. package/dist/tanstack-start/index.js +368 -0
  52. package/dist/tanstack-start/index.js.map +1 -0
  53. package/dist/tanstack-start/server.d.ts +14 -0
  54. package/dist/tanstack-start/server.js +53 -0
  55. package/dist/tanstack-start/server.js.map +1 -0
  56. package/dist/vite-graph-loader-01p1WxEq.js +104 -0
  57. package/dist/vite-graph-loader-01p1WxEq.js.map +1 -0
  58. package/dist/vite-graph-loader-Btgjz5RH.d.ts +56 -0
  59. package/dist/vite.d.ts +2 -28
  60. package/dist/vite.js +1 -307
  61. package/dist/wire-B4RQMc4e.js +26 -0
  62. package/dist/wire-B4RQMc4e.js.map +1 -0
  63. package/package.json +27 -5
  64. package/dist/checks-nk8ZRRIA.js.map +0 -1
  65. package/dist/vite.js.map +0 -1
package/dist/vite.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"vite.js","names":["statFile","openFile"],"sources":["../src/vite/index.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { open as openFile, stat as statFile } from \"node:fs/promises\";\nimport { basename, normalize, resolve } from \"node:path\";\n\nimport {\n Generator,\n getConfig,\n type GeneratorEvent,\n type GeneratorPlugin,\n type RouteNode,\n} from \"@tanstack/router-generator\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Derives a route-config module from the parsed TanStack route tree.\n *\n * The route tree is the single source of truth for which paths exist; this\n * plugin projects it into the small config the host consumes at runtime:\n * - `robotsExclusions` — path prefixes disallowed in robots.txt (feed them to\n * `renderRobots`).\n * - `reservedSegments` — top-level path segments the app must not hand out (an\n * org slug, a tenant name). Derived from the full public route surface — the\n * `publicGroups` route groups plus the group-less `extraPublicRoutes` — which\n * is parsed here but not emitted: \"which pages are public\" already has a\n * canonical runtime answer in the SEO graph.\n *\n * It also enforces that every page in `enforceCoverageIn` declares its SEO: a\n * page leaf missing both `staticData` and `head` fails dev startup and build.\n *\n * **Why we run our own Generator.** The parse must come from\n * `@tanstack/router-generator` itself — a second, hand-rolled scanner would\n * drift from TanStack's group/param/layout conventions. But routing our plugin\n * through TanStack Start does not work: `start-plugin-core` builds its own\n * generator-plugin array and drops `router.plugins` on the floor\n * (tanstack/router#7768 — `plugins` is not public API there), and even when\n * forced through, the router unplugin wraps `generator.run()` in\n * `catch (e) { console.error(e) }`, so a plugin can never fail a build.\n *\n * So we instantiate `Generator` ourselves — `config.plugins` is natively\n * honored on our own instance, and because we own the `.run()` call site a\n * coverage violation throws straight out of `buildStart`. Cost: route files are\n * parsed twice at startup (~40 files, milliseconds) — the host's router plugin\n * still owns the real `routeTree.gen.ts`; ours is a shadow parse whose route\n * tree is thrown away (see {@link inMemoryWriteFs}).\n *\n * `onRouteTreeChanged` fires on every generator run, but the config is written\n * only when its content changes, and the output path lives outside the routes\n * directory, so regeneration never feeds back into the watcher.\n */\n\nconst PLUGIN_NAME = \"seo-route-config\";\n\n/** Match a route's group folder (`filePath` is relative to the routes directory). */\nfunction groupOf(filePath: string, groups: ReadonlyArray<string>): string | undefined {\n return groups.find((group) => filePath.startsWith(`${group}/`));\n}\n\n/**\n * A page leaf is a `.tsx` route file that is not a `route.tsx` layout. This\n * excludes layout wrappers, `.ts` server routes (robots.txt / sitemap.xml /\n * markdown mirrors), and any other non-page file — matching the leaves that\n * contribute a crawlable URL.\n */\nfunction isPageLeaf(node: RouteNode): boolean {\n return node.filePath.endsWith(\".tsx\") && basename(node.filePath) !== \"route.tsx\";\n}\n\n/**\n * Convert a group-prefixed routePath (e.g. \"/(marketing)/blog/$slug\") into the\n * public URL form used by route-config (\"/blog/*\"): drop the group segment,\n * collapse the first dynamic/splat segment and everything after it to \"*\", and\n * trim the index trailing slash.\n */\nfunction routePathToPublicUrl(routePath: string): string {\n const stripped = routePath.replace(/^\\/\\([^)]+\\)/, \"\");\n if (stripped === \"\" || stripped === \"/\") return \"/\";\n\n const segments = stripped.split(\"/\");\n const dynamicIndex = segments.findIndex((segment) => segment.startsWith(\"$\"));\n if (dynamicIndex !== -1) {\n return `${segments.slice(0, dynamicIndex).join(\"/\")}/*`;\n }\n\n return stripped.endsWith(\"/\") ? stripped.slice(0, -1) : stripped;\n}\n\n/**\n * First path segment of each route, reserved so it can't be claimed as an org\n * slug. Strip the leading slash and a trailing \"/*\", then take the first\n * segment (\"/features/email\" -> \"features\").\n */\nfunction extractReservedSegments(routes: ReadonlyArray<string>): Array<string> {\n const segments = new Set<string>();\n for (const route of routes) {\n const first = route.replace(/^\\//, \"\").replace(/\\/\\*$/, \"\").split(\"/\")[0];\n if (first) segments.add(first);\n }\n return Array.from(segments).sort();\n}\n\n/**\n * robots.txt disallow prefixes are directory prefixes, so a splat route\n * (\"/reset-password/*\") disallows the whole subtree (\"/reset-password\").\n */\nfunction normalizeRoutePrefix(route: string): string {\n const cleaned = route.replace(/\\/\\*$/, \"\");\n return cleaned === \"\" ? \"/\" : cleaned;\n}\n\ninterface RouteConfigShape {\n robotsExclusions: Array<string>;\n reservedSegments: Array<string>;\n}\n\nfunction deriveRouteConfig(\n routeNodes: ReadonlyArray<RouteNode>,\n options: ResolvedOptions,\n): RouteConfigShape {\n const publicUrls = new Set<string>(options.extraPublicRoutes);\n const disallowedUrls = new Set<string>();\n\n for (const node of routeNodes) {\n const group = groupOf(node.filePath, options.publicGroups);\n if (group === undefined || !isPageLeaf(node) || node.routePath === undefined) continue;\n const url = routePathToPublicUrl(node.routePath);\n publicUrls.add(url);\n if (options.disallowGroups.includes(group)) disallowedUrls.add(url);\n }\n\n const reservedSegments = [\n ...extractReservedSegments([...publicUrls].sort()),\n ...options.reservedExtras,\n ].sort();\n\n const robotsExclusions = [\n ...new Set([...options.alwaysDisallow, ...[...disallowedUrls].map(normalizeRoutePrefix)]),\n ].sort();\n\n return { robotsExclusions, reservedSegments };\n}\n\n/**\n * Every page in an enforced group must declare its search presence. A leaf that\n * passes neither `staticData` (from which the SEO graph reads `staticData.seo`)\n * nor `head` has no path to correct metadata.\n */\nfunction findCoverageViolations(\n routeNodes: ReadonlyArray<RouteNode>,\n options: ResolvedOptions,\n): Array<string> {\n const violations: Array<string> = [];\n for (const node of routeNodes) {\n const group = groupOf(node.filePath, options.enforceCoverageIn);\n if (group === undefined || !isPageLeaf(node)) continue;\n\n const props = node.createFileRouteProps;\n if (props?.has(\"staticData\") || props?.has(\"head\")) continue;\n\n violations.push(`${node.filePath} (${group} page)`);\n }\n return violations;\n}\n\nfunction coverageMessage(violations: ReadonlyArray<string>): string {\n return (\n `[${PLUGIN_NAME}] ${violations.length} page(s) declare neither staticData nor ` +\n `head. Every page in an SEO-enforced route group must declare its SEO — add ` +\n `staticData: { seo: ... } or a head() to each route:\\n - ${violations.join(\"\\n - \")}`\n );\n}\n\nconst HEADER =\n `// Auto-generated by the ${PLUGIN_NAME} Vite plugin.\\n` +\n \"// DO NOT EDIT MANUALLY — regenerated from the route tree on every dev/build.\\n\";\n\nfunction renderRouteConfig(config: RouteConfigShape): string {\n return `${HEADER}\nexport const routeConfig = ${JSON.stringify(config, null, 2)} as const;\n\nexport type RouteConfig = typeof routeConfig;\n`;\n}\n\nfunction routeConfigGeneratorPlugin(options: ResolvedOptions): GeneratorPlugin {\n const { outputPath } = options;\n return {\n name: PLUGIN_NAME,\n init() {\n // The caller passes an explicit absolute output path, so a relocated routes\n // directory can never silently retarget the write. Guard the parent directory\n // here so a bad path fails at startup, not mid-watch.\n if (!existsSync(resolve(outputPath, \"..\"))) {\n throw new Error(\n `[${PLUGIN_NAME}] output directory does not exist: ${resolve(outputPath, \"..\")}`,\n );\n }\n },\n onRouteTreeChanged({ routeNodes }) {\n const violations = findCoverageViolations(routeNodes, options);\n if (violations.length > 0) throw new Error(coverageMessage(violations));\n\n const content = renderRouteConfig(deriveRouteConfig(routeNodes, options));\n const existing = existsSync(outputPath) ? readFileSync(outputPath, \"utf8\") : undefined;\n if (existing !== content) writeFileSync(outputPath, content);\n },\n };\n}\n\n/**\n * A `Generator` filesystem that reads real files but keeps every write in\n * memory, so our shadow parse cannot touch the repo.\n *\n * The Generator writes through `safeFileWrite`: `writeFile(<tmp>)`, then\n * `rename(<tmp>, <dest>)`. Two destinations exist, and neither may land:\n * - the route tree — we point it at a throwaway path and hold it in memory, so\n * the only route tree on disk stays the one the host's router plugin writes;\n * - route source files — the Generator normalizes them (`createFileRoute` ids,\n * code-split transforms). The host's generator already did that with its own\n * config; ours is not the host's, so such a write is dropped rather than\n * allowed to fight it.\n *\n * Reads and stats of real files go to disk, which keeps the Generator's mtime\n * cache honest: a route edited mid-watch is always seen.\n */\nfunction inMemoryWriteFs(routeTreePath: string) {\n const written = new Map<string, { content: string; mtimeMs: bigint }>();\n let clock = 0n;\n const tick = () => (clock += 1n);\n\n return {\n /**\n * The in-memory route tree is invisible to the watcher, so nothing else can\n * mark it stale. Bumping its mtime before each run is what makes the\n * Generator rebuild the tree — and therefore re-fire `onRouteTreeChanged`\n * — on every run, not only when the set of routes changes. Coverage and the\n * derived config depend on route *contents* (`staticData` / `head`), which\n * leave the route tree itself untouched.\n */\n touchRouteTree() {\n const file = written.get(routeTreePath);\n if (file) written.set(routeTreePath, { content: file.content, mtimeMs: tick() });\n },\n fs: {\n async stat(filePath: string) {\n const file = written.get(filePath);\n if (file) return { mtimeMs: file.mtimeMs, mode: 0o100644, uid: 0, gid: 0 };\n const real = await statFile(filePath, { bigint: true });\n return {\n mtimeMs: real.mtimeMs,\n mode: Number(real.mode),\n uid: Number(real.uid),\n gid: Number(real.gid),\n };\n },\n async readFile(filePath: string) {\n const file = written.get(filePath);\n if (file) return { stat: { mtimeMs: file.mtimeMs }, fileContent: file.content };\n if (!existsSync(filePath)) return \"file-not-existing\" as const;\n const handle = await openFile(filePath, \"r\");\n const fileStat = await handle.stat({ bigint: true });\n const fileContent = (await handle.readFile()).toString();\n await handle.close();\n return { stat: { mtimeMs: fileStat.mtimeMs }, fileContent };\n },\n async writeFile(filePath: string, content: string) {\n written.set(filePath, { content, mtimeMs: tick() });\n },\n async rename(oldPath: string, newPath: string) {\n const file = written.get(oldPath);\n written.delete(oldPath);\n // Anything but the throwaway route tree — i.e. a route source file — is\n // dropped here, which is the whole point: this generator never writes.\n if (file && newPath === routeTreePath) {\n written.set(newPath, { content: file.content, mtimeMs: tick() });\n }\n },\n async chmod() {},\n async chown() {},\n },\n };\n}\n\nexport interface SeoRouteConfigOptions {\n /** Absolute path the generated route-config module is written to. */\n outputPath: string;\n /** Route groups whose page leaves form the public surface. Include the parens. */\n publicGroups: ReadonlyArray<string>;\n /** Route groups where every page leaf must declare `staticData` or `head`. */\n enforceCoverageIn: ReadonlyArray<string>;\n /** Route groups whose page paths are disallowed in robots.txt (e.g. auth). */\n disallowGroups?: ReadonlyArray<string> | undefined;\n /** Public routes that live outside any group folder, so nothing discovers them. */\n extraPublicRoutes?: ReadonlyArray<string> | undefined;\n /** Reserved top-level segments that are not route-tree paths (e.g. an api mount). */\n reservedExtras?: ReadonlyArray<string> | undefined;\n /** Prefixes always disallowed in robots.txt, route tree or not. */\n alwaysDisallow?: ReadonlyArray<string> | undefined;\n /** Routes directory, relative to the Vite root. Defaults to `src/routes`. */\n routesDirectory?: string | undefined;\n}\n\ninterface ResolvedOptions {\n outputPath: string;\n publicGroups: ReadonlyArray<string>;\n enforceCoverageIn: ReadonlyArray<string>;\n disallowGroups: ReadonlyArray<string>;\n extraPublicRoutes: ReadonlyArray<string>;\n reservedExtras: ReadonlyArray<string>;\n alwaysDisallow: ReadonlyArray<string>;\n routesDirectory: string;\n}\n\nfunction resolveOptions(options: SeoRouteConfigOptions): ResolvedOptions {\n return {\n outputPath: options.outputPath,\n publicGroups: options.publicGroups,\n enforceCoverageIn: options.enforceCoverageIn,\n disallowGroups: options.disallowGroups ?? [],\n extraPublicRoutes: options.extraPublicRoutes ?? [],\n reservedExtras: options.reservedExtras ?? [],\n alwaysDisallow: options.alwaysDisallow ?? [],\n routesDirectory: options.routesDirectory ?? \"src/routes\",\n };\n}\n\n/**\n * Vite plugin that runs its own `@tanstack/router-generator` instance over the\n * routes directory and derives the route-config module from the result.\n */\nexport function seoRouteConfig(options: SeoRouteConfigOptions): Plugin {\n const resolved = resolveOptions(options);\n\n let generator: Generator | undefined;\n let touchRouteTree: (() => void) | undefined;\n let routesDirectory: string | undefined;\n\n /**\n * A throw here propagates: it fails `vite build` and dev startup, which is\n * the reason we own this call site instead of registering through Start.\n */\n const run = async (event?: GeneratorEvent) => {\n if (generator === undefined || touchRouteTree === undefined) {\n throw new Error(`[${PLUGIN_NAME}] generator was not initialized by configResolved`);\n }\n touchRouteTree();\n await generator.run(event);\n };\n\n return {\n name: PLUGIN_NAME,\n enforce: \"pre\",\n configResolved(config) {\n const root = config.root;\n // The route tree we generate is a byproduct we never want on disk; park it\n // (and the generator's temp files) inside node_modules so a stray write\n // could never show up as a repo change.\n const cacheDirectory = resolve(root, `node_modules/.cache/${PLUGIN_NAME}`);\n routesDirectory = resolve(root, resolved.routesDirectory);\n const generatorConfig = getConfig(\n {\n routesDirectory,\n generatedRouteTree: resolve(cacheDirectory, \"route-tree.gen.ts\"),\n tmpDir: resolve(cacheDirectory, \"tmp\"),\n plugins: [routeConfigGeneratorPlugin(resolved)],\n // The route tree is thrown away — skip its type emission and its\n // prettier pass.\n disableTypes: true,\n enableRouteTreeFormatting: false,\n // The host's generator is the one that reports on the route tree; this\n // second pass over the same files would only echo it.\n disableLogging: true,\n },\n root,\n );\n\n const memory = inMemoryWriteFs(generatorConfig.generatedRouteTree);\n touchRouteTree = memory.touchRouteTree;\n generator = new Generator({ config: generatorConfig, root, fs: memory.fs });\n },\n async buildStart() {\n await run();\n },\n // Vite watches the whole project, but only a route file can change the tree\n // or a route's declared options. Without this guard every CSS/component edit\n // would re-run the generator and its coverage pass (`touchRouteTree` forces\n // a rebuild, so the Generator's own short-circuit can't absorb them).\n async watchChange(id, { event }) {\n const file = normalize(id);\n if (routesDirectory === undefined || !file.startsWith(routesDirectory)) return;\n await run({ path: file, type: event });\n },\n };\n}\n"],"mappings":"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"}