UNPKG

mongoku

Version:

[![CI](https://github.com/huggingface/Mongoku/actions/workflows/ci.yml/badge.svg)](https://github.com/huggingface/Mongoku/actions/workflows/ci.yml)

1,557 lines (1,548 loc) 142 kB
import { n as noop, f as format_server_error, i as is_form_content_type, T as TRAILING_SLASH_PARAM, I as INVALIDATED_PARAM, h as has_prerendered_path, a as handle_fatal_error, r as redirect_response, m as method_not_allowed, b as negotiate, g as get_global_name, c as create_remote_key, s as serialize_uses, d as clarify_devalue_error, o as once, e as handle_error_and_jsonify, E as ENDPOINT_METHODS, P as PAGE_METHODS, j as get_status, k as normalize_error, l as static_error_page, p as parse_remote_arg, q as stringify, t as deserialize_binary_form, u as get_node_type, v as stringify$1, w as escape_html, x as split_remote_key, S as SVELTE_KIT_ASSETS } from './chunks/shared-DlqhoNLb.js'; import { I as root, J as decode_pathname, K as DEV, L as normalize_path, O as disable_search, w as with_request_store, A as uneval, Q as resolve, R as make_trackable } from './chunks/root-otUAnOAR.js'; import { j as json, t as text, R as Redirect, S as SvelteKitError, H as HttpError, e as error, A as ActionFailure, i as isRedirect } from './chunks/index-NcxaM188.js'; import { b as base, a as app_dir, c as assets, r as relative, o as override, d as reset } from './chunks/server-Crjo4w1q.js'; import { t as text_encoder, g as get_relative_path, a as base64_encode } from './chunks/utils-BQzn9ikS.js'; import { w as writable, r as readable } from './chunks/index-CtYzvcG6.js'; import { s as set_private_env, a as set_public_env, b as public_env } from './chunks/shared-server-BmU87nph.js'; import { f as find_route } from './chunks/routing-EDfUNu8L.js'; import { v as validate_layout_server_exports, a as validate_layout_exports, b as validate_page_server_exports, c as validate_page_exports } from './chunks/exports-B5ORJhfK.js'; import './chunks/async-DUoD1OpG.js'; /** * @template {{ tracing: { enabled: boolean, root: import('@opentelemetry/api').Span, current: import('@opentelemetry/api').Span } }} T * @param {T} event_like * @param {import('@opentelemetry/api').Span} current * @returns {T} */ function merge_tracing(event_like, current) { return { ...event_like, tracing: { ...event_like.tracing, current } }; } let read_implementation = null; function set_read_implementation(fn) { read_implementation = fn; } const options = { app_template_contains_nonce: false, async: true, csp: { "mode": "auto", "directives": { "upgrade-insecure-requests": false, "block-all-mixed-content": false }, "reportOnly": { "upgrade-insecure-requests": false, "block-all-mixed-content": false } }, csrf_check_origin: true, csrf_trusted_origins: [], embedded: false, env_public_prefix: "PUBLIC_", env_private_prefix: "", hash_routing: false, hooks: null, // added lazily, via `get_hooks` preload_strategy: "modulepreload", root, service_worker: false, service_worker_options: void 0, server_error_boundaries: false, templates: { app: ({ head, body, assets, nonce, env }) => '<!doctype html>\n<html lang="en" class="h-full">\n <head>\n <meta charset="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <meta name="color-scheme" content="light dark" />\n <script>\n // Set initial theme early to avoid flash\n (function () {\n try {\n const stored = localStorage.getItem("theme");\n const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;\n const theme = stored || "system";\n let actualTheme;\n\n if (theme === "system") {\n actualTheme = prefersDark ? "dark" : "light";\n } else {\n actualTheme = theme;\n }\n\n document.documentElement.setAttribute("data-theme", actualTheme);\n document.documentElement.setAttribute("data-theme-mode", theme);\n\n // Also add/remove dark class for Tailwind\n if (actualTheme === "dark") {\n document.documentElement.classList.add("dark");\n } else {\n document.documentElement.classList.remove("dark");\n }\n } catch (e) {}\n })();\n <\/script>\n ' + head + '\n </head>\n <body data-sveltekit-preload-data="hover">\n <div style="display: contents">' + body + "</div>\n </body>\n</html>\n", error: ({ status, message }) => '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <title>' + message + `</title> <style> body { --bg: white; --fg: #222; --divider: #ccc; background: var(--bg); color: var(--fg); font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; } .error { display: flex; align-items: center; max-width: 32rem; margin: 0 1rem; } .status { font-weight: 200; font-size: 3rem; line-height: 1; position: relative; top: -0.05rem; } .message { border-left: 1px solid var(--divider); padding: 0 0 0 1rem; margin: 0 0 0 1rem; min-height: 2.5rem; display: flex; align-items: center; } .message h1 { font-weight: 400; font-size: 1em; margin: 0; } @media (prefers-color-scheme: dark) { body { --bg: #222; --fg: #ddd; --divider: #666; } } </style> </head> <body> <div class="error"> <span class="status">` + status + '</span>\n <div class="message">\n <h1>' + message + "</h1>\n </div>\n </div>\n </body>\n</html>\n" }, version_hash: "ohx1vj" }; async function get_hooks() { let handle; let handleFetch; let handleError; let handleValidationError; let init; ({ handle, handleFetch, handleError, handleValidationError, init } = await import('./chunks/hooks.server-BiUSRqj1.js')); let reroute; let transport; return { handle, handleFetch, handleError, handleValidationError, init, reroute, transport }; } function with_resolvers() { let resolve2; let reject; const promise = new Promise((res, rej) => { resolve2 = res; reject = rej; }); return { promise, resolve: resolve2, reject }; } const NULL_BODY_STATUS = [101, 103, 204, 205, 304]; const IN_WEBCONTAINER = !!globalThis.process?.versions?.webcontainer; const s = JSON.stringify; async function render_endpoint(event, event_state, mod, state) { const method = ( /** @type {import('types').HttpMethod} */ event.request.method ); let handler = mod[method] || mod.fallback; if (method === "HEAD" && !mod.HEAD && mod.GET) { handler = mod.GET; } if (!handler) { return method_not_allowed(mod, method); } const prerender = mod.prerender ?? state.prerender_default; if (prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) { throw new Error("Cannot prerender endpoints that have mutative methods"); } if (state.prerendering && !state.prerendering.inside_reroute && !prerender) { if (state.depth > 0) { throw new Error(`${event.route.id} is not prerenderable`); } else { return new Response(void 0, { status: 204 }); } } try { const response = await with_request_store( { event, state: event_state }, () => handler( /** @type {import('@sveltejs/kit').RequestEvent<Record<string, any>>} */ event ) ); if (!(response instanceof Response)) { throw new Error( `Invalid response from route ${event.url.pathname}: handler should return a Response object` ); } if (state.prerendering && (!state.prerendering.inside_reroute || prerender)) { const cloned = new Response(response.clone().body, { status: response.status, statusText: response.statusText, headers: new Headers(response.headers) }); cloned.headers.set("x-sveltekit-prerender", String(prerender)); if (state.prerendering.inside_reroute && prerender) { cloned.headers.set( "x-sveltekit-routeid", encodeURI( /** @type {string} */ event.route.id ) ); state.prerendering.dependencies.set(event.url.pathname, { response: cloned, body: null }); } else { return cloned; } } return response; } catch (e) { if (e instanceof Redirect) { return new Response(void 0, { status: e.status, headers: { location: e.location } }); } throw e; } } function is_endpoint_request(event) { const { method, headers: headers2 } = event.request; if (ENDPOINT_METHODS.includes(method) && !PAGE_METHODS.includes(method)) { return true; } if (method === "POST" && headers2.get("x-sveltekit-action") === "true") return false; const accept = event.request.headers.get("accept") ?? "*/*"; return negotiate(accept, ["*", "text/html"]) !== "text/html"; } function compact(arr) { return arr.filter( /** @returns {val is NonNullable<T>} */ (val) => val != null ); } const DATA_SUFFIX = "/__data.json"; const HTML_DATA_SUFFIX = ".html__data.json"; function has_data_suffix(pathname) { return pathname.endsWith(DATA_SUFFIX) || pathname.endsWith(HTML_DATA_SUFFIX); } function add_data_suffix(pathname) { if (pathname.endsWith(".html")) return pathname.replace(/\.html$/, HTML_DATA_SUFFIX); return pathname.replace(/\/$/, "") + DATA_SUFFIX; } function strip_data_suffix(pathname) { if (pathname.endsWith(HTML_DATA_SUFFIX)) { return pathname.slice(0, -HTML_DATA_SUFFIX.length) + ".html"; } return pathname.slice(0, -DATA_SUFFIX.length); } const ROUTE_SUFFIX = "/__route.js"; function has_resolution_suffix(pathname) { return pathname.endsWith(ROUTE_SUFFIX); } function add_resolution_suffix(pathname) { return pathname.replace(/\/$/, "") + ROUTE_SUFFIX; } function strip_resolution_suffix(pathname) { return pathname.slice(0, -ROUTE_SUFFIX.length); } const noop_span = { spanContext() { return noop_span_context; }, setAttribute() { return this; }, setAttributes() { return this; }, addEvent() { return this; }, setStatus() { return this; }, updateName() { return this; }, end() { return this; }, isRecording() { return false; }, recordException() { return this; }, addLink() { return this; }, addLinks() { return this; } }; const noop_span_context = { traceId: "", spanId: "", traceFlags: 0 }; async function record_span({ name, attributes, fn }) { { return fn(noop_span); } } function is_action_json_request(event) { const accept = negotiate(event.request.headers.get("accept") ?? "*/*", [ "application/json", "text/html" ]); return accept === "application/json" && event.request.method === "POST"; } async function handle_action_json_request(event, event_state, options2, server) { const actions = server?.actions; if (!actions) { const no_actions_error = new SvelteKitError( 405, "Method Not Allowed", `POST method not allowed. No form actions exist for ${"this page"}` ); return action_json( { type: "error", error: await handle_error_and_jsonify(event, event_state, options2, no_actions_error) }, { status: no_actions_error.status, headers: { // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405 // "The server must generate an Allow header field in a 405 status code response" allow: "GET" } } ); } check_named_default_separate(actions); try { const data = await call_action(event, event_state, actions); if (DEV) ; if (data instanceof ActionFailure) { return action_json({ type: "failure", status: data.status, // @ts-expect-error we assign a string to what is supposed to be an object. That's ok // because we don't use the object outside, and this way we have better code navigation // through knowing where the related interface is used. data: stringify_action_response( data.data, /** @type {string} */ event.route.id, options2.hooks.transport ) }); } else { return action_json({ type: "success", status: data ? 200 : 204, // @ts-expect-error see comment above data: stringify_action_response( data, /** @type {string} */ event.route.id, options2.hooks.transport ) }); } } catch (e) { const err = normalize_error(e); if (err instanceof Redirect) { return action_json_redirect(err); } return action_json( { type: "error", error: await handle_error_and_jsonify( event, event_state, options2, check_incorrect_fail_use(err) ) }, { status: get_status(err) } ); } } function check_incorrect_fail_use(error2) { return error2 instanceof ActionFailure ? new Error('Cannot "throw fail()". Use "return fail()"') : error2; } function action_json_redirect(redirect) { return action_json({ type: "redirect", status: redirect.status, location: redirect.location }); } function action_json(data, init2) { return json(data, init2); } function is_action_request(event) { return event.request.method === "POST"; } async function handle_action_request(event, event_state, server) { const actions = server?.actions; if (!actions) { event.setHeaders({ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405 // "The server must generate an Allow header field in a 405 status code response" allow: "GET" }); return { type: "error", error: new SvelteKitError( 405, "Method Not Allowed", `POST method not allowed. No form actions exist for ${"this page"}` ) }; } check_named_default_separate(actions); try { const data = await call_action(event, event_state, actions); if (DEV) ; if (data instanceof ActionFailure) { return { type: "failure", status: data.status, data: data.data }; } else { return { type: "success", status: 200, // @ts-expect-error this will be removed upon serialization, so `undefined` is the same as omission data }; } } catch (e) { const err = normalize_error(e); if (err instanceof Redirect) { return { type: "redirect", status: err.status, location: err.location }; } return { type: "error", error: check_incorrect_fail_use(err) }; } } function check_named_default_separate(actions) { if (actions.default && Object.keys(actions).length > 1) { throw new Error( "When using named actions, the default action cannot be used. See the docs for more info: https://svelte.dev/docs/kit/form-actions#named-actions" ); } } async function call_action(event, event_state, actions) { const url = new URL(event.request.url); let name = "default"; for (const param of url.searchParams) { if (param[0].startsWith("/")) { name = param[0].slice(1); if (name === "default") { throw new Error('Cannot use reserved action name "default"'); } break; } } const action = actions[name]; if (!action) { throw new SvelteKitError(404, "Not Found", `No action with name '${name}' found`); } if (!is_form_content_type(event.request)) { throw new SvelteKitError( 415, "Unsupported Media Type", `Form actions expect form-encoded data — received ${event.request.headers.get( "content-type" )}` ); } return record_span({ name: "sveltekit.form_action", attributes: { "http.route": event.route.id || "unknown" }, fn: async (current2) => { const traced_event = merge_tracing(event, current2); const result = await with_request_store( { event: traced_event, state: event_state }, () => action(traced_event) ); if (result instanceof ActionFailure) { current2.setAttributes({ "sveltekit.form_action.result.type": "failure", "sveltekit.form_action.result.status": result.status }); } return result; } }); } function uneval_action_response(data, route_id, transport) { const replacer = (thing) => { for (const key2 in transport) { const encoded = transport[key2].encode(thing); if (encoded) { return `app.decode('${key2}', ${uneval(encoded, replacer)})`; } } }; return try_serialize(data, (value) => uneval(value, replacer), route_id); } function stringify_action_response(data, route_id, transport) { const encoders = Object.fromEntries( Object.entries(transport).map(([key2, value]) => [key2, value.encode]) ); return try_serialize(data, (value) => stringify$1(value, encoders), route_id); } function try_serialize(data, fn, route_id) { try { return fn(data); } catch (e) { const error2 = ( /** @type {any} */ e ); if (data instanceof Response) { throw new Error( `Data returned from action inside ${route_id} is not serializable. Form actions need to return plain objects or fail(). E.g. return { success: true } or return fail(400, { message: "invalid" });`, { cause: e } ); } if ("path" in error2) { let message = `Data returned from action inside ${route_id} is not serializable: ${error2.message}`; if (error2.path !== "") message += ` (data.${error2.path})`; throw new Error(message, { cause: e }); } throw error2; } } function create_async_iterator() { let resolved = -1; let returned = -1; const deferred = []; return { iterate: (transform = (x) => x) => { return { [Symbol.asyncIterator]() { return { next: async () => { const next = deferred[++returned]; if (!next) return { value: null, done: true }; const value = await next.promise; return { value: transform(value), done: false }; } }; } }; }, add: (promise) => { deferred.push(with_resolvers()); void promise.then((value) => { deferred[++resolved].resolve(value); }); } }; } function server_data_serializer(event, event_state, options2) { let promise_id = 1; let max_nodes = -1; const iterator = create_async_iterator(); const global = get_global_name(options2); function get_replacer(index) { return function replacer(thing) { if (typeof thing?.then === "function") { const id = promise_id++; const promise = thing.then( /** @param {any} data */ (data) => ({ data }) ).catch( /** @param {any} error */ async (error2) => ({ error: await handle_error_and_jsonify(event, event_state, options2, error2) }) ).then( /** * @param {{data: any; error: any}} result */ async ({ data, error: error2 }) => { let str; try { str = uneval(error2 ? [, error2] : [data], replacer); } catch { error2 = await handle_error_and_jsonify( event, event_state, options2, new Error(`Failed to serialize promise while rendering ${event.route.id}`) ); str = uneval([, error2], replacer); } return { index, str: `${global}.resolve(${id}, ${str.includes("app.decode") ? `(app) => ${str}` : `() => ${str}`})` }; } ); iterator.add(promise); return `${global}.defer(${id})`; } else { for (const key2 in options2.hooks.transport) { const encoded = options2.hooks.transport[key2].encode(thing); if (encoded) { return `app.decode('${key2}', ${uneval(encoded, replacer)})`; } } } }; } const strings = ( /** @type {string[]} */ [] ); return { set_max_nodes(i) { max_nodes = i; }, add_node(i, node) { try { if (!node) { strings[i] = "null"; return; } const payload = { type: "data", data: node.data, uses: serialize_uses(node) }; if (node.slash) payload.slash = node.slash; strings[i] = uneval(payload, get_replacer(i)); } catch (e) { e.path = e.path.slice(1); throw new Error(clarify_devalue_error( event, /** @type {any} */ e ), { cause: e }); } }, get_data(csp) { const open = `<script${csp.script_needs_nonce ? ` nonce="${csp.nonce}"` : ""}>`; const close = `<\/script> `; return { data: `[${compact(max_nodes > -1 ? strings.slice(0, max_nodes) : strings).join(",")}]`, chunks: promise_id > 1 ? iterator.iterate(({ index, str }) => { if (max_nodes > -1 && index >= max_nodes) { return ""; } return open + str + close; }) : null }; } }; } function server_data_serializer_json(event, event_state, options2) { let promise_id = 1; const iterator = create_async_iterator(); const reducers = { ...Object.fromEntries( Object.entries(options2.hooks.transport).map(([key2, value]) => [key2, value.encode]) ), /** @param {any} thing */ Promise: (thing) => { if (typeof thing?.then !== "function") { return; } const id = promise_id++; let key2 = "data"; const promise = thing.catch( /** @param {any} e */ async (e) => { key2 = "error"; return handle_error_and_jsonify( event, event_state, options2, /** @type {any} */ e ); } ).then( /** @param {any} value */ async (value) => { let str; try { str = stringify$1(value, reducers); } catch { const error2 = await handle_error_and_jsonify( event, event_state, options2, new Error(`Failed to serialize promise while rendering ${event.route.id}`) ); key2 = "error"; str = stringify$1(error2, reducers); } return `{"type":"chunk","id":${id},"${key2}":${str}} `; } ); iterator.add(promise); return id; } }; const strings = ( /** @type {string[]} */ [] ); return { add_node(i, node) { try { if (!node) { strings[i] = "null"; return; } if (node.type === "error" || node.type === "skip") { strings[i] = JSON.stringify(node); return; } strings[i] = `{"type":"data","data":${stringify$1(node.data, reducers)},"uses":${JSON.stringify( serialize_uses(node) )}${node.slash ? `,"slash":${JSON.stringify(node.slash)}` : ""}}`; } catch (e) { e.path = "data" + e.path; throw new Error(clarify_devalue_error( event, /** @type {any} */ e ), { cause: e }); } }, get_data() { return { data: `{"type":"data","nodes":[${strings.join(",")}]} `, chunks: promise_id > 1 ? iterator.iterate() : null }; } }; } async function load_server_data({ event, event_state, state, node, parent }) { if (!node?.server) return null; let is_tracking = true; const uses = { dependencies: /* @__PURE__ */ new Set(), params: /* @__PURE__ */ new Set(), parent: false, route: false, url: false, search_params: /* @__PURE__ */ new Set() }; const load = node.server.load; const slash = node.server.trailingSlash; if (!load) { return { type: "data", data: null, uses, slash }; } const url = make_trackable( event.url, () => { if (is_tracking) { uses.url = true; } }, (param) => { if (is_tracking) { uses.search_params.add(param); } } ); if (state.prerendering) { disable_search(url); } const result = await record_span({ name: "sveltekit.load", attributes: { "sveltekit.load.node_id": node.server_id || "unknown", "sveltekit.load.node_type": get_node_type(node.server_id), "http.route": event.route.id || "unknown" }, fn: async (current2) => { const traced_event = merge_tracing(event, current2); const result2 = await with_request_store( { event: traced_event, state: event_state }, () => load.call(null, { ...traced_event, fetch: (info, init2) => { new URL(info instanceof Request ? info.url : info, event.url); return event.fetch(info, init2); }, /** @param {string[]} deps */ depends: (...deps) => { for (const dep of deps) { const { href } = new URL(dep, event.url); uses.dependencies.add(href); } }, params: new Proxy(event.params, { get: (target, key2) => { if (is_tracking) { uses.params.add(key2); } return target[ /** @type {string} */ key2 ]; } }), parent: async () => { if (is_tracking) { uses.parent = true; } return parent(); }, route: new Proxy(event.route, { get: (target, key2) => { if (is_tracking) { uses.route = true; } return target[ /** @type {'id'} */ key2 ]; } }), url, untrack(fn) { is_tracking = false; try { return fn(); } finally { is_tracking = true; } } }) ); return result2; } }); return { type: "data", data: result ?? null, uses, slash }; } async function load_data({ event, event_state, fetched, node, parent, server_data_promise, state, resolve_opts, csr }) { const server_data_node = await server_data_promise; const load = node?.universal?.load; if (!load) { return server_data_node?.data ?? null; } const result = await record_span({ name: "sveltekit.load", attributes: { "sveltekit.load.node_id": node.universal_id || "unknown", "sveltekit.load.node_type": get_node_type(node.universal_id), "http.route": event.route.id || "unknown" }, fn: async (current2) => { const traced_event = merge_tracing(event, current2); const child_state = { ...event_state, is_in_universal_load: true }; return await with_request_store( { event: traced_event, state: child_state }, () => load.call(null, { url: event.url, params: event.params, data: server_data_node?.data ?? null, route: event.route, fetch: create_universal_fetch(event, state, fetched, csr, resolve_opts), setHeaders: event.setHeaders, depends: noop, parent, untrack: (fn) => fn(), tracing: traced_event.tracing }) ); } }); return result ?? null; } function create_universal_fetch(event, state, fetched, csr, resolve_opts) { const universal_fetch = async (input, init2) => { const cloned_body = input instanceof Request && input.body ? input.clone().body : null; const cloned_headers = input instanceof Request && [...input.headers].length ? new Headers(input.headers) : init2?.headers; let response = await event.fetch(input, init2); const url = new URL(input instanceof Request ? input.url : input, event.url); const same_origin = url.origin === event.url.origin; let dependency; if (same_origin) { if (state.prerendering) { dependency = { response, body: null }; state.prerendering.dependencies.set(url.pathname, dependency); } } else if (url.protocol === "https:" || url.protocol === "http:") { const mode = input instanceof Request ? input.mode : init2?.mode ?? "cors"; if (mode === "no-cors") { response = new Response("", { status: response.status, statusText: response.statusText, headers: response.headers }); } else { const acao = response.headers.get("access-control-allow-origin"); if (!acao || acao !== event.url.origin && acao !== "*") { throw new Error( `CORS error: ${acao ? "Incorrect" : "No"} 'Access-Control-Allow-Origin' header is present on the requested resource` ); } } } let teed_body; const proxy = new Proxy(response, { get(response2, key2, receiver) { async function push_fetched(body2, is_b64) { const status_number = Number(response2.status); if (isNaN(status_number)) { throw new Error( `response.status is not a number. value: "${response2.status}" type: ${typeof response2.status}` ); } fetched.push({ url: same_origin ? url.href.slice(event.url.origin.length) : url.href, method: event.request.method, request_body: ( /** @type {string | ArrayBufferView | undefined} */ input instanceof Request && cloned_body ? await stream_to_string(cloned_body) : init2?.body ), request_headers: cloned_headers, response_body: body2, response: response2, is_b64 }); } if (key2 === "body") { if (response2.body === null) { return null; } if (teed_body) { return teed_body; } const [a, b] = response2.body.tee(); void (async () => { let result = new Uint8Array(); for await (const chunk of a) { const combined = new Uint8Array(result.length + chunk.length); combined.set(result, 0); combined.set(chunk, result.length); result = combined; } if (dependency) { dependency.body = new Uint8Array(result); } void push_fetched(base64_encode(result), true); })(); return teed_body = b; } if (key2 === "arrayBuffer") { return async () => { const buffer = await response2.arrayBuffer(); const bytes = new Uint8Array(buffer); if (dependency) { dependency.body = bytes; } if (buffer instanceof ArrayBuffer) { await push_fetched(base64_encode(bytes), true); } return buffer; }; } async function text2() { const body2 = await response2.text(); if (body2 === "" && NULL_BODY_STATUS.includes(response2.status)) { await push_fetched(void 0, false); return void 0; } if (!body2 || typeof body2 === "string") { await push_fetched(body2, false); } if (dependency) { dependency.body = body2; } return body2; } if (key2 === "text") { return text2; } if (key2 === "json") { return async () => { const body2 = await text2(); return body2 ? JSON.parse(body2) : void 0; }; } const value = Reflect.get(response2, key2, response2); if (value instanceof Function) { return Object.defineProperties( /** * @this {any} */ function() { return Reflect.apply(value, this === receiver ? response2 : this, arguments); }, { name: { value: value.name }, length: { value: value.length } } ); } return value; } }); if (csr) { const get = response.headers.get; response.headers.get = (key2) => { const lower = key2.toLowerCase(); const value = get.call(response.headers, lower); if (value && !lower.startsWith("x-sveltekit-")) { const included = resolve_opts.filterSerializedResponseHeaders(lower, value); if (!included) { throw new Error( `Failed to get response header "${lower}" — it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#Server-hooks-handle (at ${event.route.id})` ); } } return value; }; } return proxy; }; return (input, init2) => { const response = universal_fetch(input, init2); response.catch(noop); return response; }; } async function stream_to_string(stream) { let result = ""; const reader = stream.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) { result += decoder.decode(); break; } result += decoder.decode(value, { stream: true }); } return result; } function hash(...values) { let hash2 = 5381; for (const value of values) { if (typeof value === "string") { let i = value.length; while (i) hash2 = hash2 * 33 ^ value.charCodeAt(--i); } else if (ArrayBuffer.isView(value)) { const buffer = new Uint8Array(value.buffer, value.byteOffset, value.byteLength); let i = buffer.length; while (i) hash2 = hash2 * 33 ^ buffer[--i]; } else { throw new TypeError("value must be a string or TypedArray"); } } return (hash2 >>> 0).toString(36); } const replacements = { "<": "\\u003C", "\u2028": "\\u2028", "\u2029": "\\u2029" }; const pattern = new RegExp(`[${Object.keys(replacements).join("")}]`, "g"); function serialize_data(fetched, filter, prerendering = false) { const headers2 = {}; let cache_control = null; let age = null; let varyAny = false; for (const [key2, value] of fetched.response.headers) { if (filter(key2, value)) { headers2[key2] = value; } if (key2 === "cache-control") cache_control = value; else if (key2 === "age") age = value; else if (key2 === "vary" && value.trim() === "*") varyAny = true; } const payload = { status: fetched.response.status, statusText: fetched.response.statusText, headers: headers2, body: fetched.response_body }; const safe_payload = JSON.stringify(payload).replace(pattern, (match) => replacements[match]); const attrs = [ 'type="application/json"', "data-sveltekit-fetched", `data-url="${escape_html(fetched.url, true)}"` ]; if (fetched.is_b64) { attrs.push("data-b64"); } if (fetched.request_headers || fetched.request_body) { const values = []; if (fetched.request_headers) { values.push([...new Headers(fetched.request_headers)].join(",")); } if (fetched.request_body) { values.push(fetched.request_body); } attrs.push(`data-hash="${hash(...values)}"`); } if (!prerendering && fetched.method === "GET" && cache_control && !varyAny) { const match = /s-maxage=(\d+)/g.exec(cache_control) ?? /max-age=(\d+)/g.exec(cache_control); if (match) { const ttl = +match[1] - +(age ?? "0"); attrs.push(`data-ttl="${ttl}"`); } } return `<script ${attrs.join(" ")}>${safe_payload}<\/script>`; } function sha256(data) { if (!key[0]) precompute(); const out = init.slice(0); const array2 = encode(data); for (let i = 0; i < array2.length; i += 16) { const w = array2.subarray(i, i + 16); let tmp; let a; let b; let out0 = out[0]; let out1 = out[1]; let out2 = out[2]; let out3 = out[3]; let out4 = out[4]; let out5 = out[5]; let out6 = out[6]; let out7 = out[7]; for (let i2 = 0; i2 < 64; i2++) { if (i2 < 16) { tmp = w[i2]; } else { a = w[i2 + 1 & 15]; b = w[i2 + 14 & 15]; tmp = w[i2 & 15] = (a >>> 7 ^ a >>> 18 ^ a >>> 3 ^ a << 25 ^ a << 14) + (b >>> 17 ^ b >>> 19 ^ b >>> 10 ^ b << 15 ^ b << 13) + w[i2 & 15] + w[i2 + 9 & 15] | 0; } tmp = tmp + out7 + (out4 >>> 6 ^ out4 >>> 11 ^ out4 >>> 25 ^ out4 << 26 ^ out4 << 21 ^ out4 << 7) + (out6 ^ out4 & (out5 ^ out6)) + key[i2]; out7 = out6; out6 = out5; out5 = out4; out4 = out3 + tmp | 0; out3 = out2; out2 = out1; out1 = out0; out0 = tmp + (out1 & out2 ^ out3 & (out1 ^ out2)) + (out1 >>> 2 ^ out1 >>> 13 ^ out1 >>> 22 ^ out1 << 30 ^ out1 << 19 ^ out1 << 10) | 0; } out[0] = out[0] + out0 | 0; out[1] = out[1] + out1 | 0; out[2] = out[2] + out2 | 0; out[3] = out[3] + out3 | 0; out[4] = out[4] + out4 | 0; out[5] = out[5] + out5 | 0; out[6] = out[6] + out6 | 0; out[7] = out[7] + out7 | 0; } const bytes = new Uint8Array(out.buffer); reverse_endianness(bytes); return btoa(String.fromCharCode(...bytes)); } const init = new Uint32Array(8); const key = new Uint32Array(64); function precompute() { function frac(x) { return (x - Math.floor(x)) * 4294967296; } let prime = 2; for (let i = 0; i < 64; prime++) { let is_prime = true; for (let factor = 2; factor * factor <= prime; factor++) { if (prime % factor === 0) { is_prime = false; break; } } if (is_prime) { if (i < 8) { init[i] = frac(prime ** (1 / 2)); } key[i] = frac(prime ** (1 / 3)); i++; } } } function reverse_endianness(bytes) { for (let i = 0; i < bytes.length; i += 4) { const a = bytes[i + 0]; const b = bytes[i + 1]; const c = bytes[i + 2]; const d = bytes[i + 3]; bytes[i + 0] = d; bytes[i + 1] = c; bytes[i + 2] = b; bytes[i + 3] = a; } } function encode(str) { const encoded = text_encoder.encode(str); const length = encoded.length * 8; const size = 512 * Math.ceil((length + 65) / 512); const bytes = new Uint8Array(size / 8); bytes.set(encoded); bytes[encoded.length] = 128; reverse_endianness(bytes); const words = new Uint32Array(bytes.buffer); words[words.length - 2] = Math.floor(length / 4294967296); words[words.length - 1] = length; return words; } const array = new Uint8Array(16); function generate_nonce() { crypto.getRandomValues(array); return btoa(String.fromCharCode(...array)); } const quoted = /* @__PURE__ */ new Set([ "self", "unsafe-eval", "unsafe-hashes", "unsafe-inline", "none", "strict-dynamic", "report-sample", "wasm-unsafe-eval", "script" ]); const crypto_pattern = /^(nonce|sha\d\d\d)-/; class BaseProvider { /** @type {boolean} */ #use_hashes; /** @type {boolean} */ #script_needs_csp; /** @type {boolean} */ #script_src_needs_csp; /** @type {boolean} */ #script_src_elem_needs_csp; /** @type {boolean} */ #style_needs_csp; /** @type {boolean} */ #style_src_needs_csp; /** @type {boolean} */ #style_src_attr_needs_csp; /** @type {boolean} */ #style_src_elem_needs_csp; /** @type {import('types').CspDirectives} */ #directives; /** @type {Set<import('types').Csp.Source>} */ #script_src; /** @type {Set<import('types').Csp.Source>} */ #script_src_elem; /** @type {Set<import('types').Csp.Source>} */ #style_src; /** @type {Set<import('types').Csp.Source>} */ #style_src_attr; /** @type {Set<import('types').Csp.Source>} */ #style_src_elem; /** @type {boolean} */ script_needs_nonce; /** @type {boolean} */ style_needs_nonce; /** @type {boolean} */ script_needs_hash; /** @type {string} */ #nonce; /** * @param {boolean} use_hashes * @param {import('types').CspDirectives} directives * @param {string} nonce */ constructor(use_hashes, directives, nonce) { this.#use_hashes = use_hashes; this.#directives = directives; const d = this.#directives; this.#script_src = /* @__PURE__ */ new Set(); this.#script_src_elem = /* @__PURE__ */ new Set(); this.#style_src = /* @__PURE__ */ new Set(); this.#style_src_attr = /* @__PURE__ */ new Set(); this.#style_src_elem = /* @__PURE__ */ new Set(); const effective_script_src = d["script-src"] || d["default-src"]; const script_src_elem = d["script-src-elem"]; const effective_style_src = d["style-src"] || d["default-src"]; const style_src_attr = d["style-src-attr"]; const style_src_elem = d["style-src-elem"]; const style_needs_csp = (directive) => !!directive && !directive.some((value) => value === "unsafe-inline"); const script_needs_csp = (directive) => !!directive && (!directive.some((value) => value === "unsafe-inline") || directive.some((value) => value === "strict-dynamic")); this.#script_src_needs_csp = script_needs_csp(effective_script_src); this.#script_src_elem_needs_csp = script_needs_csp(script_src_elem); this.#style_src_needs_csp = style_needs_csp(effective_style_src); this.#style_src_attr_needs_csp = style_needs_csp(style_src_attr); this.#style_src_elem_needs_csp = style_needs_csp(style_src_elem); this.#script_needs_csp = this.#script_src_needs_csp || this.#script_src_elem_needs_csp; this.#style_needs_csp = this.#style_src_needs_csp || this.#style_src_attr_needs_csp || this.#style_src_elem_needs_csp; this.script_needs_nonce = this.#script_needs_csp && !this.#use_hashes; this.style_needs_nonce = this.#style_needs_csp && !this.#use_hashes; this.script_needs_hash = this.#script_needs_csp && this.#use_hashes; this.#nonce = nonce; } /** @param {string} content */ add_script(content) { if (!this.#script_needs_csp) return; const source = this.#use_hashes ? `sha256-${sha256(content)}` : `nonce-${this.#nonce}`; if (this.#script_src_needs_csp) { this.#script_src.add(source); } if (this.#script_src_elem_needs_csp) { this.#script_src_elem.add(source); } } /** @param {`sha256-${string}`[]} hashes */ add_script_hashes(hashes) { for (const hash2 of hashes) { if (this.#script_src_needs_csp) { this.#script_src.add(hash2); } if (this.#script_src_elem_needs_csp) { this.#script_src_elem.add(hash2); } } } /** @param {string} content */ add_style(content) { if (!this.#style_needs_csp) return; const source = this.#use_hashes ? `sha256-${sha256(content)}` : `nonce-${this.#nonce}`; if (this.#style_src_needs_csp) { this.#style_src.add(source); } if (this.#style_src_attr_needs_csp) { this.#style_src_attr.add(source); } if (this.#style_src_elem_needs_csp) { const sha256_empty_comment_hash = "sha256-9OlNO0DNEeaVzHL4RZwCLsBHA8WBQ8toBp/4F5XV2nc="; const d = this.#directives; if (d["style-src-elem"] && !d["style-src-elem"].includes(sha256_empty_comment_hash) && !this.#style_src_elem.has(sha256_empty_comment_hash)) { this.#style_src_elem.add(sha256_empty_comment_hash); } if (source !== sha256_empty_comment_hash) { this.#style_src_elem.add(source); } } } /** * @param {boolean} [is_meta] */ get_header(is_meta = false) { const header = []; const directives = { ...this.#directives }; if (this.#style_src.size > 0) { directives["style-src"] = [ ...directives["style-src"] || directives["default-src"] || [], ...this.#style_src ]; } if (this.#style_src_attr.size > 0) { directives["style-src-attr"] = [ ...directives["style-src-attr"] || [], ...this.#style_src_attr ]; } if (this.#style_src_elem.size > 0) { directives["style-src-elem"] = [ ...directives["style-src-elem"] || [], ...this.#style_src_elem ]; } if (this.#script_src.size > 0) { directives["script-src"] = [ ...directives["script-src"] || directives["default-src"] || [], ...this.#script_src ]; } if (this.#script_src_elem.size > 0) { directives["script-src-elem"] = [ ...directives["script-src-elem"] || [], ...this.#script_src_elem ]; } for (const key2 in directives) { if (is_meta && (key2 === "frame-ancestors" || key2 === "report-uri" || key2 === "sandbox")) { continue; } const value = ( /** @type {string[] | true} */ directives[key2] ); if (!value) continue; const directive = [key2]; if (Array.isArray(value)) { value.forEach((value2) => { if (quoted.has(value2) || crypto_pattern.test(value2)) { directive.push(`'${value2}'`); } else { directive.push(value2); } }); } header.push(directive.join(" ")); } return header.join("; "); } } class CspProvider extends BaseProvider { get_meta() { const content = this.get_header(true); if (!content) { return; } return `<meta http-equiv="content-security-policy" content="${escape_html(content, true)}">`; } } class CspReportOnlyProvider extends BaseProvider { /** * @param {boolean} use_hashes * @param {import('types').CspDirectives} directives * @param {string} nonce */ constructor(use_hashes, directives, nonce) { super(use_hashes, directives, nonce); if (Object.values(directives).filter((v) => !!v).length > 0) { const has_report_to = directives["report-to"]?.length ?? 0 > 0; const has_report_uri = directives["report-uri"]?.length ?? 0 > 0; if (!has_report_to && !has_report_uri) { throw Error( "`content-security-policy-report-only` must be specified with either the `report-to` or `report-uri` directives, or both" ); } } } } class Csp { /** @readonly */ nonce = generate_nonce(); /** @type {CspProvider} */ csp_provider; /** @type {CspReportOnlyProvider} */ report_only_provider; /** * @param {import('./types.js').CspConfig} config * @param {import('./types.js').CspOpts} opts */ constructor({ mode, directives, reportOnly }, { prerender }) { const use_hashes = mode === "hash" || mode === "auto" && prerender; this.csp_provider = new CspProvider(use_hashes, directives, this.nonce); this.report_only_provider = new CspReportOnlyProvider(use_hashes, reportOnly, this.nonce); } get script_needs_hash() { return this.csp_provider.script_needs_hash || this.report_only_provider.script_needs_hash; } get script_needs_nonce() { return this.csp_provider.script_needs_nonce || this.report_only_provider.script_needs_nonce; } get style_needs_nonce() { return this.csp_provider.style_needs_nonce || this.report_only_provider.style_needs_nonce; } /** @param {string} content */ add_script(content) { this.csp_provider.add_script(content); this.report_only_provider.add_script(content); } /** @param {`sha256-${string}`[]} hashes */ add_script_hashes(hashes) { this.csp_provider.add_script_hashes(hashes); this.report_only_provider.add_script_hashes(hashes); } /** @param {string} content */ add_style(content) { this.csp_provider.add_style(content); this.report_only_provider.add_style(content); } } function generate_route_object(route, url, manifest) { const { errors, layouts, leaf } = route; const nodes = [...errors, ...layouts.map((l) => l?.[1]), leaf[1]].filter((n) => typeof n === "number").map((n) => `'${n}': () => ${create_client_import(manifest._.client.nodes?.[n], url)}`).join(",\n "); return [ `{ id: ${s(route.id)}`, `errors: ${s(route.errors)}`, `layouts: ${s(route.layouts)}`, `leaf: ${s(route.leaf)}`, `nodes: { ${nodes} } }` ].join(",\n "); } function create_client_import(import_path, url) { if (!import_path) return "Promise.resolve({})"; if (import_path[0] === "/") { return `import('${import_path}')`; } if (assets !== "") { return `import('${assets}/${import_path}')`; } let path = get_relative_path(url.pathname, `${base}/${import_path}`); if (path[0] !== ".") path = `./${path}`; return `import('${path}')`; } async function resolve_route(resolved_path, url, manifest) { if (!manifest._.client.routes) { return text("Server-side route resolution disabled", { status: 400 }); } const matchers = await manifest._.matchers(); const result = find_route(resolved_path, manifest._.client.routes, matchers); return create_server_routing_response(result?.route ?? null, result?.params ?? {}, url, manifest).response; } function create_server_routing_response(route, params, url, manifest) { const headers2 = new Headers({ "content-type": "application/javascript; charset=utf-8" }); if (route) { const csr_route = generate_route_object(route, url, manifest); const body2 = `${create_css_import(route, url, manifest)} export const route = ${csr_route}; export const params = ${JSON.stringify(params)};`; return { response: text(body2, { headers: headers2 }), body: body2 }; } else { return { response: text("", { headers: headers2 }), body: "" }; } } function create_css_import(route, url, manifest) { const { errors, layouts, leaf } = route; let css = ""; for (const node of [...errors, ...layouts.map((l) => l?.[1]), leaf[1]]) { if (typeof node !== "number") continue; const node_css = manifest._.client.css?.[node]; for (const css_path of node_css ?? []) { css += `'${assets || base}/${css_path}',`; } } if (!css) return ""; return