import { Serialize } from "./types/serialize.js";
import { SerializableHead } from "@unhead/vue";
import { SSRHeadPayload } from "@unhead/vue/server";
import { SSRContext, createRenderer } from "vue-bundle-renderer/runtime";
import { UseHeadInput, VueHeadClient } from "@unhead/vue/types";
import { RenderResponse } from "nitropack/types";
import { NuxtHookRegistry, NuxtLinkOptions, NuxtRequestEvent, RuntimeConfig } from "@nuxt/schema";
import { AnyFetchPath, AnyHTTPMethod, DynamicParam, Endpoint, HTTPMethod, TypedFetchErrorBody, TypedFetchMethods, TypedFetchRequestBody, TypedFetchRequestHeaders, TypedFetchRequestQuery, TypedFetchRequires, TypedFetchResponseBody, TypedFetchResponseHeaders, ValidFetchInput, WildcardParam } from "fetchdts";
//#region src/app/types.d.ts
type HookResult = Promise<void> | void;
/** A log recorded during server rendering and replayed in the browser by `dev:ssr-logs`. */
export interface DevServerLog {
  level: number;
  type: string;
  tag: string;
  args: any[];
  date: Date;
  message?: string;
  additional?: string | string[];
  [key: string]: unknown;
}
export interface NuxtAppLiterals {
  [key: string]: string;
}
export interface PluginMeta {
  name?: string;
  enforce?: 'pre' | 'default' | 'post';
  /**
   * Await for other named plugins to finish before running this plugin.
   */
  dependsOn?: NuxtAppLiterals['pluginName'][];
  /**
   * This allows more granular control over plugin order and should only be used by advanced users.
   * It overrides the value of `enforce` and is used to sort plugins.
   */
  order?: number;
}
type AppRenderedContext = {
  ssrContext: NuxtSSRContext | undefined;
  renderResult: null | Awaited<ReturnType<ReturnType<typeof createRenderer>['renderToString']>>;
};
/**
 * The runtime app hooks fired from the server runtime. The full
 * `RuntimeNuxtHooks` interface in `./nuxt.ts` extends this with the
 * client-side hooks, whose signatures need the DOM lib.
 */
export interface NuxtServerRuntimeHooks {
  'app:error': (err: any) => HookResult;
  'app:rendered': (ctx: AppRenderedContext) => HookResult;
}
/**
 * The part of the runtime Nuxt app addressable from the server runtime
 * (`ssrContext.nuxt`). The full `NuxtApp` in `./nuxt.ts` is assignable to
 * this shape; `hooks` is deliberately narrowed to the members the server
 * runtime calls, as hook registries over different hook maps are
 * not mutually assignable.
 */
export interface NuxtServerApp {
  hooks: Pick<NuxtHookRegistry<NuxtServerRuntimeHooks>, 'hook' | 'callHook'>;
  payload: NuxtPayload;
  ssrContext?: NuxtSSRContext;
  [key: string]: unknown;
}
/**
 * Type-only mirror of the `NuxtError` interface in `./composables/error.ts`,
 * which remains the canonical `NuxtError` type exported from `nuxt/app` /
 * `#app`. Duplicated here (rather than imported) so this leaf stays free of
 * the DOM-dependent module graph reachable from `./composables/error.ts`.
 *
 * The members are declared here rather than inherited from h3's `H3Error`,
 * but must stay structurally compatible with it: that is what h3 and Nitro read
 * off errors thrown during SSR.
 */
export interface NuxtError<DataT = unknown> extends Error {
  readonly __nuxt_error?: true;
  error?: true;
  /** Whether the error is fatal. */
  fatal: boolean;
  /** Whether the error was not handled by the application. */
  unhandled: boolean;
  /** Additional data attached to the error JSON body under `data`. */
  data?: DataT;
  status?: number;
  statusText?: string;
  /** @deprecated Use `status` */
  statusCode?: number;
  /** @deprecated Use `statusText` */
  statusMessage?: string;
  toJSON(): NuxtErrorJSON<DataT>;
}
/** JSON body serialized from a {@link NuxtError} when it is sent as an HTTP response. */
export interface NuxtErrorJSON<DataT = unknown> {
  message: string;
  statusCode: number;
  statusMessage?: string;
  data?: DataT;
}
/**
 * Serialized form of an error's `cause` chain, attached to the error page
 * error in development. Error causes are serialized to their name, message,
 * stack and nested cause; primitive causes are passed through as-is, and any
 * other values are omitted.
 */
export type SerializedErrorCause = string | number | boolean | null | {
  name: string;
  message: string;
  stack?: string;
  cause?: SerializedErrorCause;
};
export interface NuxtPayload {
  path?: string;
  serverRendered?: boolean;
  prerenderedAt?: number;
  data: Record<string, any>;
  state: Record<string, any>;
  once: Set<string>;
  config?: Pick<RuntimeConfig, 'public' | 'app'>;
  error?: NuxtError | undefined;
  _errors: Record<string, NuxtError | undefined>;
  /**
   * Forwarded `<link rel="preload">` / `<link rel="modulepreload">` hints from the destination route, populated when `experimental.prefetchPreloadTags` is enabled.
   * @internal
   */
  prefetchLinks?: Array<Record<string, string | boolean>>;
  [key: string]: unknown;
}
export interface NuxtSSRContext extends SSRContext {
  url: string;
  event: NuxtRequestEvent;
  runtimeConfig: RuntimeConfig;
  noSSR: boolean;
  /** whether we are rendering an SSR error */
  error?: boolean;
  nuxt: NuxtServerApp;
  payload: Partial<NuxtPayload>;
  head: VueHeadClient<UseHeadInput, SSRHeadPayload>;
  /** This is used solely to render runtime config with SPA renderer. */
  config?: Pick<RuntimeConfig, 'public' | 'app'>;
  teleports?: Record<string, string>;
  islandContext?: NuxtIslandContext;
  /** @internal */
  ['~renderResponse']?: Partial<RenderResponse>;
  /** @internal */
  ['~payloadReducers']: Record<string, (data: any) => any>;
  /** @internal */
  ['~sharedPrerenderCache']?: {
    get<T = unknown>(key: string): Promise<T> | undefined;
    set<T>(key: string, value: Promise<T>): Promise<void>;
  };
  /** @internal */
  ['~preloadManifest']?: boolean;
  /** @internal */
  ['~lazyHydratedModules']?: Set<string>;
  /** @internal */
  ['~neverHydratedModules']?: Set<string>;
}
export interface NuxtIslandSlotResponse {
  props: Array<unknown>;
  scopeId?: string;
  fallback?: string;
}
export interface NuxtIslandClientResponse {
  html: string;
  props: unknown;
  chunk: string;
  slots?: Record<string, string>;
  uid?: string;
}
export interface NuxtIslandContext {
  id?: string;
  name: string;
  props?: Record<string, any>;
  url: string;
  slots: Record<string, Omit<NuxtIslandSlotResponse, 'fallback'>>;
  components: Record<string, Omit<NuxtIslandClientResponse, 'html'>>;
}
export interface NuxtIslandResponse {
  id?: string;
  html: string;
  head: SerializableHead;
  props?: Record<string, Record<string, any>>;
  components?: Record<string, NuxtIslandClientResponse>;
  slots?: Record<string, NuxtIslandSlotResponse>;
}
export interface NuxtRenderHTMLContext {
  htmlAttrs: string[];
  head: string[];
  bodyAttrs: string[];
  bodyPrepend: string[];
  body: string[];
  bodyAppend: string[];
}
/**
 * Context passed to the `render:html:chunk` hook, fired for each chunk
 * produced by Vue's renderer (after head-suspense pushes have been
 * injected) before it is enqueued. Mutate `chunk` to transform the bytes.
 */
export interface NuxtRenderChunkContext {
  chunk: Uint8Array;
  index: number;
}
/**
 * Context passed to the `render:html:close` hook, fired after the Vue
 * stream completes, before the closing tags. Mutate `bodyAppend` to
 * inject final scripts/markup.
 */
export interface NuxtRenderCloseContext {
  bodyAppend: string[];
}
/**
 * Context passed to the `render:route` hook, fired once per request
 * before rendering begins (streaming enabled or not).
 */
export interface NuxtRenderRouteContext {
  /**
   * Whether SSR streaming is possible for this route. `false` when a
   * buffered-only feature is in play (component islands, ISR/SWR cache,
   * `noScripts`, redirects) or SSR streaming is disabled. Read-only: the
   * renderer enforces this regardless of `prefersStream`.
   */
  readonly canStream: boolean;
  /**
   * Whether streaming is preferred for this request. Pre-computed from the
   * route's `streaming` rule and bot detection. Mutate it to override the
   * decision at runtime (e.g. set `false` to disable streaming for
   * authenticated users). The renderer streams only when
   * `canStream && prefersStream`, so setting it `true` on a non-streamable
   * route is a no-op.
   */
  prefersStream: boolean;
}
//#endregion
export type { AnyFetchPath, AnyHTTPMethod, DynamicParam, Endpoint, HTTPMethod, NuxtLinkOptions, Serialize, TypedFetchErrorBody, TypedFetchMethods, TypedFetchRequestBody, TypedFetchRequestHeaders, TypedFetchRequestQuery, TypedFetchRequires, TypedFetchResponseBody, TypedFetchResponseHeaders, ValidFetchInput, WildcardParam };