@agent-native/core 0.31.2 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -0
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +5 -5
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +8 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/deploy/build.d.ts +2 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +104 -42
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/immutable-assets.d.ts.map +1 -1
- package/dist/deploy/immutable-assets.js +5 -0
- package/dist/deploy/immutable-assets.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +1719 -1685
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/framework-request-handler.js +8 -6
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/request-context.d.ts +8 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +25 -4
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +54 -15
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/shared/cache-control.d.ts +6 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +6 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/package.json +1 -1
|
@@ -19,12 +19,12 @@ import { createRequestHandler } from "react-router";
|
|
|
19
19
|
import { defineEventHandler } from "h3";
|
|
20
20
|
import { getSentryClientConfigScript } from "./sentry-config.js";
|
|
21
21
|
import { BETTER_AUTH_COOKIE_PREFIX, COOKIE_NAME, getSession } from "./auth.js";
|
|
22
|
-
import { runWithRequestContext } from "./request-context.js";
|
|
22
|
+
import { hasAuthContextAccess, runWithRequestContext, } from "./request-context.js";
|
|
23
23
|
import { requestHasEmbedAuthMarker } from "./embed-session.js";
|
|
24
24
|
import { EMBED_SESSION_COOKIE, EMBED_TOKEN_QUERY_PARAM, } from "../shared/embed-auth.js";
|
|
25
25
|
import { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE } from "../shared/social-meta.js";
|
|
26
|
-
import { DEFAULT_SSR_CACHE_CONTROL } from "../shared/cache-control.js";
|
|
27
|
-
export { DEFAULT_SSR_CACHE_CONTROL } from "../shared/cache-control.js";
|
|
26
|
+
import { DEFAULT_SPECULATION_RULES_PATH, DEFAULT_SSR_CACHE_CONTROL, } from "../shared/cache-control.js";
|
|
27
|
+
export { DEFAULT_SPECULATION_RULES_HEADER, DEFAULT_SSR_CACHE_CONTROL, } from "../shared/cache-control.js";
|
|
28
28
|
const ANONYMOUS_SESSION_COOKIE_NAMES = new Set(["an_docs_session"]);
|
|
29
29
|
const BETTER_AUTH_SESSION_COOKIE_RE = /\.session_(?:token|data)$/;
|
|
30
30
|
/**
|
|
@@ -181,28 +181,66 @@ function isAuthenticatedCookieName(name) {
|
|
|
181
181
|
bareName === `${BETTER_AUTH_COOKIE_PREFIX}.session_data` ||
|
|
182
182
|
BETTER_AUTH_SESSION_COOKIE_RE.test(bareName));
|
|
183
183
|
}
|
|
184
|
-
function shouldUseDefaultSsrCacheHeader(headers, status, pathname,
|
|
184
|
+
function shouldUseDefaultSsrCacheHeader(headers, status, pathname, authContextAccessed) {
|
|
185
185
|
if (status < 200 || status >= 400)
|
|
186
186
|
return false;
|
|
187
|
+
if (authContextAccessed) {
|
|
188
|
+
// Do not bypass cache just because a browser carries an auth-looking
|
|
189
|
+
// cookie: public docs/pages can receive stale workspace cookies and should
|
|
190
|
+
// still warm the CDN. But if SSR code actually reads user/org context,
|
|
191
|
+
// that route is rendering private data and must not be public-cached.
|
|
192
|
+
// Move those reads to client-side actions/API to regain CDN caching.
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
187
195
|
const contentType = headers.get("content-type")?.toLowerCase() ?? "";
|
|
188
196
|
if (contentType.includes("text/html")) {
|
|
189
|
-
|
|
197
|
+
// SSR HTML is public app shell in this framework; any per-user state is
|
|
198
|
+
// fetched after hydration. Always enforce the framework SWR default here;
|
|
199
|
+
// route-level no-cache/private headers on SSR HTML recreate the same
|
|
200
|
+
// origin stampede this cache policy is meant to prevent.
|
|
201
|
+
return true;
|
|
190
202
|
}
|
|
191
203
|
if (!pathname.endsWith(".data"))
|
|
192
204
|
return false;
|
|
193
|
-
if (hasAuthSignal)
|
|
194
|
-
return false;
|
|
195
205
|
if (!contentType.includes("text/x-script"))
|
|
196
206
|
return false;
|
|
197
|
-
|
|
198
|
-
|
|
207
|
+
// React Router gives loader `.data` responses `cache-control: no-cache` by
|
|
208
|
+
// default. In Agent-Native, SSR output is intentionally public app shell:
|
|
209
|
+
// user/org-specific reads happen after hydration through actions and API
|
|
210
|
+
// routes. Keep `.data` on the same short-fresh/long-SWR policy as HTML so
|
|
211
|
+
// route data fetches warm the CDN instead of hammering origin.
|
|
212
|
+
// Do not re-add a blanket cookie/auth-signal bypass here: logged-in browsers
|
|
213
|
+
// still need CDN-cached public route data. The auth-context leak guard above
|
|
214
|
+
// is the narrow protection for old SSR loaders that still read user/org data.
|
|
215
|
+
// Also do not preserve route-level private/no-store for React Router .data:
|
|
216
|
+
// if a route needs per-user data, it belongs behind a client-side action/API
|
|
217
|
+
// call rather than in the shared SSR payload.
|
|
218
|
+
return true;
|
|
199
219
|
}
|
|
200
|
-
function applyDefaultSsrCacheHeader(headers, status, pathname,
|
|
201
|
-
if (!shouldUseDefaultSsrCacheHeader(headers, status, pathname,
|
|
220
|
+
function applyDefaultSsrCacheHeader(headers, status, pathname, authContextAccessed) {
|
|
221
|
+
if (!shouldUseDefaultSsrCacheHeader(headers, status, pathname, authContextAccessed)) {
|
|
202
222
|
return;
|
|
203
223
|
}
|
|
204
224
|
headers.set("cache-control", DEFAULT_SSR_CACHE_CONTROL);
|
|
205
225
|
}
|
|
226
|
+
function applyDefaultSpeculationRulesHeader(headers, status, basePath) {
|
|
227
|
+
if (status < 200 || status >= 400)
|
|
228
|
+
return;
|
|
229
|
+
if (headers.has("speculation-rules"))
|
|
230
|
+
return;
|
|
231
|
+
const contentType = headers.get("content-type")?.toLowerCase() ?? "";
|
|
232
|
+
if (!contentType.includes("text/html"))
|
|
233
|
+
return;
|
|
234
|
+
// Cloudflare Speed Brain injects its own Speculation-Rules header when the
|
|
235
|
+
// origin omits one. Those browser prefetches carry `Sec-Purpose: prefetch`,
|
|
236
|
+
// and Cloudflare refuses cache-ineligible dynamic pages with a 503 before
|
|
237
|
+
// the request can reach Netlify/origin. We publish an explicit no-op ruleset
|
|
238
|
+
// by default so Cloudflare does not inject its edge prefetch rules. Preserve
|
|
239
|
+
// an app-provided Speculation-Rules header above if a template deliberately
|
|
240
|
+
// owns this behavior.
|
|
241
|
+
const rulesPath = prefixMountedPath(DEFAULT_SPECULATION_RULES_PATH, basePath);
|
|
242
|
+
headers.set("speculation-rules", `"${rulesPath}"`);
|
|
243
|
+
}
|
|
206
244
|
function isFrameworkOrAssetPath(pathname) {
|
|
207
245
|
return (pathname.startsWith("/.well-known/") ||
|
|
208
246
|
pathname.startsWith("/_agent_native/") ||
|
|
@@ -218,10 +256,11 @@ function isFrameworkOrAssetPath(pathname) {
|
|
|
218
256
|
pathname === "/favicon.png" ||
|
|
219
257
|
(/\.\w+$/.test(pathname) && !pathname.endsWith(".data")));
|
|
220
258
|
}
|
|
221
|
-
async function rewriteMountedResponse(response, basePath, pathname,
|
|
259
|
+
async function rewriteMountedResponse(response, basePath, pathname, requestContext) {
|
|
222
260
|
const sentryClientConfigScript = getSentryClientConfigScript();
|
|
223
261
|
const headers = new Headers(response.headers);
|
|
224
|
-
applyDefaultSsrCacheHeader(headers, response.status, pathname,
|
|
262
|
+
applyDefaultSsrCacheHeader(headers, response.status, pathname, hasAuthContextAccess(requestContext));
|
|
263
|
+
applyDefaultSpeculationRulesHeader(headers, response.status, basePath);
|
|
225
264
|
const location = headers.get("location");
|
|
226
265
|
if (location?.startsWith("/") && !location.startsWith("//")) {
|
|
227
266
|
headers.set("location", prefixMountedPath(location, basePath));
|
|
@@ -287,9 +326,9 @@ export function createH3SSRHandler(getBuild) {
|
|
|
287
326
|
status: response.status,
|
|
288
327
|
statusText: response.statusText,
|
|
289
328
|
headers: response.headers,
|
|
290
|
-
}), basePath, p,
|
|
329
|
+
}), basePath, p, ctx);
|
|
291
330
|
}
|
|
292
|
-
return await rewriteMountedResponse(await runWithRequestContext(ctx, () => handler(request)), basePath, p,
|
|
331
|
+
return await rewriteMountedResponse(await runWithRequestContext(ctx, () => handler(request)), basePath, p, ctx);
|
|
293
332
|
}
|
|
294
333
|
catch (err) {
|
|
295
334
|
// Log the full stack server-side, but never leak it to the client.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-handler.js","sourceRoot":"","sources":["../../src/server/ssr-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAgB,MAAM,IAAI,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACpE,MAAM,6BAA6B,GAAG,2BAA2B,CAAC;AAElE;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAAC,KAAc;IAC7C,IAAI,CAAC;QACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;QACvC,OAAO,GAAG,EAAE,KAAK,IAAI,SAAS,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB;IACrD,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IAC3C,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,OAAO,GACX,MAAM,CAAC,IAGR,CAAC,GAAG,CAAC;IACN,OAAO,oBAAoB,CACzB,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC5B,OAAO,CAAC,GAAG,CAAC,aAAa;QACzB,OAAO,EAAE,kBAAkB;QAC3B,OAAO,EAAE,aAAa;QACtB,OAAO,EAAE,QAAQ,CACpB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,OAAO,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB,EAAE,QAAgB;IACvD,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC/B,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACtC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;QACxC,OAAO,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,mBAAmB,CAC1B,OAAgB,EAChB,QAAgB,EAChB,QAAgB;IAEhB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,QAAQ,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,aAAa,GAAG,KAAK;iBACxB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;iBAC5C,IAAI,CAAC,GAAG,CAAC,CAAC;YACb,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;gBAC5B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;gBAC7C,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxB,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAC7B,MAAM,IAAI,GAAsC;QAC9C,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC;IACF,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC5E,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAAgB;IACvD,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAAgB;IACvD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,IAAI;SACR,OAAO,CACN,iEAAiE,EACjE,CAAC,MAAM,EAAE,IAAY,EAAE,KAAa,EAAE,IAAY,EAAE,EAAE,CACpD,GAAG,IAAI,IAAI,KAAK,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,KAAK,EAAE,CACjE;SACA,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtE,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,MAAqB;IAC3D,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,YAAY,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,gBAAgB,GAAG,oDAAoD,CAAC;AAC9E,MAAM,oBAAoB,GACxB,oDAAoD,CAAC;AACvD,MAAM,qBAAqB,GACzB,qDAAqD,CAAC;AAExD,SAAS,4BAA4B,CAAC,IAAY;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,YAAY,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,iBAAiB,GACrB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CACP,sCAAsC,iCAAiC,IAAI,CAC5E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CACP,uCAAuC,iCAAiC,IAAI,CAC7E,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;IAClC,OAAO,OAAO,CACZ,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC5B,6BAA6B,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpD,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,uBAAuB,CAAC;QACnD,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;QACtC,yBAAyB,CAAC,KAAK,CAAC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,6BAA6B,CAAC,YAA2B;IAChE,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAChC,OAAO,YAAY;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;SACvD,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAC/C,IAAI,CAAC,yBAAyB,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAY;IAC7C,IAAI,8BAA8B,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACzD,OAAO,CACL,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,oBAAoB;QACjC,QAAQ,KAAK,YAAY;QACzB,QAAQ,KAAK,sBAAsB;QACnC,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC;QAClC,QAAQ,KAAK,GAAG,yBAAyB,gBAAgB;QACzD,QAAQ,KAAK,GAAG,yBAAyB,eAAe;QACxD,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC7C,CAAC;AACJ,CAAC;AAED,SAAS,8BAA8B,CACrC,OAAgB,EAChB,MAAc,EACd,QAAgB,EAChB,aAAsB;IAEtB,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IAEhD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACrE,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,aAAa;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,eAAe,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClD,OAAO,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC;AAC3E,CAAC;AAED,SAAS,0BAA0B,CACjC,OAAgB,EAChB,MAAc,EACd,QAAgB,EAChB,aAAsB;IAEtB,IACE,CAAC,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,EACzE,CAAC;QACD,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAgB;IAC9C,OAAO,CACL,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;QACpC,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC;QACtC,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC;QACtC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAC5B,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;QAC9B,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAC5B,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAC5B,QAAQ,KAAK,iBAAiB;QAC9B,QAAQ,KAAK,cAAc;QAC3B,QAAQ,KAAK,mBAAmB;QAChC,QAAQ,KAAK,cAAc;QAC3B,QAAQ,KAAK,cAAc;QAC3B,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CACzD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,QAAkB,EAClB,QAAgB,EAChB,QAAgB,EAChB,aAAsB;IAEtB,MAAM,wBAAwB,GAAG,2BAA2B,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,0BAA0B,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAE9E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvE,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;YACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,OAAO,IAAI,QAAQ,CACjB,gBAAgB,CACd,4BAA4B,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAC/D,wBAAwB,CACzB,EACD;QACE,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,OAAO;KACR,CACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAA0C;IAC3E,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAe,CAAC,CAAC;IACtD,OAAO,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,GAAc,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACvE,wEAAwE;YACxE,uEAAuE;YACvE,gEAAgE;YAChE,uEAAuE;YACvE,+DAA+D;YAC/D,IAAI,OAAO,GAAkD,IAAI,CAAC;YAClE,MAAM,aAAa,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,aAAa,EAAE,CAAC;gBAClB,IAAI,CAAC;oBACH,OAAO,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;gBACpC,CAAC;gBAAC,MAAM,CAAC;oBACP,qEAAqE;gBACvE,CAAC;YACH,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1E,MAAM,GAAG,GAAG;gBACV,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,SAAS;gBACtC,KAAK;aACN,CAAC;YACF,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC9B,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;oBAC1C,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,CACrD,OAAO,CAAC,UAAU,CAAC,CACpB,CAAC;gBACF,OAAO,MAAM,sBAAsB,CACjC,IAAI,QAAQ,CAAC,IAAI,EAAE;oBACjB,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;iBAC1B,CAAC,EACF,QAAQ,EACR,CAAC,EACD,aAAa,CACd,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,sBAAsB,CACjC,MAAM,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EACxD,QAAQ,EACR,CAAC,EACD,aAAa,CACd,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,mEAAmE;YACnE,uEAAuE;YACvE,sEAAsE;YACtE,oEAAoE;YACpE,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;YACrD,MAAM,IAAI,GAAG,MAAM;gBACjB,CAAC,CAAC,uBAAuB;gBACzB,CAAC,CAAC,0BAA2B,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC;YAC/D,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;gBACxB,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Shared SSR catch-all handler for React Router framework mode.\n *\n * Templates wire this up via:\n *\n * // server/routes/[...page].get.ts\n * import { createH3SSRHandler } from \"@agent-native/core/server/ssr-handler\";\n * export default createH3SSRHandler(\n * () => import(\"virtual:react-router/server-build\"),\n * );\n *\n * The `getBuild` callback MUST live in the template's own source so Vite's\n * @react-router/dev plugin can resolve the `virtual:` module. Pulling the\n * import into core (e.g. via a re-export) puts it in node_modules where\n * Vite's SSR externalizer leaves it untouched and Node's ESM loader rejects\n * the unknown scheme — silently 302'ing every request to \"/\".\n */\nimport { createRequestHandler } from \"react-router\";\nimport { defineEventHandler, type H3Event } from \"h3\";\nimport { getSentryClientConfigScript } from \"./sentry-config.js\";\nimport { BETTER_AUTH_COOKIE_PREFIX, COOKIE_NAME, getSession } from \"./auth.js\";\nimport { runWithRequestContext } from \"./request-context.js\";\nimport { requestHasEmbedAuthMarker } from \"./embed-session.js\";\nimport {\n EMBED_SESSION_COOKIE,\n EMBED_TOKEN_QUERY_PARAM,\n} from \"../shared/embed-auth.js\";\nimport { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE } from \"../shared/social-meta.js\";\nimport { DEFAULT_SSR_CACHE_CONTROL } from \"../shared/cache-control.js\";\n\nexport { DEFAULT_SSR_CACHE_CONTROL } from \"../shared/cache-control.js\";\nconst ANONYMOUS_SESSION_COOKIE_NAMES = new Set([\"an_docs_session\"]);\nconst BETTER_AUTH_SESSION_COOKIE_RE = /\\.session_(?:token|data)$/;\n\n/**\n * Read the active org for a request without forcing every template to bundle\n * the org module. Mirrors what `core-routes-plugin` does for action handlers.\n */\nasync function readOrgIdForEvent(event: H3Event): Promise<string | undefined> {\n try {\n const { getOrgContext } = await import(\"../org/context.js\");\n const ctx = await getOrgContext(event);\n return ctx?.orgId ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeAppBasePath(value: string | undefined): string {\n if (!value || value === \"/\") return \"\";\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n return `/${trimmed.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\")}`;\n}\n\nfunction getAppBasePath(): string {\n const metaEnv = (\n import.meta as unknown as {\n env?: Record<string, string | undefined>;\n }\n ).env;\n return normalizeAppBasePath(\n process.env.VITE_APP_BASE_PATH ||\n process.env.APP_BASE_PATH ||\n metaEnv?.VITE_APP_BASE_PATH ||\n metaEnv?.APP_BASE_PATH ||\n metaEnv?.BASE_URL,\n );\n}\n\nfunction stripAppBasePath(pathname: string): string {\n const basePath = getAppBasePath();\n return stripBasePath(pathname, basePath);\n}\n\nfunction stripBasePath(pathname: string, basePath: string): string {\n if (!basePath) return pathname;\n if (pathname === basePath) return \"/\";\n if (pathname.startsWith(`${basePath}/`)) {\n return pathname.slice(basePath.length) || \"/\";\n }\n return pathname;\n}\n\nfunction requestWithPathname(\n request: Request,\n pathname: string,\n basePath: string,\n): Request {\n const url = new URL(request.url);\n let changed = false;\n if (basePath && pathname === \"/__manifest\") {\n const paths = url.searchParams.get(\"paths\");\n if (paths) {\n const strippedPaths = paths\n .split(\",\")\n .map((path) => stripBasePath(path, basePath))\n .join(\",\");\n if (strippedPaths !== paths) {\n url.searchParams.set(\"paths\", strippedPaths);\n changed = true;\n }\n }\n }\n if (url.pathname !== pathname) {\n url.pathname = pathname;\n changed = true;\n }\n if (!changed) return request;\n const init: RequestInit & { duplex?: \"half\" } = {\n method: request.method,\n headers: request.headers,\n signal: request.signal,\n };\n if (request.body && ![\"GET\", \"HEAD\"].includes(request.method.toUpperCase())) {\n init.body = request.body;\n init.duplex = \"half\";\n }\n return new Request(url, init);\n}\n\nfunction prefixMountedPath(path: string, basePath: string): string {\n if (!basePath || !path.startsWith(\"/\") || path.startsWith(\"//\")) return path;\n if (path === basePath || path.startsWith(`${basePath}/`)) return path;\n return `${basePath}${path}`;\n}\n\nfunction prefixMountedHtml(html: string, basePath: string): string {\n if (!basePath) return html;\n return html\n .replace(\n /\\b(href|src|action|formaction|poster)=([\"'])(\\/(?!\\/)[^\"']*)\\2/g,\n (_match, attr: string, quote: string, path: string) =>\n `${attr}=${quote}${prefixMountedPath(path, basePath)}${quote}`,\n )\n .replace(/url\\(([\"']?)(\\/(?!\\/)[^)'\" ]+)\\1\\)/g, (_match, quote, path) => {\n const q = quote || \"\";\n return `url(${q}${prefixMountedPath(path, basePath)}${q})`;\n });\n}\n\nfunction injectHeadScript(html: string, script: string | null): string {\n if (!script) return html;\n const headCloseIdx = html.indexOf(\"</head>\");\n if (headCloseIdx === -1) return html;\n return html.slice(0, headCloseIdx) + script + html.slice(headCloseIdx);\n}\n\nconst OG_IMAGE_META_RE = /<meta\\b(?=[^>]*\\bproperty=([\"'])og:image\\1)[^>]*>/i;\nconst TWITTER_CARD_META_RE =\n /<meta\\b(?=[^>]*\\bname=([\"'])twitter:card\\1)[^>]*>/i;\nconst TWITTER_IMAGE_META_RE =\n /<meta\\b(?=[^>]*\\bname=([\"'])twitter:image\\1)[^>]*>/i;\n\nfunction injectDefaultSocialImageMeta(html: string): string {\n const headCloseIdx = html.indexOf(\"</head>\");\n if (headCloseIdx === -1) return html;\n\n const hasAnySocialImage =\n OG_IMAGE_META_RE.test(html) || TWITTER_IMAGE_META_RE.test(html);\n const tags: string[] = [];\n\n if (!hasAnySocialImage) {\n tags.push(\n `<meta property=\"og:image\" content=\"${AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE}\">`,\n );\n }\n if (!TWITTER_CARD_META_RE.test(html)) {\n tags.push(`<meta name=\"twitter:card\" content=\"summary_large_image\">`);\n }\n if (!hasAnySocialImage) {\n tags.push(\n `<meta name=\"twitter:image\" content=\"${AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE}\">`,\n );\n }\n\n if (tags.length === 0) return html;\n return html.slice(0, headCloseIdx) + tags.join(\"\") + html.slice(headCloseIdx);\n}\n\nfunction requestHasAuthSignal(event: H3Event): boolean {\n const headers = event.req.headers;\n return Boolean(\n headers.get(\"authorization\") ||\n requestHasAuthenticatedCookie(headers.get(\"cookie\")) ||\n event.url.searchParams.has(EMBED_TOKEN_QUERY_PARAM) ||\n event.url.searchParams.has(\"_session\") ||\n requestHasEmbedAuthMarker(event),\n );\n}\n\nfunction requestHasAuthenticatedCookie(cookieHeader: string | null): boolean {\n if (!cookieHeader) return false;\n return cookieHeader\n .split(\";\")\n .map((cookie) => cookie.trim().split(\"=\", 1)[0]?.trim())\n .filter((name): name is string => Boolean(name))\n .some(isAuthenticatedCookieName);\n}\n\nfunction isAuthenticatedCookieName(name: string): boolean {\n if (ANONYMOUS_SESSION_COOKIE_NAMES.has(name)) return false;\n const bareName = name.replace(/^__(?:Secure|Host)-/, \"\");\n return (\n bareName === COOKIE_NAME ||\n bareName === EMBED_SESSION_COOKIE ||\n bareName === \"an_session\" ||\n bareName === \"an_session_workspace\" ||\n bareName.startsWith(\"an_session_\") ||\n bareName === `${BETTER_AUTH_COOKIE_PREFIX}.session_token` ||\n bareName === `${BETTER_AUTH_COOKIE_PREFIX}.session_data` ||\n BETTER_AUTH_SESSION_COOKIE_RE.test(bareName)\n );\n}\n\nfunction shouldUseDefaultSsrCacheHeader(\n headers: Headers,\n status: number,\n pathname: string,\n hasAuthSignal: boolean,\n): boolean {\n if (status < 200 || status >= 400) return false;\n\n const contentType = headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (contentType.includes(\"text/html\")) {\n return !headers.has(\"cache-control\");\n }\n\n if (!pathname.endsWith(\".data\")) return false;\n if (hasAuthSignal) return false;\n if (!contentType.includes(\"text/x-script\")) return false;\n\n const cacheControl = headers.get(\"cache-control\");\n return !cacheControl || cacheControl.trim().toLowerCase() === \"no-cache\";\n}\n\nfunction applyDefaultSsrCacheHeader(\n headers: Headers,\n status: number,\n pathname: string,\n hasAuthSignal: boolean,\n) {\n if (\n !shouldUseDefaultSsrCacheHeader(headers, status, pathname, hasAuthSignal)\n ) {\n return;\n }\n headers.set(\"cache-control\", DEFAULT_SSR_CACHE_CONTROL);\n}\n\nfunction isFrameworkOrAssetPath(pathname: string): boolean {\n return (\n pathname.startsWith(\"/.well-known/\") ||\n pathname.startsWith(\"/_agent_native/\") ||\n pathname.startsWith(\"/_agent-native/\") ||\n pathname.startsWith(\"/api/\") ||\n pathname.startsWith(\"/@vite/\") ||\n pathname.startsWith(\"/@id/\") ||\n pathname.startsWith(\"/@fs/\") ||\n pathname === \"/@react-refresh\" ||\n pathname === \"/__vite_ping\" ||\n pathname === \"/__open-in-editor\" ||\n pathname === \"/favicon.ico\" ||\n pathname === \"/favicon.png\" ||\n (/\\.\\w+$/.test(pathname) && !pathname.endsWith(\".data\"))\n );\n}\n\nasync function rewriteMountedResponse(\n response: Response,\n basePath: string,\n pathname: string,\n hasAuthSignal: boolean,\n): Promise<Response> {\n const sentryClientConfigScript = getSentryClientConfigScript();\n const headers = new Headers(response.headers);\n applyDefaultSsrCacheHeader(headers, response.status, pathname, hasAuthSignal);\n\n const location = headers.get(\"location\");\n if (location?.startsWith(\"/\") && !location.startsWith(\"//\")) {\n headers.set(\"location\", prefixMountedPath(location, basePath));\n }\n\n const contentType = headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().includes(\"text/html\") || !response.body) {\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n const html = await response.text();\n headers.delete(\"content-length\");\n return new Response(\n injectHeadScript(\n injectDefaultSocialImageMeta(prefixMountedHtml(html, basePath)),\n sentryClientConfigScript,\n ),\n {\n status: response.status,\n statusText: response.statusText,\n headers,\n },\n );\n}\n\n/**\n * Create an h3 catch-all that hands page routes to React Router and\n * returns 404 for framework / asset paths that React Router doesn't own.\n */\nexport function createH3SSRHandler(getBuild: () => Promise<unknown> | unknown) {\n const handler = createRequestHandler(getBuild as any);\n return defineEventHandler(async (event) => {\n const basePath = getAppBasePath();\n const p = stripAppBasePath(event.url.pathname);\n if (isFrameworkOrAssetPath(p)) {\n return new Response(null, { status: 404 });\n }\n try {\n const request = requestWithPathname(event.req as Request, p, basePath);\n // Pin the active session onto the async request context so React Router\n // loaders that call `getRequestUserEmail()` / `accessFilter()` see the\n // signed-in user. Without this, SSR loaders fall through to the\n // unauthenticated branch even when the user is logged in — which broke\n // shared-deck \"Presentation link\" access for non-public decks.\n let session: Awaited<ReturnType<typeof getSession>> | null = null;\n const hasAuthSignal = requestHasAuthSignal(event);\n if (hasAuthSignal) {\n try {\n session = await getSession(event);\n } catch {\n // Auth lookup failures must not break SSR; treat as unauthenticated.\n }\n }\n const orgId = session?.email ? await readOrgIdForEvent(event) : undefined;\n const ctx = {\n userEmail: session?.email ?? undefined,\n orgId,\n };\n if (request.method === \"HEAD\") {\n const getRequest = new Request(request.url, {\n method: \"GET\",\n headers: request.headers,\n signal: request.signal,\n });\n const response = await runWithRequestContext(ctx, () =>\n handler(getRequest),\n );\n return await rewriteMountedResponse(\n new Response(null, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n }),\n basePath,\n p,\n hasAuthSignal,\n );\n }\n return await rewriteMountedResponse(\n await runWithRequestContext(ctx, () => handler(request)),\n basePath,\n p,\n hasAuthSignal,\n );\n } catch (err) {\n // Log the full stack server-side, but never leak it to the client.\n // Stack traces expose file paths, library versions, and code structure\n // that aid reconnaissance attacks. In dev we surface the message text\n // so devtools shows something useful; in prod we return a bare 500.\n console.error(\"[ssr-handler] SSR error:\", err);\n const isProd = process.env.NODE_ENV === \"production\";\n const body = isProd\n ? \"Internal Server Error\"\n : `Internal Server Error: ${(err as Error)?.message ?? err}`;\n return new Response(body, {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ssr-handler.js","sourceRoot":"","sources":["../../src/server/ssr-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared SSR catch-all handler for React Router framework mode.\n *\n * Templates wire this up via:\n *\n * // server/routes/[...page].get.ts\n * import { createH3SSRHandler } from \"@agent-native/core/server/ssr-handler\";\n * export default createH3SSRHandler(\n * () => import(\"virtual:react-router/server-build\"),\n * );\n *\n * The `getBuild` callback MUST live in the template's own source so Vite's\n * @react-router/dev plugin can resolve the `virtual:` module. Pulling the\n * import into core (e.g. via a re-export) puts it in node_modules where\n * Vite's SSR externalizer leaves it untouched and Node's ESM loader rejects\n * the unknown scheme — silently 302'ing every request to \"/\".\n */\nimport { createRequestHandler } from \"react-router\";\nimport { defineEventHandler, type H3Event } from \"h3\";\nimport { getSentryClientConfigScript } from \"./sentry-config.js\";\nimport { BETTER_AUTH_COOKIE_PREFIX, COOKIE_NAME, getSession } from \"./auth.js\";\nimport {\n hasAuthContextAccess,\n runWithRequestContext,\n type RequestContext,\n} from \"./request-context.js\";\nimport { requestHasEmbedAuthMarker } from \"./embed-session.js\";\nimport {\n EMBED_SESSION_COOKIE,\n EMBED_TOKEN_QUERY_PARAM,\n} from \"../shared/embed-auth.js\";\nimport { AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE } from \"../shared/social-meta.js\";\nimport {\n DEFAULT_SPECULATION_RULES_PATH,\n DEFAULT_SSR_CACHE_CONTROL,\n} from \"../shared/cache-control.js\";\n\nexport {\n DEFAULT_SPECULATION_RULES_HEADER,\n DEFAULT_SSR_CACHE_CONTROL,\n} from \"../shared/cache-control.js\";\nconst ANONYMOUS_SESSION_COOKIE_NAMES = new Set([\"an_docs_session\"]);\nconst BETTER_AUTH_SESSION_COOKIE_RE = /\\.session_(?:token|data)$/;\n\n/**\n * Read the active org for a request without forcing every template to bundle\n * the org module. Mirrors what `core-routes-plugin` does for action handlers.\n */\nasync function readOrgIdForEvent(event: H3Event): Promise<string | undefined> {\n try {\n const { getOrgContext } = await import(\"../org/context.js\");\n const ctx = await getOrgContext(event);\n return ctx?.orgId ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeAppBasePath(value: string | undefined): string {\n if (!value || value === \"/\") return \"\";\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n return `/${trimmed.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\")}`;\n}\n\nfunction getAppBasePath(): string {\n const metaEnv = (\n import.meta as unknown as {\n env?: Record<string, string | undefined>;\n }\n ).env;\n return normalizeAppBasePath(\n process.env.VITE_APP_BASE_PATH ||\n process.env.APP_BASE_PATH ||\n metaEnv?.VITE_APP_BASE_PATH ||\n metaEnv?.APP_BASE_PATH ||\n metaEnv?.BASE_URL,\n );\n}\n\nfunction stripAppBasePath(pathname: string): string {\n const basePath = getAppBasePath();\n return stripBasePath(pathname, basePath);\n}\n\nfunction stripBasePath(pathname: string, basePath: string): string {\n if (!basePath) return pathname;\n if (pathname === basePath) return \"/\";\n if (pathname.startsWith(`${basePath}/`)) {\n return pathname.slice(basePath.length) || \"/\";\n }\n return pathname;\n}\n\nfunction requestWithPathname(\n request: Request,\n pathname: string,\n basePath: string,\n): Request {\n const url = new URL(request.url);\n let changed = false;\n if (basePath && pathname === \"/__manifest\") {\n const paths = url.searchParams.get(\"paths\");\n if (paths) {\n const strippedPaths = paths\n .split(\",\")\n .map((path) => stripBasePath(path, basePath))\n .join(\",\");\n if (strippedPaths !== paths) {\n url.searchParams.set(\"paths\", strippedPaths);\n changed = true;\n }\n }\n }\n if (url.pathname !== pathname) {\n url.pathname = pathname;\n changed = true;\n }\n if (!changed) return request;\n const init: RequestInit & { duplex?: \"half\" } = {\n method: request.method,\n headers: request.headers,\n signal: request.signal,\n };\n if (request.body && ![\"GET\", \"HEAD\"].includes(request.method.toUpperCase())) {\n init.body = request.body;\n init.duplex = \"half\";\n }\n return new Request(url, init);\n}\n\nfunction prefixMountedPath(path: string, basePath: string): string {\n if (!basePath || !path.startsWith(\"/\") || path.startsWith(\"//\")) return path;\n if (path === basePath || path.startsWith(`${basePath}/`)) return path;\n return `${basePath}${path}`;\n}\n\nfunction prefixMountedHtml(html: string, basePath: string): string {\n if (!basePath) return html;\n return html\n .replace(\n /\\b(href|src|action|formaction|poster)=([\"'])(\\/(?!\\/)[^\"']*)\\2/g,\n (_match, attr: string, quote: string, path: string) =>\n `${attr}=${quote}${prefixMountedPath(path, basePath)}${quote}`,\n )\n .replace(/url\\(([\"']?)(\\/(?!\\/)[^)'\" ]+)\\1\\)/g, (_match, quote, path) => {\n const q = quote || \"\";\n return `url(${q}${prefixMountedPath(path, basePath)}${q})`;\n });\n}\n\nfunction injectHeadScript(html: string, script: string | null): string {\n if (!script) return html;\n const headCloseIdx = html.indexOf(\"</head>\");\n if (headCloseIdx === -1) return html;\n return html.slice(0, headCloseIdx) + script + html.slice(headCloseIdx);\n}\n\nconst OG_IMAGE_META_RE = /<meta\\b(?=[^>]*\\bproperty=([\"'])og:image\\1)[^>]*>/i;\nconst TWITTER_CARD_META_RE =\n /<meta\\b(?=[^>]*\\bname=([\"'])twitter:card\\1)[^>]*>/i;\nconst TWITTER_IMAGE_META_RE =\n /<meta\\b(?=[^>]*\\bname=([\"'])twitter:image\\1)[^>]*>/i;\n\nfunction injectDefaultSocialImageMeta(html: string): string {\n const headCloseIdx = html.indexOf(\"</head>\");\n if (headCloseIdx === -1) return html;\n\n const hasAnySocialImage =\n OG_IMAGE_META_RE.test(html) || TWITTER_IMAGE_META_RE.test(html);\n const tags: string[] = [];\n\n if (!hasAnySocialImage) {\n tags.push(\n `<meta property=\"og:image\" content=\"${AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE}\">`,\n );\n }\n if (!TWITTER_CARD_META_RE.test(html)) {\n tags.push(`<meta name=\"twitter:card\" content=\"summary_large_image\">`);\n }\n if (!hasAnySocialImage) {\n tags.push(\n `<meta name=\"twitter:image\" content=\"${AGENT_NATIVE_DEFAULT_SOCIAL_IMAGE}\">`,\n );\n }\n\n if (tags.length === 0) return html;\n return html.slice(0, headCloseIdx) + tags.join(\"\") + html.slice(headCloseIdx);\n}\n\nfunction requestHasAuthSignal(event: H3Event): boolean {\n const headers = event.req.headers;\n return Boolean(\n headers.get(\"authorization\") ||\n requestHasAuthenticatedCookie(headers.get(\"cookie\")) ||\n event.url.searchParams.has(EMBED_TOKEN_QUERY_PARAM) ||\n event.url.searchParams.has(\"_session\") ||\n requestHasEmbedAuthMarker(event),\n );\n}\n\nfunction requestHasAuthenticatedCookie(cookieHeader: string | null): boolean {\n if (!cookieHeader) return false;\n return cookieHeader\n .split(\";\")\n .map((cookie) => cookie.trim().split(\"=\", 1)[0]?.trim())\n .filter((name): name is string => Boolean(name))\n .some(isAuthenticatedCookieName);\n}\n\nfunction isAuthenticatedCookieName(name: string): boolean {\n if (ANONYMOUS_SESSION_COOKIE_NAMES.has(name)) return false;\n const bareName = name.replace(/^__(?:Secure|Host)-/, \"\");\n return (\n bareName === COOKIE_NAME ||\n bareName === EMBED_SESSION_COOKIE ||\n bareName === \"an_session\" ||\n bareName === \"an_session_workspace\" ||\n bareName.startsWith(\"an_session_\") ||\n bareName === `${BETTER_AUTH_COOKIE_PREFIX}.session_token` ||\n bareName === `${BETTER_AUTH_COOKIE_PREFIX}.session_data` ||\n BETTER_AUTH_SESSION_COOKIE_RE.test(bareName)\n );\n}\n\nfunction shouldUseDefaultSsrCacheHeader(\n headers: Headers,\n status: number,\n pathname: string,\n authContextAccessed: boolean,\n): boolean {\n if (status < 200 || status >= 400) return false;\n if (authContextAccessed) {\n // Do not bypass cache just because a browser carries an auth-looking\n // cookie: public docs/pages can receive stale workspace cookies and should\n // still warm the CDN. But if SSR code actually reads user/org context,\n // that route is rendering private data and must not be public-cached.\n // Move those reads to client-side actions/API to regain CDN caching.\n return false;\n }\n\n const contentType = headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (contentType.includes(\"text/html\")) {\n // SSR HTML is public app shell in this framework; any per-user state is\n // fetched after hydration. Always enforce the framework SWR default here;\n // route-level no-cache/private headers on SSR HTML recreate the same\n // origin stampede this cache policy is meant to prevent.\n return true;\n }\n\n if (!pathname.endsWith(\".data\")) return false;\n if (!contentType.includes(\"text/x-script\")) return false;\n\n // React Router gives loader `.data` responses `cache-control: no-cache` by\n // default. In Agent-Native, SSR output is intentionally public app shell:\n // user/org-specific reads happen after hydration through actions and API\n // routes. Keep `.data` on the same short-fresh/long-SWR policy as HTML so\n // route data fetches warm the CDN instead of hammering origin.\n // Do not re-add a blanket cookie/auth-signal bypass here: logged-in browsers\n // still need CDN-cached public route data. The auth-context leak guard above\n // is the narrow protection for old SSR loaders that still read user/org data.\n // Also do not preserve route-level private/no-store for React Router .data:\n // if a route needs per-user data, it belongs behind a client-side action/API\n // call rather than in the shared SSR payload.\n return true;\n}\n\nfunction applyDefaultSsrCacheHeader(\n headers: Headers,\n status: number,\n pathname: string,\n authContextAccessed: boolean,\n) {\n if (\n !shouldUseDefaultSsrCacheHeader(\n headers,\n status,\n pathname,\n authContextAccessed,\n )\n ) {\n return;\n }\n headers.set(\"cache-control\", DEFAULT_SSR_CACHE_CONTROL);\n}\n\nfunction applyDefaultSpeculationRulesHeader(\n headers: Headers,\n status: number,\n basePath: string,\n) {\n if (status < 200 || status >= 400) return;\n if (headers.has(\"speculation-rules\")) return;\n\n const contentType = headers.get(\"content-type\")?.toLowerCase() ?? \"\";\n if (!contentType.includes(\"text/html\")) return;\n\n // Cloudflare Speed Brain injects its own Speculation-Rules header when the\n // origin omits one. Those browser prefetches carry `Sec-Purpose: prefetch`,\n // and Cloudflare refuses cache-ineligible dynamic pages with a 503 before\n // the request can reach Netlify/origin. We publish an explicit no-op ruleset\n // by default so Cloudflare does not inject its edge prefetch rules. Preserve\n // an app-provided Speculation-Rules header above if a template deliberately\n // owns this behavior.\n const rulesPath = prefixMountedPath(DEFAULT_SPECULATION_RULES_PATH, basePath);\n headers.set(\"speculation-rules\", `\"${rulesPath}\"`);\n}\n\nfunction isFrameworkOrAssetPath(pathname: string): boolean {\n return (\n pathname.startsWith(\"/.well-known/\") ||\n pathname.startsWith(\"/_agent_native/\") ||\n pathname.startsWith(\"/_agent-native/\") ||\n pathname.startsWith(\"/api/\") ||\n pathname.startsWith(\"/@vite/\") ||\n pathname.startsWith(\"/@id/\") ||\n pathname.startsWith(\"/@fs/\") ||\n pathname === \"/@react-refresh\" ||\n pathname === \"/__vite_ping\" ||\n pathname === \"/__open-in-editor\" ||\n pathname === \"/favicon.ico\" ||\n pathname === \"/favicon.png\" ||\n (/\\.\\w+$/.test(pathname) && !pathname.endsWith(\".data\"))\n );\n}\n\nasync function rewriteMountedResponse(\n response: Response,\n basePath: string,\n pathname: string,\n requestContext?: RequestContext,\n): Promise<Response> {\n const sentryClientConfigScript = getSentryClientConfigScript();\n const headers = new Headers(response.headers);\n applyDefaultSsrCacheHeader(\n headers,\n response.status,\n pathname,\n hasAuthContextAccess(requestContext),\n );\n applyDefaultSpeculationRulesHeader(headers, response.status, basePath);\n\n const location = headers.get(\"location\");\n if (location?.startsWith(\"/\") && !location.startsWith(\"//\")) {\n headers.set(\"location\", prefixMountedPath(location, basePath));\n }\n\n const contentType = headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().includes(\"text/html\") || !response.body) {\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n const html = await response.text();\n headers.delete(\"content-length\");\n return new Response(\n injectHeadScript(\n injectDefaultSocialImageMeta(prefixMountedHtml(html, basePath)),\n sentryClientConfigScript,\n ),\n {\n status: response.status,\n statusText: response.statusText,\n headers,\n },\n );\n}\n\n/**\n * Create an h3 catch-all that hands page routes to React Router and\n * returns 404 for framework / asset paths that React Router doesn't own.\n */\nexport function createH3SSRHandler(getBuild: () => Promise<unknown> | unknown) {\n const handler = createRequestHandler(getBuild as any);\n return defineEventHandler(async (event) => {\n const basePath = getAppBasePath();\n const p = stripAppBasePath(event.url.pathname);\n if (isFrameworkOrAssetPath(p)) {\n return new Response(null, { status: 404 });\n }\n try {\n const request = requestWithPathname(event.req as Request, p, basePath);\n // Pin the active session onto the async request context so React Router\n // loaders that call `getRequestUserEmail()` / `accessFilter()` see the\n // signed-in user. Without this, SSR loaders fall through to the\n // unauthenticated branch even when the user is logged in — which broke\n // shared-deck \"Presentation link\" access for non-public decks.\n let session: Awaited<ReturnType<typeof getSession>> | null = null;\n const hasAuthSignal = requestHasAuthSignal(event);\n if (hasAuthSignal) {\n try {\n session = await getSession(event);\n } catch {\n // Auth lookup failures must not break SSR; treat as unauthenticated.\n }\n }\n const orgId = session?.email ? await readOrgIdForEvent(event) : undefined;\n const ctx = {\n userEmail: session?.email ?? undefined,\n orgId,\n };\n if (request.method === \"HEAD\") {\n const getRequest = new Request(request.url, {\n method: \"GET\",\n headers: request.headers,\n signal: request.signal,\n });\n const response = await runWithRequestContext(ctx, () =>\n handler(getRequest),\n );\n return await rewriteMountedResponse(\n new Response(null, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n }),\n basePath,\n p,\n ctx,\n );\n }\n return await rewriteMountedResponse(\n await runWithRequestContext(ctx, () => handler(request)),\n basePath,\n p,\n ctx,\n );\n } catch (err) {\n // Log the full stack server-side, but never leak it to the client.\n // Stack traces expose file paths, library versions, and code structure\n // that aid reconnaissance attacks. In dev we surface the message text\n // so devtools shows something useful; in prod we return a bare 500.\n console.error(\"[ssr-handler] SSR error:\", err);\n const isProd = process.env.NODE_ENV === \"production\";\n const body = isProd\n ? \"Internal Server Error\"\n : `Internal Server Error: ${(err as Error)?.message ?? err}`;\n return new Response(body, {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n });\n}\n"]}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export declare const DEFAULT_SSR_CACHE_CONTROL = "public, max-age=5, stale-while-revalidate=604800, stale-if-error=3600";
|
|
2
|
+
export declare const DEFAULT_SPECULATION_RULES_PATH = "/_agent-native/speculation-rules.json";
|
|
3
|
+
export declare const DEFAULT_SPECULATION_RULES_HEADER = "\"/_agent-native/speculation-rules.json\"";
|
|
4
|
+
export declare const EMPTY_SPECULATION_RULES: {
|
|
5
|
+
readonly prefetch: readonly [];
|
|
6
|
+
readonly prerender: readonly [];
|
|
7
|
+
};
|
|
2
8
|
//# sourceMappingURL=cache-control.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-control.d.ts","sourceRoot":"","sources":["../../src/shared/cache-control.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,0EACmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"cache-control.d.ts","sourceRoot":"","sources":["../../src/shared/cache-control.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,0EACmC,CAAC;AAE1E,eAAO,MAAM,8BAA8B,0CACF,CAAC;AAE1C,eAAO,MAAM,gCAAgC,8CAAwC,CAAC;AAEtF,eAAO,MAAM,uBAAuB;;;CAG1B,CAAC"}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export const DEFAULT_SSR_CACHE_CONTROL = "public, max-age=5, stale-while-revalidate=604800, stale-if-error=3600";
|
|
2
|
+
export const DEFAULT_SPECULATION_RULES_PATH = "/_agent-native/speculation-rules.json";
|
|
3
|
+
export const DEFAULT_SPECULATION_RULES_HEADER = `"${DEFAULT_SPECULATION_RULES_PATH}"`;
|
|
4
|
+
export const EMPTY_SPECULATION_RULES = {
|
|
5
|
+
prefetch: [],
|
|
6
|
+
prerender: [],
|
|
7
|
+
};
|
|
2
8
|
//# sourceMappingURL=cache-control.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-control.js","sourceRoot":"","sources":["../../src/shared/cache-control.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GACpC,uEAAuE,CAAC","sourcesContent":["export const DEFAULT_SSR_CACHE_CONTROL =\n \"public, max-age=5, stale-while-revalidate=604800, stale-if-error=3600\";\n"]}
|
|
1
|
+
{"version":3,"file":"cache-control.js","sourceRoot":"","sources":["../../src/shared/cache-control.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GACpC,uEAAuE,CAAC;AAE1E,MAAM,CAAC,MAAM,8BAA8B,GACzC,uCAAuC,CAAC;AAE1C,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,8BAA8B,GAAG,CAAC;AAEtF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,EAAE;CACL,CAAC","sourcesContent":["export const DEFAULT_SSR_CACHE_CONTROL =\n \"public, max-age=5, stale-while-revalidate=604800, stale-if-error=3600\";\n\nexport const DEFAULT_SPECULATION_RULES_PATH =\n \"/_agent-native/speculation-rules.json\";\n\nexport const DEFAULT_SPECULATION_RULES_HEADER = `\"${DEFAULT_SPECULATION_RULES_PATH}\"`;\n\nexport const EMPTY_SPECULATION_RULES = {\n prefetch: [],\n prerender: [],\n} as const;\n"]}
|