{"version":3,"sources":["../src/core/builder-constants.ts","../src/next.ts"],"names":[],"mappings":"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","file":"next.cjs","sourcesContent":["/**\n * Nombres de los query params del puente builder. Constantes PURAS (sin DOM ni\n * `window`) para poder compartirlas entre el core (browser: `builder-token.ts`)\n * y el helper de servidor `veo-sdk/next` (`src/next.ts`), sin arrastrar código de\n * navegador al bundle de servidor.\n */\n\n/** Token de correlación del handshake. */\nexport const BUILDER_TOKEN_PARAM = 'veoBuilder';\n/** Origen del dashboard de Veo (para postMessage / frame-ancestors). */\nexport const BUILDER_ORIGIN_PARAM = 'veoBuilderOrigin';\n/** `1` → modo \"panel inyectado\": la app es top-level y el editor se inyecta encima. */\nexport const BUILDER_PANEL_PARAM = 'veoBuilderPanel';\n/** Path del panel del editor en el dashboard (default `/guides/design`). */\nexport const BUILDER_PANEL_PATH_PARAM = 'veoBuilderPanelPath';\n/** Id de la guía que se está editando (para cargar/guardar en el panel). */\nexport const BUILDER_GUIDE_PARAM = 'veoGuide';\n","/**\n * `veo-sdk/next` — helper de middleware para el \"modo diseño\" del editor visual.\n *\n * El editor de Veo embebe tu app en un `<iframe>` con `?veoBuilder=<token>`. Para\n * que tu app se deje diseñar hacen falta 3 cosas MECÁNICAS:\n *   1. permitir el embed (`frame-ancestors`, sacar `X-Frame-Options`),\n *   2. que las cookies de sesión viajen en el iframe cross-site\n *      (`SameSite=None; Secure; Partitioned` — CHIPS),\n *   3. persistir el modo builder entre navegaciones (cookie particionada), así\n *      sobrevive al redirect del guard de auth y a un login.\n *\n * Este wrapper hace las 3. Lo ÚNICO app-specific — qué sesión renderizás sin\n * login (usuario demo, etc.) — queda en tu handler, que recibe `{ builder }`.\n *\n * No depende de `next` (usa tipos estructurales), así el SDK sigue sin\n * dependencias de runtime. `NextRequest`/`NextResponse` son compatibles.\n *\n * @example\n * ```ts\n * // middleware.ts (o proxy.ts en Next 16)\n * import { veoBuilderProxy } from 'veo-sdk/next';\n *\n * export default veoBuilderProxy(\n *   async (request, { builder }) => {\n *     const { supabase, response } = createSupabaseMiddleware(request);\n *     const { data: { user } } = await supabase.auth.getUser();\n *     // Lo único tuyo: la sesión de diseño cuando estás embebido y sin login.\n *     if (builder && !user) {\n *       await supabase.auth.signInWithPassword({\n *         email: process.env.VEO_BUILDER_DEMO_EMAIL!,\n *         password: process.env.VEO_BUILDER_DEMO_PASSWORD!,\n *       });\n *     }\n *     return response;\n *   },\n *   { dashboardOrigins: [process.env.VEO_DASHBOARD_ORIGINS ?? ''] },\n * );\n * ```\n */\nimport { BUILDER_ORIGIN_PARAM, BUILDER_TOKEN_PARAM } from './core/builder-constants';\n\n/** Cookie que persiste el token del builder (particionada, contexto embebido). */\nexport const VEO_BUILDER_COOKIE = 'veo-builder';\n/** Cookie que persiste el origen del dashboard de Veo. */\nexport const VEO_BUILDER_ORIGIN_COOKIE = 'veo-builder-origin';\n\n/** Sesión de builder activa (la app está embebida por el editor de Veo). */\nexport interface VeoBuilderContext {\n  /** Token de correlación del handshake (idealmente firmado por el backend). */\n  token: string;\n  /** Origen del dashboard que embebe, para `frame-ancestors`. */\n  origin: string | null;\n}\n\n// ── Tipos estructurales, compatibles con NextRequest/NextResponse ──\ninterface CookieLike {\n  name: string;\n  value: string;\n  path?: string;\n  domain?: string;\n  maxAge?: number;\n  expires?: Date | number;\n  httpOnly?: boolean;\n  sameSite?: boolean | 'lax' | 'strict' | 'none';\n  secure?: boolean;\n  partitioned?: boolean;\n  priority?: 'low' | 'medium' | 'high';\n}\n\nexport interface VeoBuilderRequest {\n  nextUrl: { searchParams: URLSearchParams };\n  cookies: { get(name: string): { value: string } | undefined };\n}\n\nexport interface VeoBuilderResponse {\n  headers: { set(name: string, value: string): void; delete(name: string): void };\n  cookies: {\n    set(cookie: CookieLike): void;\n    getAll(): CookieLike[];\n  };\n}\n\nexport interface VeoBuilderProxyOptions {\n  /**\n   * Orígenes autorizados a embeber la app (`frame-ancestors`), p.ej.\n   * `['https://veo-dashboard-opal.vercel.app']`. Si se omite o queda vacío, se\n   * usa el origen que envía el propio editor (`veoBuilderOrigin`).\n   */\n  dashboardOrigins?: string[];\n  /** TTL de las cookies del modo builder, en segundos. Default 1800 (30 min). */\n  cookieMaxAge?: number;\n}\n\n/**\n * Lee el contexto de builder del request: del query param (`?veoBuilder`, primer\n * arranque dentro del iframe) o de la cookie (sobrevive navegaciones SPA y\n * requests RSC que ya no llevan el param). `null` si la app corre en modo normal.\n */\nexport function readVeoBuilderContext(request: VeoBuilderRequest): VeoBuilderContext | null {\n  const params = request.nextUrl.searchParams;\n  const fromParam = params.get(BUILDER_TOKEN_PARAM);\n  if (fromParam) {\n    return {\n      token: fromParam,\n      origin:\n        params.get(BUILDER_ORIGIN_PARAM) ??\n        request.cookies.get(VEO_BUILDER_ORIGIN_COOKIE)?.value ??\n        null,\n    };\n  }\n  const fromCookie = request.cookies.get(VEO_BUILDER_COOKIE)?.value;\n  if (fromCookie) {\n    return {\n      token: fromCookie,\n      origin: request.cookies.get(VEO_BUILDER_ORIGIN_COOKIE)?.value ?? null,\n    };\n  }\n  return null;\n}\n\n/** Cliente de auth mínimo para la sesión de diseño. Compatible con `supabase.auth`\n *  y cualquier auth con la misma forma (tipos estructurales, sin acoplar el SDK). */\nexport interface DesignAuthClient {\n  getUser(): Promise<{ data: { user: unknown } }>;\n  signInWithPassword(credentials: { email: string; password: string }): Promise<unknown>;\n}\n\nexport interface DesignSessionOptions {\n  /** Email del usuario demo. Default: env `VEO_BUILDER_DEMO_EMAIL`. */\n  email?: string;\n  /** Password del usuario demo. Default: env `VEO_BUILDER_DEMO_PASSWORD`. */\n  password?: string;\n}\n\n/**\n * Establece la \"sesión de diseño\" cuando la app está embebida por el editor de\n * Veo y no hay login: entra como usuario DEMO (sin datos reales) para poder\n * navegar la app sin auth. No-op fuera de modo builder, si ya hay sesión, o si\n * faltan credenciales. Agnóstico del proveedor: funciona con `supabase.auth` y\n * cualquier cliente con `getUser` + `signInWithPassword`.\n *\n * @example\n * ```ts\n * await ensureVeoDesignSession(builder, supabase.auth);\n * ```\n */\nexport async function ensureVeoDesignSession(\n  builder: VeoBuilderContext | null,\n  auth: DesignAuthClient,\n  options: DesignSessionOptions = {},\n): Promise<void> {\n  if (!builder) return;\n  const email = options.email ?? readEnv('VEO_BUILDER_DEMO_EMAIL');\n  const password = options.password ?? readEnv('VEO_BUILDER_DEMO_PASSWORD');\n  if (!email || !password) return;\n  const {\n    data: { user },\n  } = await auth.getUser();\n  if (!user) await auth.signInWithPassword({ email, password });\n}\n\nfunction readEnv(key: string): string | undefined {\n  try {\n    return typeof process !== 'undefined' ? process.env?.[key] : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\n/**\n * Envuelve tu middleware de Next para habilitar el modo diseño de Veo. Cuando la\n * app está embebida (`?veoBuilder` o cookie), DESPUÉS de correr tu handler:\n *  - reescribe TODAS las cookies de la respuesta a `SameSite=None; Secure;\n *    Partitioned` (así la sesión viaja en el iframe cross-site),\n *  - persiste token + origen en cookies particionadas,\n *  - setea `frame-ancestors` y saca `X-Frame-Options`.\n *\n * Tu handler recibe `{ builder }` para decidir la sesión de diseño (lo único\n * app-specific). Fuera de modo builder es un passthrough exacto (no toca nada).\n */\nexport function veoBuilderProxy<Req extends VeoBuilderRequest, Res extends VeoBuilderResponse>(\n  handler: (request: Req, ctx: { builder: VeoBuilderContext | null }) => Res | Promise<Res>,\n  options: VeoBuilderProxyOptions = {},\n): (request: Req) => Promise<Res> {\n  return async (request: Req): Promise<Res> => {\n    const builder = readVeoBuilderContext(request);\n    const response = await handler(request, { builder });\n    if (builder) {\n      repartitionCookies(response);\n      persistBuilderCookies(response, builder, options.cookieMaxAge ?? 1800);\n      applyFramingHeaders(response, builder, options.dashboardOrigins);\n    }\n    return response;\n  };\n}\n\n/** Reescribe todas las cookies de la respuesta a particionadas (CHIPS). */\nfunction repartitionCookies(response: VeoBuilderResponse): void {\n  for (const cookie of response.cookies.getAll()) {\n    response.cookies.set({ ...cookie, sameSite: 'none', secure: true, partitioned: true });\n  }\n}\n\nfunction persistBuilderCookies(\n  response: VeoBuilderResponse,\n  ctx: VeoBuilderContext,\n  maxAge: number,\n): void {\n  const base = { path: '/', maxAge, sameSite: 'none' as const, secure: true, partitioned: true };\n  response.cookies.set({ name: VEO_BUILDER_COOKIE, value: ctx.token, httpOnly: true, ...base });\n  if (ctx.origin) {\n    response.cookies.set({\n      name: VEO_BUILDER_ORIGIN_COOKIE,\n      value: ctx.origin,\n      httpOnly: false,\n      ...base,\n    });\n  }\n}\n\nfunction applyFramingHeaders(\n  response: VeoBuilderResponse,\n  ctx: VeoBuilderContext,\n  dashboardOrigins?: string[],\n): void {\n  const configured = (dashboardOrigins ?? []).map((s) => s.trim()).filter(Boolean);\n  const origins = configured.length > 0 ? configured : ctx.origin ? [ctx.origin] : [];\n  response.headers.delete('X-Frame-Options');\n  response.headers.set(\n    'Content-Security-Policy',\n    `frame-ancestors 'self' ${origins.join(' ')}`.trim(),\n  );\n}\n"]}