{"version":3,"file":"snapshot.mjs","names":[],"sources":["../../../../src/astro/routes/api/snapshot.ts"],"sourcesContent":["/**\n * Snapshot endpoint — exports a portable database snapshot for preview mode.\n *\n * Security:\n * - Authenticated users: requires content:read + schema:read permissions\n * - Builds and previews: the frontend service account's API token (Bearer), same permissions\n * - Excludes auth/user/session/token tables\n */\n\nimport type { User } from \"@premium-cms/auth\";\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { generateSnapshot } from \"#api/handlers/snapshot.js\";\nimport { getPublicOrigin } from \"#api/public-url.js\";\n\nimport { resolveSessionUser } from \"../../session-user.js\";\n\nexport const prerender = false;\n\nexport const GET: APIRoute = async ({ request, locals, url, session }) => {\n\tconst { emdash } = locals;\n\t// Auth middleware resolves sessions and Bearer tokens; the manual session\n\t// resolution below only covers callers the middleware left unresolved.\n\tlet user: User | undefined = (locals as { user?: User }).user;\n\tif (!user && session && emdash?.db) {\n\t\ttry {\n\t\t\tconst { createKyselyAdapter } = await import(\"@premium-cms/auth/adapters/kysely\");\n\t\t\tconst sessionUser = await resolveSessionUser(session);\n\t\t\tif (sessionUser?.id) {\n\t\t\t\tconst adapter = createKyselyAdapter(emdash.db);\n\t\t\t\tconst resolved = await adapter.getUserById(sessionUser.id);\n\t\t\t\tif (resolved && !resolved.disabled) {\n\t\t\t\t\tuser = resolved;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Session resolution failed; the permission checks below answer 401\n\t\t}\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\t// A session (an admin) or an API token — the frontend service account's, or anyone's with the grants.\n\tconst contentDenied = requirePerm(user, \"content:read\");\n\tif (contentDenied) return contentDenied;\n\tconst schemaDenied = requirePerm(user, \"schema:read\");\n\tif (schemaDenied) return schemaDenied;\n\n\ttry {\n\t\tconst includeDrafts = url.searchParams.get(\"drafts\") === \"true\";\n\t\tconst snapshot = await generateSnapshot(emdash.db, {\n\t\t\tincludeDrafts,\n\t\t\torigin: getPublicOrigin(url, emdash.config),\n\t\t});\n\n\t\treturn apiSuccess(snapshot);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to generate snapshot\", \"SNAPSHOT_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;;;;;AAmBA,MAAa,YAAY;AAEzB,MAAa,MAAgB,OAAO,EAAE,SAAS,QAAQ,KAAK,cAAc;CACzE,MAAM,EAAE,WAAW;CAGnB,IAAI,OAA0B,OAA2B;AACzD,KAAI,CAAC,QAAQ,WAAW,QAAQ,GAC/B,KAAI;EACH,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,cAAc,MAAM,mBAAmB,QAAQ;AACrD,MAAI,aAAa,IAAI;GAEpB,MAAM,WAAW,MADD,oBAAoB,OAAO,GAAG,CACf,YAAY,YAAY,GAAG;AAC1D,OAAI,YAAY,CAAC,SAAS,SACzB,QAAO;;SAGF;AAKT,KAAI,CAAC,QAAQ,GACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAIpE,MAAM,gBAAgB,YAAY,MAAM,eAAe;AACvD,KAAI,cAAe,QAAO;CAC1B,MAAM,eAAe,YAAY,MAAM,cAAc;AACrD,KAAI,aAAc,QAAO;AAEzB,KAAI;EACH,MAAM,gBAAgB,IAAI,aAAa,IAAI,SAAS,KAAK;AAMzD,SAAO,WALU,MAAM,iBAAiB,OAAO,IAAI;GAClD;GACA,QAAQ,gBAAgB,KAAK,OAAO,OAAO;GAC3C,CAAC,CAEyB;UACnB,OAAO;AACf,SAAO,YAAY,OAAO,+BAA+B,iBAAiB"}