{"version":3,"file":"plugin.js","sources":["../../../src/start-router-plugin/plugin.ts"],"sourcesContent":["import {\n  tanStackRouterCodeSplitter,\n  tanstackRouterAutoImport,\n  tanstackRouterGenerator,\n} from '@tanstack/router-plugin/vite'\nimport { normalizePath } from 'vite'\nimport path from 'pathe'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { routesManifestPlugin } from './generator-plugins/routes-manifest-plugin'\nimport { prerenderRoutesPlugin } from './generator-plugins/prerender-routes-plugin'\nimport { pruneServerOnlySubtrees } from './pruneServerOnlySubtrees'\nimport { SERVER_PROP } from './constants'\nimport type { GetConfigFn, TanStackStartVitePluginCoreOptions } from '../types'\nimport type {\n  Generator,\n  GeneratorPlugin,\n  RouteNode,\n} from '@tanstack/router-generator'\nimport type { DevEnvironment, Plugin, PluginOption } from 'vite'\nimport type { TanStackStartInputConfig } from '../schema'\n\nfunction isServerOnlyNode(node: RouteNode | undefined) {\n  if (!node?.createFileRouteProps) {\n    return false\n  }\n  return (\n    node.createFileRouteProps.has(SERVER_PROP) &&\n    node.createFileRouteProps.size === 1\n  )\n}\n\nfunction moduleDeclaration({\n  startFilePath,\n  routerFilePath,\n  corePluginOpts,\n  generatedRouteTreePath,\n}: {\n  startFilePath: string | undefined\n  routerFilePath: string\n  corePluginOpts: TanStackStartVitePluginCoreOptions\n  generatedRouteTreePath: string\n}): string {\n  function getImportPath(absolutePath: string) {\n    let relativePath = path.relative(\n      path.dirname(generatedRouteTreePath),\n      absolutePath,\n    )\n\n    if (!relativePath.startsWith('.')) {\n      relativePath = './' + relativePath\n    }\n\n    // convert to POSIX-style for ESM imports (important on Windows)\n    relativePath = relativePath.split(path.sep).join('/')\n    return relativePath\n  }\n\n  const result: Array<string> = [\n    `import type { getRouter } from '${getImportPath(routerFilePath)}'`,\n  ]\n  if (startFilePath) {\n    result.push(\n      `import type { startInstance } from '${getImportPath(startFilePath)}'`,\n    )\n  }\n  // make sure we import something from start to get the server route declaration merge\n  else {\n    result.push(\n      `import type { createStart } from '@tanstack/${corePluginOpts.framework}-start'`,\n    )\n  }\n  result.push(\n    `declare module '@tanstack/${corePluginOpts.framework}-start' {\n  interface Register {\n    ssr: true\n    router: Awaited<ReturnType<typeof getRouter>>`,\n  )\n  if (startFilePath) {\n    result.push(\n      `    config: Awaited<ReturnType<typeof startInstance.getOptions>>`,\n    )\n  }\n  result.push(`  }\n}`)\n\n  return result.join('\\n')\n}\n\nexport function tanStackStartRouter(\n  startPluginOpts: TanStackStartInputConfig,\n  getConfig: GetConfigFn,\n  corePluginOpts: TanStackStartVitePluginCoreOptions,\n): Array<PluginOption> {\n  const getGeneratedRouteTreePath = () => {\n    const { startConfig } = getConfig()\n    return path.resolve(startConfig.router.generatedRouteTree)\n  }\n\n  let clientEnvironment: DevEnvironment | null = null\n  function invalidate() {\n    if (!clientEnvironment) {\n      return\n    }\n\n    const mod = clientEnvironment.moduleGraph.getModuleById(\n      getGeneratedRouteTreePath(),\n    )\n    if (mod) {\n      clientEnvironment.moduleGraph.invalidateModule(mod)\n    }\n    clientEnvironment.hot.send({ type: 'full-reload', path: '*' })\n  }\n\n  let generatorInstance: Generator | null = null\n\n  const clientTreeGeneratorPlugin: GeneratorPlugin = {\n    name: 'start-client-tree-plugin',\n    init({ generator }) {\n      generatorInstance = generator\n    },\n    afterTransform({ node, prevNode }) {\n      if (isServerOnlyNode(node) !== isServerOnlyNode(prevNode)) {\n        invalidate()\n      }\n    },\n  }\n\n  let routeTreeFileFooter: Array<string> | null = null\n\n  function getRouteTreeFileFooter() {\n    if (routeTreeFileFooter) {\n      return routeTreeFileFooter\n    }\n    const { startConfig, resolvedStartConfig } = getConfig()\n    const ogRouteTreeFileFooter = startConfig.router.routeTreeFileFooter\n    if (ogRouteTreeFileFooter) {\n      if (Array.isArray(ogRouteTreeFileFooter)) {\n        routeTreeFileFooter = ogRouteTreeFileFooter\n      } else {\n        routeTreeFileFooter = ogRouteTreeFileFooter()\n      }\n    }\n    routeTreeFileFooter = [\n      moduleDeclaration({\n        generatedRouteTreePath: getGeneratedRouteTreePath(),\n        corePluginOpts,\n        startFilePath: resolvedStartConfig.startFilePath,\n        routerFilePath: resolvedStartConfig.routerFilePath,\n      }),\n      ...(routeTreeFileFooter ?? []),\n    ]\n    return routeTreeFileFooter\n  }\n\n  let resolvedGeneratedRouteTreePath: string | null = null\n  const clientTreePlugin: Plugin = {\n    name: 'tanstack-start:route-tree-client-plugin',\n    enforce: 'pre',\n    applyToEnvironment: (env) => env.name === VITE_ENVIRONMENT_NAMES.client,\n    configureServer(server) {\n      clientEnvironment = server.environments[VITE_ENVIRONMENT_NAMES.client]\n    },\n    config() {\n      type LoadObjectHook = Extract<\n        typeof clientTreePlugin.load,\n        { filter?: unknown }\n      >\n      resolvedGeneratedRouteTreePath = normalizePath(\n        getGeneratedRouteTreePath(),\n      )\n      ;(clientTreePlugin.load as LoadObjectHook).filter = {\n        id: { include: new RegExp(resolvedGeneratedRouteTreePath) },\n      }\n    },\n\n    load: {\n      filter: {\n        // this will be set in the config hook above since it relies on `config` hook being called first\n      },\n      async handler() {\n        if (!generatorInstance) {\n          throw new Error('Generator instance not initialized')\n        }\n        const crawlingResult = await generatorInstance.getCrawlingResult()\n        if (!crawlingResult) {\n          throw new Error('Crawling result not available')\n        }\n        const prunedAcc = pruneServerOnlySubtrees(crawlingResult)\n        const acc = {\n          ...crawlingResult.acc,\n          ...prunedAcc,\n        }\n        const buildResult = generatorInstance.buildRouteTree({\n          ...crawlingResult,\n          acc,\n          config: {\n            // importRoutesUsingAbsolutePaths: true,\n            // addExtensions: true,\n            disableTypes: true,\n            enableRouteTreeFormatting: false,\n            routeTreeFileHeader: [],\n            routeTreeFileFooter: [],\n          },\n        })\n        return { code: buildResult.routeTreeContent, map: null }\n      },\n    },\n  }\n  return [\n    clientTreePlugin,\n    tanstackRouterGenerator(() => {\n      const routerConfig = getConfig().startConfig.router\n      const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]\n      if (startPluginOpts?.prerender?.enabled === true) {\n        plugins.push(prerenderRoutesPlugin())\n      }\n      return {\n        ...routerConfig,\n        target: corePluginOpts.framework,\n        routeTreeFileFooter: getRouteTreeFileFooter,\n        plugins,\n      }\n    }),\n    tanStackRouterCodeSplitter(() => {\n      const routerConfig = getConfig().startConfig.router\n      return {\n        ...routerConfig,\n        codeSplittingOptions: {\n          ...routerConfig.codeSplittingOptions,\n          deleteNodes: ['ssr', 'server', 'headers'],\n          addHmr: true,\n        },\n        plugin: {\n          vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },\n        },\n      }\n    }),\n    tanStackRouterCodeSplitter(() => {\n      const routerConfig = getConfig().startConfig.router\n      return {\n        ...routerConfig,\n        codeSplittingOptions: {\n          ...routerConfig.codeSplittingOptions,\n          addHmr: false,\n        },\n        plugin: {\n          vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },\n        },\n      }\n    }),\n    tanstackRouterAutoImport(startPluginOpts?.router),\n  ]\n}\n"],"names":["path"],"mappings":"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"}