// The route report (D-33): at server start the layer posts its static // routes (#seo-routes, built from the pages) to the SEO plugin's // POST /_seo/api/v1/registry/routes with the route-report token, so the // CMS's page registry knows every frontend page. Pure helpers for the // Nitro plugin server/plugins/seo-route-report.ts, so `node --test` drives // them. /** The plugin's limits: at most 2000 paths of at most 2048 bytes each. */ export const ROUTE_REPORT_MAX_ROUTES = 2000 export const ROUTE_REPORT_MAX_BYTES = 2048 /** The one retry after a failed report waits this long. */ export const ROUTE_REPORT_RETRY_MS = 60_000 /** The request body: the paths within the plugin's limits. */ export function routeReportBody(paths: readonly string[]): { routes: string[] } { const routes = paths .filter((p) => typeof p === 'string' && p.startsWith('/') && Buffer.byteLength(p, 'utf8') <= ROUTE_REPORT_MAX_BYTES) .slice(0, ROUTE_REPORT_MAX_ROUTES) return { routes } } /** * What an answer means: sent (2xx), absent (404: a backend without the * page registry, or with both tokens empty; never retried), refused (401 or * 403: the token is wrong; never retried) or retry (no answer, or any other * status: tried once more after ROUTE_REPORT_RETRY_MS). */ export function routeReportOutcome(status: number | null): 'sent' | 'absent' | 'refused' | 'retry' { if (status !== null && status >= 200 && status < 300) return 'sent' if (status === 404) return 'absent' if (status === 401 || status === 403) return 'refused' return 'retry' }