"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
0 && (module.exports = {
    generateLinkTypesFile: null,
    generateRouteTypesFile: null,
    generateValidatorFile: null
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    generateLinkTypesFile: function() {
        return generateLinkTypesFile;
    },
    generateRouteTypesFile: function() {
        return generateRouteTypesFile;
    },
    generateValidatorFile: function() {
        return generateValidatorFile;
    }
});
const _isdynamic = require("../../../shared/lib/router/utils/is-dynamic");
function generateRouteTypes(routesManifest) {
    const appRoutes = Object.keys(routesManifest.appRoutes).sort();
    const pageRoutes = Object.keys(routesManifest.pageRoutes).sort();
    const layoutRoutes = Object.keys(routesManifest.layoutRoutes).sort();
    const redirectRoutes = Object.keys(routesManifest.redirectRoutes).sort();
    const rewriteRoutes = Object.keys(routesManifest.rewriteRoutes).sort();
    let result = '';
    // Generate AppRoutes union type (pages only)
    if (appRoutes.length > 0) {
        result += `type AppRoutes = ${appRoutes.map((route)=>JSON.stringify(route)).join(' | ')}\n`;
    } else {
        result += 'type AppRoutes = never\n';
    }
    // Generate AppRouteHandlerRoutes union type for route handlers
    const appRouteHandlerRoutes = Object.keys(routesManifest.appRouteHandlerRoutes).sort();
    const hasAppRouteHandlers = appRouteHandlerRoutes.length > 0;
    if (hasAppRouteHandlers) {
        result += `type AppRouteHandlerRoutes = ${appRouteHandlerRoutes.map((route)=>JSON.stringify(route)).join(' | ')}\n`;
    }
    // Generate PageRoutes union type
    if (pageRoutes.length > 0) {
        result += `type PageRoutes = ${pageRoutes.map((route)=>JSON.stringify(route)).join(' | ')}\n`;
    } else {
        result += 'type PageRoutes = never\n';
    }
    // Generate LayoutRoutes union type
    if (layoutRoutes.length > 0) {
        result += `type LayoutRoutes = ${layoutRoutes.map((route)=>JSON.stringify(route)).join(' | ')}\n`;
    } else {
        result += 'type LayoutRoutes = never\n';
    }
    // Generate RedirectRoutes union type
    if (redirectRoutes.length > 0) {
        result += `type RedirectRoutes = ${redirectRoutes.map((route)=>JSON.stringify(route)).join(' | ')}\n`;
    } else {
        result += 'type RedirectRoutes = never\n';
    }
    // Generate RewriteRoutes union type
    if (rewriteRoutes.length > 0) {
        result += `type RewriteRoutes = ${rewriteRoutes.map((route)=>JSON.stringify(route)).join(' | ')}\n`;
    } else {
        result += 'type RewriteRoutes = never\n';
    }
    // Only include AppRouteHandlerRoutes in Routes union if there are actual route handlers
    const routeUnionParts = [
        'AppRoutes',
        'PageRoutes',
        'LayoutRoutes',
        'RedirectRoutes',
        'RewriteRoutes'
    ];
    if (hasAppRouteHandlers) {
        routeUnionParts.push('AppRouteHandlerRoutes');
    }
    result += `type Routes = ${routeUnionParts.join(' | ')}\n`;
    return result;
}
function generateParamTypes(routesManifest) {
    const allRoutes = {
        ...routesManifest.appRoutes,
        ...routesManifest.appRouteHandlerRoutes,
        ...routesManifest.pageRoutes,
        ...routesManifest.layoutRoutes,
        ...routesManifest.redirectRoutes,
        ...routesManifest.rewriteRoutes
    };
    let paramTypes = 'interface ParamMap {\n';
    // Sort routes deterministically for consistent output
    const sortedRoutes = Object.entries(allRoutes).sort(([a], [b])=>a.localeCompare(b));
    for (const [route, routeInfo] of sortedRoutes){
        const { groups } = routeInfo;
        // For static routes (no dynamic segments), we can produce an empty parameter map.
        if (!(0, _isdynamic.isDynamicRoute)(route) || Object.keys(groups ?? {}).length === 0) {
            paramTypes += `  ${JSON.stringify(route)}: {}\n`;
            continue;
        }
        let paramType = '{';
        // Process each group based on its properties
        for (const [key, group] of Object.entries(groups)){
            const escapedKey = JSON.stringify(key);
            if (group.repeat) {
                // Catch-all parameters
                if (group.optional) {
                    paramType += ` ${escapedKey}?: string[];`;
                } else {
                    paramType += ` ${escapedKey}: string[];`;
                }
            } else {
                // Regular parameters
                if (group.optional) {
                    paramType += ` ${escapedKey}?: string;`;
                } else {
                    paramType += ` ${escapedKey}: string;`;
                }
            }
        }
        paramType += ' }';
        paramTypes += `  ${JSON.stringify(route)}: ${paramType}\n`;
    }
    paramTypes += '}\n';
    return paramTypes;
}
function generateLayoutSlotMap(routesManifest) {
    let slotMap = 'interface LayoutSlotMap {\n';
    // Sort routes deterministically for consistent output
    const sortedLayoutRoutes = Object.entries(routesManifest.layoutRoutes).sort(([a], [b])=>a.localeCompare(b));
    for (const [route, routeInfo] of sortedLayoutRoutes){
        if ('slots' in routeInfo) {
            const slots = routeInfo.slots.sort();
            if (slots.length > 0) {
                slotMap += `  ${JSON.stringify(route)}: ${slots.map((slot)=>JSON.stringify(slot)).join(' | ')}\n`;
            } else {
                slotMap += `  ${JSON.stringify(route)}: never\n`;
            }
        } else {
            slotMap += `  ${JSON.stringify(route)}: never\n`;
        }
    }
    slotMap += '}\n';
    return slotMap;
}
// Helper function to format routes to route types (matches the plugin logic exactly)
function formatRouteToRouteType(route) {
    const isDynamic = (0, _isdynamic.isDynamicRoute)(route);
    if (isDynamic) {
        route = route.split('/').map((part)=>{
            if (part.startsWith('[') && part.endsWith(']')) {
                if (part.startsWith('[...')) {
                    // /[...slug]
                    return `\${CatchAllSlug<T>}`;
                } else if (part.startsWith('[[...') && part.endsWith(']]')) {
                    // /[[...slug]]
                    return `\${OptionalCatchAllSlug<T>}`;
                }
                // /[slug]
                return `\${SafeSlug<T>}`;
            }
            return part;
        }).join('/');
    }
    return {
        isDynamic,
        routeType: route
    };
}
// Helper function to serialize route types (matches the plugin logic exactly)
function serializeRouteTypes(routeTypes) {
    // route collection is not deterministic, this makes the output of the file deterministic
    return routeTypes.sort().map((route)=>`\n    | \`${route}\``).join('');
}
function generateLinkTypesFile(routesManifest) {
    // Generate serialized static and dynamic routes for the internal namespace
    // Build a unified set of routes across app/pages/redirect/rewrite as well as
    // app route handlers and Pages Router API routes.
    const allRoutesSet = new Set([
        ...Object.keys(routesManifest.appRoutes),
        ...Object.keys(routesManifest.pageRoutes),
        ...Object.keys(routesManifest.redirectRoutes),
        ...Object.keys(routesManifest.rewriteRoutes),
        // Allow linking to App Route Handlers (e.g. `/logout/route.ts`)
        ...Object.keys(routesManifest.appRouteHandlerRoutes),
        // Allow linking to Pages Router API routes (e.g. `/api/*`)
        ...Array.from(routesManifest.pageApiRoutes)
    ]);
    const staticRouteTypes = [];
    const dynamicRouteTypes = [];
    // Process each route using the same logic as the plugin
    for (const route of allRoutesSet){
        const { isDynamic, routeType } = formatRouteToRouteType(route);
        if (isDynamic) {
            dynamicRouteTypes.push(routeType);
        } else {
            staticRouteTypes.push(routeType);
        }
    }
    const serializedStaticRouteTypes = serializeRouteTypes(staticRouteTypes);
    const serializedDynamicRouteTypes = serializeRouteTypes(dynamicRouteTypes);
    // If both StaticRoutes and DynamicRoutes are empty, fallback to type 'string & {}'.
    const routeTypesFallback = !serializedStaticRouteTypes && !serializedDynamicRouteTypes ? 'string & {}' : '';
    return `// This file is generated automatically by Next.js
// Do not edit this file manually

// Type definitions for Next.js routes

/**
 * Internal types used by the Next.js router and Link component.
 * These types are not meant to be used directly.
 * @internal
 */
declare namespace __next_route_internal_types__ {
  type SearchOrHash = \`?\${string}\` | \`#\${string}\`
  type WithProtocol = \`\${string}:\${string}\`

  type Suffix = '' | SearchOrHash

  type SafeSlug<S extends string> = S extends \`\${string}/\${string}\`
    ? never
    : S extends \`\${string}\${SearchOrHash}\`
    ? never
    : S extends ''
    ? never
    : S

  type CatchAllSlug<S extends string> = S extends \`\${string}\${SearchOrHash}\`
    ? never
    : S extends ''
    ? never
    : S

  type OptionalCatchAllSlug<S extends string> =
    S extends \`\${string}\${SearchOrHash}\` ? never : S

  type StaticRoutes = ${serializedStaticRouteTypes || 'never'}
  type DynamicRoutes<T extends string = string> = ${serializedDynamicRouteTypes || 'never'}

  type RouteImpl<T> = ${routeTypesFallback || `
    ${// This keeps autocompletion working for static routes.
    '| StaticRoutes'}
    | SearchOrHash
    | WithProtocol
    | \`\${StaticRoutes}\${SearchOrHash}\`
    | (T extends \`\${DynamicRoutes<infer _>}\${Suffix}\` ? T : never)
    `}
}

declare module 'next' {
  export { default } from 'next/types.js'
  export * from 'next/types.js'

  export type Route<T extends string = string> =
    __next_route_internal_types__.RouteImpl<T>
}

declare module 'next/link' {
  import type { LinkProps as OriginalLinkProps } from 'next/dist/client/link.js'
  import type { AnchorHTMLAttributes, DetailedHTMLProps } from 'react'
  import type { UrlObject } from 'url'

  type LinkRestProps = Omit<
    Omit<
      DetailedHTMLProps<
        AnchorHTMLAttributes<HTMLAnchorElement>,
        HTMLAnchorElement
      >,
      keyof OriginalLinkProps
    > &
      OriginalLinkProps,
    'href'
  >

  export type LinkProps<RouteInferType> = LinkRestProps & {
    /**
     * The path or URL to navigate to. This is the only required prop. It can also be an object.
     * @see https://nextjs.org/docs/api-reference/next/link
     */
    href: __next_route_internal_types__.RouteImpl<RouteInferType> | UrlObject
  }

  export default function Link<RouteType>(props: LinkProps<RouteType>): JSX.Element
}

declare module 'next/navigation' {
  export * from 'next/dist/client/components/navigation.js'

  import type { NavigateOptions, AppRouterInstance as OriginalAppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime.js'
  import type { RedirectType } from 'next/dist/client/components/redirect-error.js'
  
  interface AppRouterInstance extends OriginalAppRouterInstance {
    /**
     * Navigate to the provided href.
     * Pushes a new history entry.
     */
    push<RouteType>(href: __next_route_internal_types__.RouteImpl<RouteType>, options?: NavigateOptions): void
    /**
     * Navigate to the provided href.
     * Replaces the current history entry.
     */
    replace<RouteType>(href: __next_route_internal_types__.RouteImpl<RouteType>, options?: NavigateOptions): void
    /**
     * Prefetch the provided href.
     */
    prefetch<RouteType>(href: __next_route_internal_types__.RouteImpl<RouteType>): void
  }

  export function useRouter(): AppRouterInstance;
  
  /**
   * This function allows you to redirect the user to another URL. It can be used in
   * [Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components),
   * [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers), and
   * [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
   *
   * - In a Server Component, this will insert a meta tag to redirect the user to the target page.
   * - In a Route Handler or Server Action, it will serve a 307/303 to the caller.
   * - In a Server Action, type defaults to 'push' and 'replace' elsewhere.
   *
   * Read more: [Next.js Docs: redirect](https://nextjs.org/docs/app/api-reference/functions/redirect)
   */
  export function redirect<RouteType>(
    /** The URL to redirect to */
    url: __next_route_internal_types__.RouteImpl<RouteType>,
    type?: RedirectType
  ): never;
  
  /**
   * This function allows you to redirect the user to another URL. It can be used in
   * [Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components),
   * [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers), and
   * [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
   *
   * - In a Server Component, this will insert a meta tag to redirect the user to the target page.
   * - In a Route Handler or Server Action, it will serve a 308/303 to the caller.
   *
   * Read more: [Next.js Docs: redirect](https://nextjs.org/docs/app/api-reference/functions/redirect)
   */
  export function permanentRedirect<RouteType>(
    /** The URL to redirect to */
    url: __next_route_internal_types__.RouteImpl<RouteType>,
    type?: RedirectType
  ): never;
}

declare module 'next/form' {
  import type { FormProps as OriginalFormProps } from 'next/dist/client/form.js'

  type FormRestProps = Omit<OriginalFormProps, 'action'>

  export type FormProps<RouteInferType> = {
    /**
     * \`action\` can be either a \`string\` or a function.
     * - If \`action\` is a string, it will be interpreted as a path or URL to navigate to when the form is submitted.
     *   The path will be prefetched when the form becomes visible.
     * - If \`action\` is a function, it will be called when the form is submitted. See the [React docs](https://react.dev/reference/react-dom/components/form#props) for more.
     */
    action: __next_route_internal_types__.RouteImpl<RouteInferType> | ((formData: FormData) => void)
  } & FormRestProps

  export default function Form<RouteType>(props: FormProps<RouteType>): JSX.Element
}
`;
}
function generateValidatorFile(routesManifest) {
    const generateValidations = (paths, type, pathToRouteMap)=>paths.sort()// Only validate TypeScript files - JavaScript files have too many type inference limitations
        .filter((filePath)=>filePath.endsWith('.ts') || filePath.endsWith('.tsx')).filter(// Don't include metadata routes or pages
        // (e.g. /manifest.webmanifest)
        (filePath)=>type !== 'AppPageConfig' || filePath.endsWith('page.ts') || filePath.endsWith('page.tsx')).map((filePath)=>{
            // Keep the file extension for TypeScript imports to support node16 module resolution
            const importPath = filePath;
            const route = pathToRouteMap == null ? void 0 : pathToRouteMap.get(filePath);
            const typeWithRoute = route && (type === 'AppPageConfig' || type === 'LayoutConfig' || type === 'RouteHandlerConfig') ? `${type}<${JSON.stringify(route)}>` : type;
            return `// Validate ${filePath}
{
  const handler = {} as typeof import(${JSON.stringify(importPath.replace(/\.tsx?$/, '.js'))})
  handler satisfies ${typeWithRoute}
}`;
        }).join('\n\n');
    // Use direct mappings from the manifest
    // Generate validations for different route types
    const appPageValidations = generateValidations(Array.from(routesManifest.appPagePaths).sort(), 'AppPageConfig', routesManifest.filePathToRoute);
    const appRouteHandlerValidations = generateValidations(Array.from(routesManifest.appRouteHandlers).sort(), 'RouteHandlerConfig', routesManifest.filePathToRoute);
    const pagesRouterPageValidations = generateValidations(Array.from(routesManifest.pagesRouterPagePaths).sort(), 'PagesPageConfig');
    const pagesApiRouteValidations = generateValidations(Array.from(routesManifest.pageApiRoutes).sort(), 'ApiRouteConfig');
    const layoutValidations = generateValidations(Array.from(routesManifest.layoutPaths).sort(), 'LayoutConfig', routesManifest.filePathToRoute);
    const hasAppRouteHandlers = Object.keys(routesManifest.appRouteHandlerRoutes).length > 0;
    // Build type definitions based on what's actually used
    let typeDefinitions = '';
    if (appPageValidations) {
        typeDefinitions += `type AppPageConfig<Route extends AppRoutes = AppRoutes> = {
  default: React.ComponentType<{ params: Promise<ParamMap[Route]> } & any> | ((props: { params: Promise<ParamMap[Route]> } & any) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
  generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
  generateMetadata?: (
    props: { params: Promise<ParamMap[Route]> } & any,
    parent: ResolvingMetadata
  ) => Promise<any> | any
  generateViewport?: (
    props: { params: Promise<ParamMap[Route]> } & any,
    parent: ResolvingViewport
  ) => Promise<any> | any
  metadata?: any
  viewport?: any
}

`;
    }
    if (pagesRouterPageValidations) {
        typeDefinitions += `type PagesPageConfig = {
  default: React.ComponentType<any> | ((props: any) => React.ReactNode | Promise<React.ReactNode> | never | void)
  getStaticProps?: (context: any) => Promise<any> | any
  getStaticPaths?: (context: any) => Promise<any> | any
  getServerSideProps?: (context: any) => Promise<any> | any
  getInitialProps?: (context: any) => Promise<any> | any
  /**
   * Segment configuration for legacy Pages Router pages.
   * Validated at build-time by parsePagesSegmentConfig.
   */
  config?: {
    amp?: boolean | 'hybrid' | string // necessary for JS
    maxDuration?: number
    runtime?: 'edge' | 'experimental-edge' | 'nodejs' | string // necessary unless config is exported as const
    regions?: string[]
  }
}

`;
    }
    if (layoutValidations) {
        typeDefinitions += `type LayoutConfig<Route extends LayoutRoutes = LayoutRoutes> = {
  default: React.ComponentType<LayoutProps<Route>> | ((props: LayoutProps<Route>) => React.ReactNode | Promise<React.ReactNode> | never | void | Promise<void>)
  generateStaticParams?: (props: { params: ParamMap[Route] }) => Promise<any[]> | any[]
  generateMetadata?: (
    props: { params: Promise<ParamMap[Route]> } & any,
    parent: ResolvingMetadata
  ) => Promise<any> | any
  generateViewport?: (
    props: { params: Promise<ParamMap[Route]> } & any,
    parent: ResolvingViewport
  ) => Promise<any> | any
  metadata?: any
  viewport?: any
}

`;
    }
    if (appRouteHandlerValidations) {
        typeDefinitions += `type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRoutes> = {
  GET?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
  POST?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
  PUT?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
  PATCH?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
  DELETE?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
  HEAD?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
  OPTIONS?: (request: NextRequest, context: { params: Promise<ParamMap[Route]> }) => Promise<Response | void> | Response | void
}

`;
    }
    if (pagesApiRouteValidations) {
        typeDefinitions += `type ApiRouteConfig = {
  default: (req: any, res: any) => Promise<Response | void> | Response | void
  config?: {
    api?: {
      bodyParser?: boolean | { sizeLimit?: string }
      responseLimit?: string | number | boolean
      externalResolver?: boolean
    }
    runtime?: 'edge' | 'experimental-edge' | 'nodejs' | string // necessary unless config is exported as const
    maxDuration?: number
  }
}

`;
    }
    // Build import statement based on what's actually needed
    const routeImports = [];
    // Only import AppRoutes if there are app pages
    if (appPageValidations) {
        routeImports.push('AppRoutes');
    }
    // Only import LayoutRoutes if there are layouts
    if (layoutValidations) {
        routeImports.push('LayoutRoutes');
    }
    // Only import ParamMap if there are routes that use it
    if (appPageValidations || layoutValidations || appRouteHandlerValidations) {
        routeImports.push('ParamMap');
    }
    if (hasAppRouteHandlers) {
        routeImports.push('AppRouteHandlerRoutes');
    }
    const routeImportStatement = routeImports.length > 0 ? `import type { ${routeImports.join(', ')} } from "./routes.js"` : '';
    const nextRequestImport = hasAppRouteHandlers ? "import type { NextRequest } from 'next/server.js'\n" : '';
    // Only import metadata types if there are App Router pages or layouts that might use them
    const metadataImport = appPageValidations || layoutValidations ? 'import type { ResolvingMetadata, ResolvingViewport } from "next/dist/lib/metadata/types/metadata-interface.js"\n' : '';
    return `// This file is generated automatically by Next.js
// Do not edit this file manually
// This file validates that all pages and layouts export the correct types

${routeImportStatement}
${metadataImport}${nextRequestImport}
${typeDefinitions}
${appPageValidations}

${appRouteHandlerValidations}

${pagesRouterPageValidations}

${pagesApiRouteValidations}

${layoutValidations}
`;
}
function generateRouteTypesFile(routesManifest) {
    const routeTypes = generateRouteTypes(routesManifest);
    const paramTypes = generateParamTypes(routesManifest);
    const layoutSlotMap = generateLayoutSlotMap(routesManifest);
    const hasAppRouteHandlers = Object.keys(routesManifest.appRouteHandlerRoutes).length > 0;
    // Build export statement based on what's actually generated
    const routeExports = [
        'AppRoutes',
        'PageRoutes',
        'LayoutRoutes',
        'RedirectRoutes',
        'RewriteRoutes',
        'ParamMap'
    ];
    if (hasAppRouteHandlers) {
        routeExports.push('AppRouteHandlerRoutes');
    }
    const exportStatement = `export type { ${routeExports.join(', ')} }`;
    const routeContextInterface = hasAppRouteHandlers ? `

  /**
   * Context for Next.js App Router route handlers
   * @example
   * \`\`\`tsx
   * export async function GET(request: NextRequest, context: RouteContext<'/api/users/[id]'>) {
   *   const { id } = await context.params
   *   return Response.json({ id })
   * }
   * \`\`\`
   */
  interface RouteContext<AppRouteHandlerRoute extends AppRouteHandlerRoutes> {
    params: Promise<ParamMap[AppRouteHandlerRoute]>
  }` : '';
    return `// This file is generated automatically by Next.js
// Do not edit this file manually

${routeTypes}

${paramTypes}

export type ParamsOf<Route extends Routes> = ParamMap[Route]

${layoutSlotMap}

${exportStatement}

declare global {
  /**
   * Props for Next.js App Router page components
   * @example
   * \`\`\`tsx
   * export default function Page(props: PageProps<'/blog/[slug]'>) {
   *   const { slug } = await props.params
   *   return <div>Blog post: {slug}</div>
   * }
   * \`\`\`
   */
  interface PageProps<AppRoute extends AppRoutes> {
    params: Promise<ParamMap[AppRoute]>
    searchParams: Promise<Record<string, string | string[] | undefined>>
  }

  /**
   * Props for Next.js App Router layout components
   * @example
   * \`\`\`tsx
   * export default function Layout(props: LayoutProps<'/dashboard'>) {
   *   return <div>{props.children}</div>
   * }
   * \`\`\`
   */
  type LayoutProps<LayoutRoute extends LayoutRoutes> = {
    params: Promise<ParamMap[LayoutRoute]>
    children: React.ReactNode
  } & {
    [K in LayoutSlotMap[LayoutRoute]]: React.ReactNode
  }${routeContextInterface}
}
`;
}

//# sourceMappingURL=typegen.js.map