Files
base/build/server/index.js
T
eewing c0fae761da
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m24s
PWA
2026-02-19 07:41:49 -06:00

5646 lines
170 KiB
JavaScript

import { w as with_request_store, t as text_decoder, b as base64_decode, r as root, d as decode_pathname, a as browser, n as normalize_path, c as disable_search, e as decode_params, v as validate_layout_server_exports, f as validate_layout_exports, g as validate_page_server_exports, h as validate_page_exports, i as text_encoder, j as resolve, m as make_trackable, k as get_relative_path, l as base64_encode } from './chunks/root-ByBW8a1L.js';
import { H as HttpError, j as json, t as text, S as SvelteKitError, R as Redirect, e as error, A as ActionFailure } from './chunks/index-wpIsICWW.js';
import { D as DevalueError, i as is_primitive, g as get_type, a as is_plain_object, e as enumerable_symbols, s as stringify_key, b as stringify_string, v as valid_array_indices, u as uneval } from './chunks/index2-CkPUJ4Ro.js';
import { w as writable, r as readable } from './chunks/index-DAWk3dQT.js';
import 'clsx';
/**
* @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 base = "";
let assets = base;
const app_dir = "_app";
const relative = true;
const initial = { base, assets };
function override(paths) {
base = paths.base;
assets = paths.assets;
}
function reset() {
base = initial.base;
assets = initial.assets;
}
/**
* Base64 Encodes an arraybuffer
* @param {ArrayBuffer} arraybuffer
* @returns {string}
*/
function encode64(arraybuffer) {
const dv = new DataView(arraybuffer);
let binaryString = "";
for (let i = 0; i < arraybuffer.byteLength; i++) {
binaryString += String.fromCharCode(dv.getUint8(i));
}
return binaryToAscii(binaryString);
}
/**
* Decodes a base64 string into an arraybuffer
* @param {string} string
* @returns {ArrayBuffer}
*/
function decode64(string) {
const binaryString = asciiToBinary(string);
const arraybuffer = new ArrayBuffer(binaryString.length);
const dv = new DataView(arraybuffer);
for (let i = 0; i < arraybuffer.byteLength; i++) {
dv.setUint8(i, binaryString.charCodeAt(i));
}
return arraybuffer;
}
const KEY_STRING =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* Substitute for atob since it's deprecated in node.
* Does not do any input validation.
*
* @see https://github.com/jsdom/abab/blob/master/lib/atob.js
*
* @param {string} data
* @returns {string}
*/
function asciiToBinary(data) {
if (data.length % 4 === 0) {
data = data.replace(/==?$/, "");
}
let output = "";
let buffer = 0;
let accumulatedBits = 0;
for (let i = 0; i < data.length; i++) {
buffer <<= 6;
buffer |= KEY_STRING.indexOf(data[i]);
accumulatedBits += 6;
if (accumulatedBits === 24) {
output += String.fromCharCode((buffer & 0xff0000) >> 16);
output += String.fromCharCode((buffer & 0xff00) >> 8);
output += String.fromCharCode(buffer & 0xff);
buffer = accumulatedBits = 0;
}
}
if (accumulatedBits === 12) {
buffer >>= 4;
output += String.fromCharCode(buffer);
} else if (accumulatedBits === 18) {
buffer >>= 2;
output += String.fromCharCode((buffer & 0xff00) >> 8);
output += String.fromCharCode(buffer & 0xff);
}
return output;
}
/**
* Substitute for btoa since it's deprecated in node.
* Does not do any input validation.
*
* @see https://github.com/jsdom/abab/blob/master/lib/btoa.js
*
* @param {string} str
* @returns {string}
*/
function binaryToAscii(str) {
let out = "";
for (let i = 0; i < str.length; i += 3) {
/** @type {[number, number, number, number]} */
const groupsOfSix = [undefined, undefined, undefined, undefined];
groupsOfSix[0] = str.charCodeAt(i) >> 2;
groupsOfSix[1] = (str.charCodeAt(i) & 0x03) << 4;
if (str.length > i + 1) {
groupsOfSix[1] |= str.charCodeAt(i + 1) >> 4;
groupsOfSix[2] = (str.charCodeAt(i + 1) & 0x0f) << 2;
}
if (str.length > i + 2) {
groupsOfSix[2] |= str.charCodeAt(i + 2) >> 6;
groupsOfSix[3] = str.charCodeAt(i + 2) & 0x3f;
}
for (let j = 0; j < groupsOfSix.length; j++) {
if (typeof groupsOfSix[j] === "undefined") {
out += "=";
} else {
out += KEY_STRING[groupsOfSix[j]];
}
}
}
return out;
}
const UNDEFINED = -1;
const HOLE = -2;
const NAN = -3;
const POSITIVE_INFINITY = -4;
const NEGATIVE_INFINITY = -5;
const NEGATIVE_ZERO = -6;
const SPARSE = -7;
/**
* Revive a value serialized with `devalue.stringify`
* @param {string} serialized
* @param {Record<string, (value: any) => any>} [revivers]
*/
function parse(serialized, revivers) {
return unflatten(JSON.parse(serialized), revivers);
}
/**
* Revive a value flattened with `devalue.stringify`
* @param {number | any[]} parsed
* @param {Record<string, (value: any) => any>} [revivers]
*/
function unflatten(parsed, revivers) {
if (typeof parsed === 'number') return hydrate(parsed, true);
if (!Array.isArray(parsed) || parsed.length === 0) {
throw new Error('Invalid input');
}
const values = /** @type {any[]} */ (parsed);
const hydrated = Array(values.length);
/**
* A set of values currently being hydrated with custom revivers,
* used to detect invalid cyclical dependencies
* @type {Set<number> | null}
*/
let hydrating = null;
/**
* @param {number} index
* @returns {any}
*/
function hydrate(index, standalone = false) {
if (index === UNDEFINED) return undefined;
if (index === NAN) return NaN;
if (index === POSITIVE_INFINITY) return Infinity;
if (index === NEGATIVE_INFINITY) return -Infinity;
if (index === NEGATIVE_ZERO) return -0;
if (standalone || typeof index !== 'number') {
throw new Error(`Invalid input`);
}
if (index in hydrated) return hydrated[index];
const value = values[index];
if (!value || typeof value !== 'object') {
hydrated[index] = value;
} else if (Array.isArray(value)) {
if (typeof value[0] === 'string') {
const type = value[0];
const reviver =
revivers && Object.hasOwn(revivers, type)
? revivers[type]
: undefined;
if (reviver) {
let i = value[1];
if (typeof i !== 'number') {
// if it's not a number, it was serialized by a builtin reviver
// so we need to munge it into the format expected by a custom reviver
i = values.push(value[1]) - 1;
}
hydrating ??= new Set();
if (hydrating.has(i)) {
throw new Error('Invalid circular reference');
}
hydrating.add(i);
hydrated[index] = reviver(hydrate(i));
hydrating.delete(i);
return hydrated[index];
}
switch (type) {
case 'Date':
hydrated[index] = new Date(value[1]);
break;
case 'Set':
const set = new Set();
hydrated[index] = set;
for (let i = 1; i < value.length; i += 1) {
set.add(hydrate(value[i]));
}
break;
case 'Map':
const map = new Map();
hydrated[index] = map;
for (let i = 1; i < value.length; i += 2) {
map.set(hydrate(value[i]), hydrate(value[i + 1]));
}
break;
case 'RegExp':
hydrated[index] = new RegExp(value[1], value[2]);
break;
case 'Object':
hydrated[index] = Object(value[1]);
break;
case 'BigInt':
hydrated[index] = BigInt(value[1]);
break;
case 'null':
const obj = Object.create(null);
hydrated[index] = obj;
for (let i = 1; i < value.length; i += 2) {
obj[value[i]] = hydrate(value[i + 1]);
}
break;
case 'Int8Array':
case 'Uint8Array':
case 'Uint8ClampedArray':
case 'Int16Array':
case 'Uint16Array':
case 'Int32Array':
case 'Uint32Array':
case 'Float32Array':
case 'Float64Array':
case 'BigInt64Array':
case 'BigUint64Array': {
if (values[value[1]][0] !== 'ArrayBuffer') {
// without this, if we receive malformed input we could
// end up trying to hydrate in a circle or allocate
// huge amounts of memory when we call `new TypedArrayConstructor(buffer)`
throw new Error('Invalid data');
}
const TypedArrayConstructor = globalThis[type];
const buffer = hydrate(value[1]);
const typedArray = new TypedArrayConstructor(buffer);
hydrated[index] =
value[2] !== undefined
? typedArray.subarray(value[2], value[3])
: typedArray;
break;
}
case 'ArrayBuffer': {
const base64 = value[1];
if (typeof base64 !== 'string') {
throw new Error('Invalid ArrayBuffer encoding');
}
const arraybuffer = decode64(base64);
hydrated[index] = arraybuffer;
break;
}
case 'Temporal.Duration':
case 'Temporal.Instant':
case 'Temporal.PlainDate':
case 'Temporal.PlainTime':
case 'Temporal.PlainDateTime':
case 'Temporal.PlainMonthDay':
case 'Temporal.PlainYearMonth':
case 'Temporal.ZonedDateTime': {
const temporalName = type.slice(9);
// @ts-expect-error TS doesn't know about Temporal yet
hydrated[index] = Temporal[temporalName].from(value[1]);
break;
}
case 'URL': {
const url = new URL(value[1]);
hydrated[index] = url;
break;
}
case 'URLSearchParams': {
const url = new URLSearchParams(value[1]);
hydrated[index] = url;
break;
}
default:
throw new Error(`Unknown type ${type}`);
}
} else if (value[0] === SPARSE) {
// Sparse array encoding: [SPARSE, length, idx, val, idx, val, ...]
const len = value[1];
const array = new Array(len);
hydrated[index] = array;
for (let i = 2; i < value.length; i += 2) {
const idx = value[i];
array[idx] = hydrate(value[i + 1]);
}
} else {
const array = new Array(value.length);
hydrated[index] = array;
for (let i = 0; i < value.length; i += 1) {
const n = value[i];
if (n === HOLE) continue;
array[i] = hydrate(n);
}
}
} else {
/** @type {Record<string, any>} */
const object = {};
hydrated[index] = object;
for (const key of Object.keys(value)) {
if (key === '__proto__') {
throw new Error('Cannot parse an object with a `__proto__` property');
}
const n = value[key];
object[key] = hydrate(n);
}
}
return hydrated[index];
}
return hydrate(0);
}
/**
* Turn a value into a JSON string that can be parsed with `devalue.parse`
* @param {any} value
* @param {Record<string, (value: any) => any>} [reducers]
*/
function stringify$1(value, reducers) {
/** @type {any[]} */
const stringified = [];
/** @type {Map<any, number>} */
const indexes = new Map();
/** @type {Array<{ key: string, fn: (value: any) => any }>} */
const custom = [];
if (reducers) {
for (const key of Object.getOwnPropertyNames(reducers)) {
custom.push({ key, fn: reducers[key] });
}
}
/** @type {string[]} */
const keys = [];
let p = 0;
/** @param {any} thing */
function flatten(thing) {
if (thing === undefined) return UNDEFINED;
if (Number.isNaN(thing)) return NAN;
if (thing === Infinity) return POSITIVE_INFINITY;
if (thing === -Infinity) return NEGATIVE_INFINITY;
if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO;
if (indexes.has(thing)) return indexes.get(thing);
const index = p++;
indexes.set(thing, index);
for (const { key, fn } of custom) {
const value = fn(thing);
if (value) {
stringified[index] = `["${key}",${flatten(value)}]`;
return index;
}
}
if (typeof thing === 'function') {
throw new DevalueError(`Cannot stringify a function`, keys, thing, value);
}
let str = '';
if (is_primitive(thing)) {
str = stringify_primitive(thing);
} else {
const type = get_type(thing);
switch (type) {
case 'Number':
case 'String':
case 'Boolean':
str = `["Object",${stringify_primitive(thing)}]`;
break;
case 'BigInt':
str = `["BigInt",${thing}]`;
break;
case 'Date':
const valid = !isNaN(thing.getDate());
str = `["Date","${valid ? thing.toISOString() : ''}"]`;
break;
case 'URL':
str = `["URL",${stringify_string(thing.toString())}]`;
break;
case 'URLSearchParams':
str = `["URLSearchParams",${stringify_string(thing.toString())}]`;
break;
case 'RegExp':
const { source, flags } = thing;
str = flags
? `["RegExp",${stringify_string(source)},"${flags}"]`
: `["RegExp",${stringify_string(source)}]`;
break;
case 'Array': {
// For dense arrays (no holes), we iterate normally.
// When we encounter the first hole, we call Object.keys
// to determine the sparseness, then decide between:
// - HOLE encoding: [-2, val, -2, ...] (default)
// - Sparse encoding: [-7, length, idx, val, ...] (for very sparse arrays)
// Only the sparse path avoids iterating every slot, which
// is what protects against the DoS of e.g. `arr[1000000] = 1`.
let mostly_dense = false;
str = '[';
for (let i = 0; i < thing.length; i += 1) {
if (i > 0) str += ',';
if (Object.hasOwn(thing, i)) {
keys.push(`[${i}]`);
str += flatten(thing[i]);
keys.pop();
} else if (mostly_dense) {
// Use dense encoding. The heuristic guarantees the
// array is only mildly sparse, so iterating over every
// slot is fine.
str += HOLE;
} else {
// Decide between HOLE encoding and sparse encoding.
//
// HOLE encoding: each hole is serialized as the HOLE
// sentinel (-2). For example, [, "a", ,] becomes
// [-2, 0, -2]. Each hole costs 3 chars ("-2" + comma).
//
// Sparse encoding: lists only populated indices.
// For example, [, "a", ,] becomes [-7, 3, 1, 0] — the
// -7 sentinel, the array length (3), then index-value
// pairs. This avoids paying per-hole, but each element
// costs extra chars to write its index.
//
// The values are the same size either way, so the
// choice comes down to structural overhead:
//
// HOLE overhead:
// 3 chars per hole ("-2" + comma)
// = (L - P) * 3
//
// Sparse overhead:
// "-7," — 3 chars (sparse sentinel + comma)
// + length + "," — (d + 1) chars (array length + comma)
// + per element: index + "," — (d + 1) chars
// = (4 + d) + P * (d + 1)
//
// where L is the array length, P is the number of
// populated elements, and d is the number of digits
// in L (an upper bound on the digits in any index).
//
// Sparse encoding is cheaper when:
// (4 + d) + P * (d + 1) < (L - P) * 3
const populated_keys = valid_array_indices(/** @type {any[]} */ (thing));
const population = populated_keys.length;
const d = String(thing.length).length;
const hole_cost = (thing.length - population) * 3;
const sparse_cost = 4 + d + population * (d + 1);
if (hole_cost > sparse_cost) {
str = '[' + SPARSE + ',' + thing.length;
for (let j = 0; j < populated_keys.length; j++) {
const key = populated_keys[j];
keys.push(`[${key}]`);
str += ',' + key + ',' + flatten(thing[key]);
keys.pop();
}
break;
} else {
mostly_dense = true;
str += HOLE;
}
}
}
str += ']';
break;
}
case 'Set':
str = '["Set"';
for (const value of thing) {
str += `,${flatten(value)}`;
}
str += ']';
break;
case 'Map':
str = '["Map"';
for (const [key, value] of thing) {
keys.push(
`.get(${is_primitive(key) ? stringify_primitive(key) : '...'})`
);
str += `,${flatten(key)},${flatten(value)}`;
keys.pop();
}
str += ']';
break;
case 'Int8Array':
case 'Uint8Array':
case 'Uint8ClampedArray':
case 'Int16Array':
case 'Uint16Array':
case 'Int32Array':
case 'Uint32Array':
case 'Float32Array':
case 'Float64Array':
case 'BigInt64Array':
case 'BigUint64Array': {
/** @type {import("./types.js").TypedArray} */
const typedArray = thing;
str = '["' + type + '",' + flatten(typedArray.buffer);
const a = thing.byteOffset;
const b = a + thing.byteLength;
// handle subarrays
if (a > 0 || b !== typedArray.buffer.byteLength) {
const m = +/(\d+)/.exec(type)[1] / 8;
str += `,${a / m},${b / m}`;
}
str += ']';
break;
}
case 'ArrayBuffer': {
/** @type {ArrayBuffer} */
const arraybuffer = thing;
const base64 = encode64(arraybuffer);
str = `["ArrayBuffer","${base64}"]`;
break;
}
case 'Temporal.Duration':
case 'Temporal.Instant':
case 'Temporal.PlainDate':
case 'Temporal.PlainTime':
case 'Temporal.PlainDateTime':
case 'Temporal.PlainMonthDay':
case 'Temporal.PlainYearMonth':
case 'Temporal.ZonedDateTime':
str = `["${type}",${stringify_string(thing.toString())}]`;
break;
default:
if (!is_plain_object(thing)) {
throw new DevalueError(
`Cannot stringify arbitrary non-POJOs`,
keys,
thing,
value
);
}
if (enumerable_symbols(thing).length > 0) {
throw new DevalueError(
`Cannot stringify POJOs with symbolic keys`,
keys,
thing,
value
);
}
if (Object.getPrototypeOf(thing) === null) {
str = '["null"';
for (const key of Object.keys(thing)) {
if (key === '__proto__') {
throw new DevalueError(
`Cannot stringify objects with __proto__ keys`,
keys,
thing,
value
);
}
keys.push(stringify_key(key));
str += `,${stringify_string(key)},${flatten(thing[key])}`;
keys.pop();
}
str += ']';
} else {
str = '{';
let started = false;
for (const key of Object.keys(thing)) {
if (key === '__proto__') {
throw new DevalueError(
`Cannot stringify objects with __proto__ keys`,
keys,
thing,
value
);
}
if (started) str += ',';
started = true;
keys.push(stringify_key(key));
str += `${stringify_string(key)}:${flatten(thing[key])}`;
keys.pop();
}
str += '}';
}
}
}
stringified[index] = str;
return index;
}
const index = flatten(value);
// special case — value is represented as a negative index
if (index < 0) return `${index}`;
return `[${stringified.join(',')}]`;
}
/**
* @param {any} thing
* @returns {string}
*/
function stringify_primitive(thing) {
const type = typeof thing;
if (type === 'string') return stringify_string(thing);
if (thing instanceof String) return stringify_string(thing.toString());
if (thing === void 0) return UNDEFINED.toString();
if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO.toString();
if (type === 'bigint') return `["BigInt","${thing}"]`;
return String(thing);
}
const SVELTE_KIT_ASSETS = "/_svelte_kit_assets";
const ENDPOINT_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
const PAGE_METHODS = ["GET", "POST", "HEAD"];
function set_nested_value(object, path_string, value) {
if (path_string.startsWith("n:")) {
path_string = path_string.slice(2);
value = value === "" ? void 0 : parseFloat(value);
} else if (path_string.startsWith("b:")) {
path_string = path_string.slice(2);
value = value === "on";
}
deep_set(object, split_path(path_string), value);
}
function convert_formdata(data) {
const result = {};
for (let key of data.keys()) {
const is_array = key.endsWith("[]");
let values = data.getAll(key);
if (is_array) key = key.slice(0, -2);
if (values.length > 1 && !is_array) {
throw new Error(`Form cannot contain duplicated keys — "${key}" has ${values.length} values`);
}
values = values.filter(
(entry) => typeof entry === "string" || entry.name !== "" || entry.size > 0
);
if (key.startsWith("n:")) {
key = key.slice(2);
values = values.map((v) => v === "" ? void 0 : parseFloat(
/** @type {string} */
v
));
} else if (key.startsWith("b:")) {
key = key.slice(2);
values = values.map((v) => v === "on");
}
set_nested_value(result, key, is_array ? values : values[0]);
}
return result;
}
const BINARY_FORM_CONTENT_TYPE = "application/x-sveltekit-formdata";
const BINARY_FORM_VERSION = 0;
const HEADER_BYTES = 1 + 4 + 2;
async function deserialize_binary_form(request) {
if (request.headers.get("content-type") !== BINARY_FORM_CONTENT_TYPE) {
const form_data = await request.formData();
return { data: convert_formdata(form_data), meta: {}, form_data };
}
if (!request.body) {
throw deserialize_error("no body");
}
const content_length = parseInt(request.headers.get("content-length") ?? "");
if (Number.isNaN(content_length)) {
throw deserialize_error("invalid Content-Length header");
}
const reader = request.body.getReader();
const chunks = [];
function get_chunk(index) {
if (index in chunks) return chunks[index];
let i = chunks.length;
while (i <= index) {
chunks[i] = reader.read().then((chunk) => chunk.value);
i++;
}
return chunks[index];
}
async function get_buffer(offset, length) {
let start_chunk;
let chunk_start = 0;
let chunk_index;
for (chunk_index = 0; ; chunk_index++) {
const chunk = await get_chunk(chunk_index);
if (!chunk) return null;
const chunk_end = chunk_start + chunk.byteLength;
if (offset >= chunk_start && offset < chunk_end) {
start_chunk = chunk;
break;
}
chunk_start = chunk_end;
}
if (offset + length <= chunk_start + start_chunk.byteLength) {
return start_chunk.subarray(offset - chunk_start, offset + length - chunk_start);
}
const chunks2 = [start_chunk.subarray(offset - chunk_start)];
let cursor = start_chunk.byteLength - offset + chunk_start;
while (cursor < length) {
chunk_index++;
let chunk = await get_chunk(chunk_index);
if (!chunk) return null;
if (chunk.byteLength > length - cursor) {
chunk = chunk.subarray(0, length - cursor);
}
chunks2.push(chunk);
cursor += chunk.byteLength;
}
const buffer = new Uint8Array(length);
cursor = 0;
for (const chunk of chunks2) {
buffer.set(chunk, cursor);
cursor += chunk.byteLength;
}
return buffer;
}
const header = await get_buffer(0, HEADER_BYTES);
if (!header) throw deserialize_error("too short");
if (header[0] !== BINARY_FORM_VERSION) {
throw deserialize_error(`got version ${header[0]}, expected version ${BINARY_FORM_VERSION}`);
}
const header_view = new DataView(header.buffer, header.byteOffset, header.byteLength);
const data_length = header_view.getUint32(1, true);
if (HEADER_BYTES + data_length > content_length) {
throw deserialize_error("data overflow");
}
const file_offsets_length = header_view.getUint16(5, true);
if (HEADER_BYTES + data_length + file_offsets_length > content_length) {
throw deserialize_error("file offset table overflow");
}
const data_buffer = await get_buffer(HEADER_BYTES, data_length);
if (!data_buffer) throw deserialize_error("data too short");
let file_offsets;
let files_start_offset;
if (file_offsets_length > 0) {
const file_offsets_buffer = await get_buffer(HEADER_BYTES + data_length, file_offsets_length);
if (!file_offsets_buffer) throw deserialize_error("file offset table too short");
const parsed_offsets = JSON.parse(text_decoder.decode(file_offsets_buffer));
if (!Array.isArray(parsed_offsets) || parsed_offsets.some((n) => typeof n !== "number" || !Number.isInteger(n) || n < 0)) {
throw deserialize_error("invalid file offset table");
}
file_offsets = /** @type {Array<number>} */
parsed_offsets;
files_start_offset = HEADER_BYTES + data_length + file_offsets_length;
}
const [data, meta] = parse(text_decoder.decode(data_buffer), {
File: ([name, type, size, last_modified, index]) => {
if (typeof name !== "string" || typeof type !== "string" || typeof size !== "number" || typeof last_modified !== "number" || typeof index !== "number") {
throw deserialize_error("invalid file metadata");
}
if (files_start_offset + file_offsets[index] + size > content_length) {
throw deserialize_error("file data overflow");
}
return new Proxy(
new LazyFile(
name,
type,
size,
last_modified,
get_chunk,
files_start_offset + file_offsets[index]
),
{
getPrototypeOf() {
return File.prototype;
}
}
);
}
});
void (async () => {
let has_more = true;
while (has_more) {
const chunk = await get_chunk(chunks.length);
has_more = !!chunk;
}
})();
return { data, meta, form_data: null };
}
function deserialize_error(message) {
return new SvelteKitError(400, "Bad Request", `Could not deserialize binary form: ${message}`);
}
class LazyFile {
/** @type {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} */
#get_chunk;
/** @type {number} */
#offset;
/**
* @param {string} name
* @param {string} type
* @param {number} size
* @param {number} last_modified
* @param {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} get_chunk
* @param {number} offset
*/
constructor(name, type, size, last_modified, get_chunk, offset) {
this.name = name;
this.type = type;
this.size = size;
this.lastModified = last_modified;
this.webkitRelativePath = "";
this.#get_chunk = get_chunk;
this.#offset = offset;
this.arrayBuffer = this.arrayBuffer.bind(this);
this.bytes = this.bytes.bind(this);
this.slice = this.slice.bind(this);
this.stream = this.stream.bind(this);
this.text = this.text.bind(this);
}
/** @type {ArrayBuffer | undefined} */
#buffer;
async arrayBuffer() {
this.#buffer ??= await new Response(this.stream()).arrayBuffer();
return this.#buffer;
}
async bytes() {
return new Uint8Array(await this.arrayBuffer());
}
/**
* @param {number=} start
* @param {number=} end
* @param {string=} contentType
*/
slice(start = 0, end = this.size, contentType = this.type) {
if (start < 0) {
start = Math.max(this.size + start, 0);
} else {
start = Math.min(start, this.size);
}
if (end < 0) {
end = Math.max(this.size + end, 0);
} else {
end = Math.min(end, this.size);
}
const size = Math.max(end - start, 0);
const file = new LazyFile(
this.name,
contentType,
size,
this.lastModified,
this.#get_chunk,
this.#offset + start
);
return file;
}
stream() {
let cursor = 0;
let chunk_index = 0;
return new ReadableStream({
start: async (controller) => {
let chunk_start = 0;
let start_chunk = null;
for (chunk_index = 0; ; chunk_index++) {
const chunk = await this.#get_chunk(chunk_index);
if (!chunk) return null;
const chunk_end = chunk_start + chunk.byteLength;
if (this.#offset >= chunk_start && this.#offset < chunk_end) {
start_chunk = chunk;
break;
}
chunk_start = chunk_end;
}
if (this.#offset + this.size <= chunk_start + start_chunk.byteLength) {
controller.enqueue(
start_chunk.subarray(this.#offset - chunk_start, this.#offset + this.size - chunk_start)
);
controller.close();
} else {
controller.enqueue(start_chunk.subarray(this.#offset - chunk_start));
cursor = start_chunk.byteLength - this.#offset + chunk_start;
}
},
pull: async (controller) => {
chunk_index++;
let chunk = await this.#get_chunk(chunk_index);
if (!chunk) {
controller.error("incomplete file data");
controller.close();
return;
}
if (chunk.byteLength > this.size - cursor) {
chunk = chunk.subarray(0, this.size - cursor);
}
controller.enqueue(chunk);
cursor += chunk.byteLength;
if (cursor >= this.size) {
controller.close();
}
}
});
}
async text() {
return text_decoder.decode(await this.arrayBuffer());
}
}
const path_regex = /^[a-zA-Z_$]\w*(\.[a-zA-Z_$]\w*|\[\d+\])*$/;
function split_path(path) {
if (!path_regex.test(path)) {
throw new Error(`Invalid path ${path}`);
}
return path.split(/\.|\[|\]/).filter(Boolean);
}
function check_prototype_pollution(key) {
if (key === "__proto__" || key === "constructor" || key === "prototype") {
throw new Error(
`Invalid key "${key}"`
);
}
}
function deep_set(object, keys, value) {
let current = object;
for (let i = 0; i < keys.length - 1; i += 1) {
const key = keys[i];
check_prototype_pollution(key);
const is_array = /^\d+$/.test(keys[i + 1]);
const exists = Object.hasOwn(current, key);
const inner = current[key];
if (exists && is_array !== Array.isArray(inner)) {
throw new Error(`Invalid array key ${keys[i + 1]}`);
}
if (!exists) {
current[key] = is_array ? [] : {};
}
current = current[key];
}
const final_key = keys[keys.length - 1];
check_prototype_pollution(final_key);
current[final_key] = value;
}
function negotiate(accept, types) {
const parts = [];
accept.split(",").forEach((str, i) => {
const match = /([^/ \t]+)\/([^; \t]+)[ \t]*(?:;[ \t]*q=([0-9.]+))?/.exec(str);
if (match) {
const [, type, subtype, q = "1"] = match;
parts.push({ type, subtype, q: +q, i });
}
});
parts.sort((a, b) => {
if (a.q !== b.q) {
return b.q - a.q;
}
if (a.subtype === "*" !== (b.subtype === "*")) {
return a.subtype === "*" ? 1 : -1;
}
if (a.type === "*" !== (b.type === "*")) {
return a.type === "*" ? 1 : -1;
}
return a.i - b.i;
});
let accepted;
let min_priority = Infinity;
for (const mimetype of types) {
const [type, subtype] = mimetype.split("/");
const priority = parts.findIndex(
(part) => (part.type === type || part.type === "*") && (part.subtype === subtype || part.subtype === "*")
);
if (priority !== -1 && priority < min_priority) {
accepted = mimetype;
min_priority = priority;
}
}
return accepted;
}
function is_content_type(request, ...types) {
const type = request.headers.get("content-type")?.split(";", 1)[0].trim() ?? "";
return types.includes(type.toLowerCase());
}
function is_form_content_type(request) {
return is_content_type(
request,
"application/x-www-form-urlencoded",
"multipart/form-data",
"text/plain",
BINARY_FORM_CONTENT_TYPE
);
}
function coalesce_to_error(err) {
return err instanceof Error || err && /** @type {any} */
err.name && /** @type {any} */
err.message ? (
/** @type {Error} */
err
) : new Error(JSON.stringify(err));
}
function normalize_error(error) {
return (
/** @type {import('../exports/internal/index.js').Redirect | HttpError | SvelteKitError | Error} */
error
);
}
function get_status(error) {
return error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500;
}
function get_message(error) {
return error instanceof SvelteKitError ? error.text : "Internal Error";
}
const escape_html_attr_dict = {
"&": "&amp;",
'"': "&quot;"
// Svelte also escapes < because the escape function could be called inside a `noscript` there
// https://github.com/sveltejs/svelte/security/advisories/GHSA-8266-84wp-wv5c
// However, that doesn't apply in SvelteKit
};
const escape_html_dict = {
"&": "&amp;",
"<": "&lt;"
};
const surrogates = (
// high surrogate without paired low surrogate
"[\\ud800-\\udbff](?![\\udc00-\\udfff])|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\udc00-\\udfff]"
);
const escape_html_attr_regex = new RegExp(
`[${Object.keys(escape_html_attr_dict).join("")}]|` + surrogates,
"g"
);
const escape_html_regex = new RegExp(
`[${Object.keys(escape_html_dict).join("")}]|` + surrogates,
"g"
);
function escape_html(str, is_attr) {
const dict = is_attr ? escape_html_attr_dict : escape_html_dict;
const escaped_str = str.replace(is_attr ? escape_html_attr_regex : escape_html_regex, (match) => {
if (match.length === 2) {
return match;
}
return dict[match] ?? `&#${match.charCodeAt(0)};`;
});
return escaped_str;
}
function method_not_allowed(mod, method) {
return text(`${method} method not allowed`, {
status: 405,
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: allowed_methods(mod).join(", ")
}
});
}
function allowed_methods(mod) {
const allowed = ENDPOINT_METHODS.filter((method) => method in mod);
if ("GET" in mod && !("HEAD" in mod)) {
allowed.push("HEAD");
}
return allowed;
}
function get_global_name(options) {
return `__sveltekit_${options.version_hash}`;
}
function static_error_page(options, status, message) {
let page = options.templates.error({ status, message: escape_html(message) });
return text(page, {
headers: { "content-type": "text/html; charset=utf-8" },
status
});
}
async function handle_fatal_error(event, state, options, error) {
error = error instanceof HttpError ? error : coalesce_to_error(error);
const status = get_status(error);
const body = await handle_error_and_jsonify(event, state, options, error);
const type = negotiate(event.request.headers.get("accept") || "text/html", [
"application/json",
"text/html"
]);
if (event.isDataRequest || type === "application/json") {
return json(body, {
status
});
}
return static_error_page(options, status, body.message);
}
async function handle_error_and_jsonify(event, state, options, error) {
if (error instanceof HttpError) {
return { message: "Unknown Error", ...error.body };
}
const status = get_status(error);
const message = get_message(error);
return await with_request_store(
{ event, state },
() => options.hooks.handleError({ error, event, status, message })
) ?? { message };
}
function redirect_response(status, location) {
const response = new Response(void 0, {
status,
headers: { location }
});
return response;
}
function clarify_devalue_error(event, error) {
if (error.path) {
return `Data returned from \`load\` while rendering ${event.route.id} is not serializable: ${error.message} (${error.path}). If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#Universal-hooks-transport.`;
}
if (error.path === "") {
return `Data returned from \`load\` while rendering ${event.route.id} is not a plain object`;
}
return error.message;
}
function serialize_uses(node) {
const uses = {};
if (node.uses && node.uses.dependencies.size > 0) {
uses.dependencies = Array.from(node.uses.dependencies);
}
if (node.uses && node.uses.search_params.size > 0) {
uses.search_params = Array.from(node.uses.search_params);
}
if (node.uses && node.uses.params.size > 0) {
uses.params = Array.from(node.uses.params);
}
if (node.uses?.parent) uses.parent = 1;
if (node.uses?.route) uses.route = 1;
if (node.uses?.url) uses.url = 1;
return uses;
}
function has_prerendered_path(manifest, pathname) {
return manifest._.prerendered_routes.has(pathname) || pathname.at(-1) === "/" && manifest._.prerendered_routes.has(pathname.slice(0, -1));
}
function format_server_error(status, error, event) {
const formatted_text = `
\x1B[1;31m[${status}] ${event.request.method} ${event.url.pathname}\x1B[0m`;
if (status === 404) {
return formatted_text;
}
return `${formatted_text}
${error.stack}`;
}
function get_node_type(node_id) {
const parts = node_id?.split("/");
const filename = parts?.at(-1);
if (!filename) return "unknown";
const dot_parts = filename.split(".");
return dot_parts.slice(0, -1).join(".");
}
const INVALIDATED_PARAM = "x-sveltekit-invalidated";
const TRAILING_SLASH_PARAM = "x-sveltekit-trailing-slash";
function stringify(data, transport) {
const encoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.encode]));
return stringify$1(data, encoders);
}
function parse_remote_arg(string, transport) {
if (!string) return void 0;
const json_string = text_decoder.decode(
// no need to add back `=` characters, atob can handle it
base64_decode(string.replaceAll("-", "+").replaceAll("_", "/"))
);
const decoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.decode]));
return parse(json_string, decoders);
}
function create_remote_key(id, payload) {
return id + "/" + payload;
}
let public_env = {};
function set_private_env(environment) {
}
function set_public_env(environment) {
public_env = environment;
}
let read_implementation = null;
function set_read_implementation(fn) {
read_implementation = fn;
}
const options = {
app_template_contains_nonce: false,
async: false,
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: null,
templates: {
app: ({ head, body, assets, nonce, env }) => '<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <link rel="icon" href="' + assets + '/favicon.png" />\n <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5, viewport-fit=cover" />\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: "x0o6jd"
};
async function get_hooks() {
let handle;
let handleFetch;
let handleError;
let handleValidationError;
let init;
({ handle, handleFetch, handleError, handleValidationError, init } = await import('./chunks/hooks.server-BgYA4Ixf.js'));
let reroute;
let transport;
return {
handle,
handleFetch,
handleError,
handleValidationError,
init,
reroute,
transport
};
}
var cookie = {};
/*!
* cookie
* Copyright(c) 2012-2014 Roman Shtylman
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
var hasRequiredCookie;
function requireCookie () {
if (hasRequiredCookie) return cookie;
hasRequiredCookie = 1;
/**
* Module exports.
* @public
*/
cookie.parse = parse;
cookie.serialize = serialize;
/**
* Module variables.
* @private
*/
var __toString = Object.prototype.toString;
/**
* RegExp to match field-content in RFC 7230 sec 3.2
*
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
* field-vchar = VCHAR / obs-text
* obs-text = %x80-FF
*/
var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
/**
* Parse a cookie header.
*
* Parse the given cookie header string into an object
* The object has the various cookies as keys(names) => values
*
* @param {string} str
* @param {object} [options]
* @return {object}
* @public
*/
function parse(str, options) {
if (typeof str !== 'string') {
throw new TypeError('argument str must be a string');
}
var obj = {};
var opt = options || {};
var dec = opt.decode || decode;
var index = 0;
while (index < str.length) {
var eqIdx = str.indexOf('=', index);
// no more cookie pairs
if (eqIdx === -1) {
break
}
var endIdx = str.indexOf(';', index);
if (endIdx === -1) {
endIdx = str.length;
} else if (endIdx < eqIdx) {
// backtrack on prior semicolon
index = str.lastIndexOf(';', eqIdx - 1) + 1;
continue
}
var key = str.slice(index, eqIdx).trim();
// only assign once
if (undefined === obj[key]) {
var val = str.slice(eqIdx + 1, endIdx).trim();
// quoted values
if (val.charCodeAt(0) === 0x22) {
val = val.slice(1, -1);
}
obj[key] = tryDecode(val, dec);
}
index = endIdx + 1;
}
return obj;
}
/**
* Serialize data into a cookie header.
*
* Serialize the a name value pair into a cookie string suitable for
* http headers. An optional options object specified cookie parameters.
*
* serialize('foo', 'bar', { httpOnly: true })
* => "foo=bar; httpOnly"
*
* @param {string} name
* @param {string} val
* @param {object} [options]
* @return {string}
* @public
*/
function serialize(name, val, options) {
var opt = options || {};
var enc = opt.encode || encode;
if (typeof enc !== 'function') {
throw new TypeError('option encode is invalid');
}
if (!fieldContentRegExp.test(name)) {
throw new TypeError('argument name is invalid');
}
var value = enc(val);
if (value && !fieldContentRegExp.test(value)) {
throw new TypeError('argument val is invalid');
}
var str = name + '=' + value;
if (null != opt.maxAge) {
var maxAge = opt.maxAge - 0;
if (isNaN(maxAge) || !isFinite(maxAge)) {
throw new TypeError('option maxAge is invalid')
}
str += '; Max-Age=' + Math.floor(maxAge);
}
if (opt.domain) {
if (!fieldContentRegExp.test(opt.domain)) {
throw new TypeError('option domain is invalid');
}
str += '; Domain=' + opt.domain;
}
if (opt.path) {
if (!fieldContentRegExp.test(opt.path)) {
throw new TypeError('option path is invalid');
}
str += '; Path=' + opt.path;
}
if (opt.expires) {
var expires = opt.expires;
if (!isDate(expires) || isNaN(expires.valueOf())) {
throw new TypeError('option expires is invalid');
}
str += '; Expires=' + expires.toUTCString();
}
if (opt.httpOnly) {
str += '; HttpOnly';
}
if (opt.secure) {
str += '; Secure';
}
if (opt.partitioned) {
str += '; Partitioned';
}
if (opt.priority) {
var priority = typeof opt.priority === 'string'
? opt.priority.toLowerCase()
: opt.priority;
switch (priority) {
case 'low':
str += '; Priority=Low';
break
case 'medium':
str += '; Priority=Medium';
break
case 'high':
str += '; Priority=High';
break
default:
throw new TypeError('option priority is invalid')
}
}
if (opt.sameSite) {
var sameSite = typeof opt.sameSite === 'string'
? opt.sameSite.toLowerCase() : opt.sameSite;
switch (sameSite) {
case true:
str += '; SameSite=Strict';
break;
case 'lax':
str += '; SameSite=Lax';
break;
case 'strict':
str += '; SameSite=Strict';
break;
case 'none':
str += '; SameSite=None';
break;
default:
throw new TypeError('option sameSite is invalid');
}
}
return str;
}
/**
* URL-decode string value. Optimized to skip native call when no %.
*
* @param {string} str
* @returns {string}
*/
function decode (str) {
return str.indexOf('%') !== -1
? decodeURIComponent(str)
: str
}
/**
* URL-encode value.
*
* @param {string} val
* @returns {string}
*/
function encode (val) {
return encodeURIComponent(val)
}
/**
* Determine if value is a Date.
*
* @param {*} val
* @private
*/
function isDate (val) {
return __toString.call(val) === '[object Date]' ||
val instanceof Date
}
/**
* Try decoding a string using a decoding function.
*
* @param {string} str
* @param {function} decode
* @private
*/
function tryDecode(str, decode) {
try {
return decode(str);
} catch (e) {
return str;
}
}
return cookie;
}
var cookieExports = requireCookie();
var defaultParseOptions = {
decodeValues: true,
map: false,
silent: false,
split: "auto", // auto = split strings but not arrays
};
function isForbiddenKey(key) {
return typeof key !== "string" || key in {};
}
function createNullObj() {
return Object.create(null);
}
function isNonEmptyString(str) {
return typeof str === "string" && !!str.trim();
}
function parseString(setCookieValue, options) {
var parts = setCookieValue.split(";").filter(isNonEmptyString);
var nameValuePairStr = parts.shift();
var parsed = parseNameValuePair(nameValuePairStr);
var name = parsed.name;
var value = parsed.value;
options = options
? Object.assign({}, defaultParseOptions, options)
: defaultParseOptions;
if (isForbiddenKey(name)) {
return null;
}
try {
value = options.decodeValues ? decodeURIComponent(value) : value; // decode cookie value
} catch (e) {
console.error(
"set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.",
e
);
}
var cookie = createNullObj();
cookie.name = name;
cookie.value = value;
parts.forEach(function (part) {
var sides = part.split("=");
var key = sides.shift().trimLeft().toLowerCase();
if (isForbiddenKey(key)) {
return;
}
var value = sides.join("=");
if (key === "expires") {
cookie.expires = new Date(value);
} else if (key === "max-age") {
var n = parseInt(value, 10);
if (!Number.isNaN(n)) cookie.maxAge = n;
} else if (key === "secure") {
cookie.secure = true;
} else if (key === "httponly") {
cookie.httpOnly = true;
} else if (key === "samesite") {
cookie.sameSite = value;
} else if (key === "partitioned") {
cookie.partitioned = true;
} else if (key) {
cookie[key] = value;
}
});
return cookie;
}
function parseNameValuePair(nameValuePairStr) {
// Parses name-value-pair according to rfc6265bis draft
var name = "";
var value = "";
var nameValueArr = nameValuePairStr.split("=");
if (nameValueArr.length > 1) {
name = nameValueArr.shift();
value = nameValueArr.join("="); // everything after the first =, joined by a "=" if there was more than one part
} else {
value = nameValuePairStr;
}
return { name: name, value: value };
}
function parseSetCookie(input, options) {
options = options
? Object.assign({}, defaultParseOptions, options)
: defaultParseOptions;
if (!input) {
if (!options.map) {
return [];
} else {
return createNullObj();
}
}
if (input.headers) {
if (typeof input.headers.getSetCookie === "function") {
// for fetch responses - they combine headers of the same type in the headers array,
// but getSetCookie returns an uncombined array
input = input.headers.getSetCookie();
} else if (input.headers["set-cookie"]) {
// fast-path for node.js (which automatically normalizes header names to lower-case)
input = input.headers["set-cookie"];
} else {
// slow-path for other environments - see #25
var sch =
input.headers[
Object.keys(input.headers).find(function (key) {
return key.toLowerCase() === "set-cookie";
})
];
// warn if called on a request-like object with a cookie header rather than a set-cookie header - see #34, 36
if (!sch && input.headers.cookie && !options.silent) {
console.warn(
"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning."
);
}
input = sch;
}
}
var split = options.split;
var isArray = Array.isArray(input);
if (split === "auto") {
split = !isArray;
}
if (!isArray) {
input = [input];
}
input = input.filter(isNonEmptyString);
if (split) {
input = input.map(splitCookiesString).flat();
}
if (!options.map) {
return input
.map(function (str) {
return parseString(str, options);
})
.filter(Boolean);
} else {
var cookies = createNullObj();
return input.reduce(function (cookies, str) {
var cookie = parseString(str, options);
if (cookie && !isForbiddenKey(cookie.name)) {
cookies[cookie.name] = cookie;
}
return cookies;
}, cookies);
}
}
/*
Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
that are within a single set-cookie field-value, such as in the Expires portion.
This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
React Native's fetch does this for *every* header, including set-cookie.
Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
*/
function splitCookiesString(cookiesString) {
if (Array.isArray(cookiesString)) {
return cookiesString;
}
if (typeof cookiesString !== "string") {
return [];
}
var cookiesStrings = [];
var pos = 0;
var start;
var ch;
var lastComma;
var nextStart;
var cookiesSeparatorFound;
function skipWhitespace() {
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
pos += 1;
}
return pos < cookiesString.length;
}
function notSpecialChar() {
ch = cookiesString.charAt(pos);
return ch !== "=" && ch !== ";" && ch !== ",";
}
while (pos < cookiesString.length) {
start = pos;
cookiesSeparatorFound = false;
while (skipWhitespace()) {
ch = cookiesString.charAt(pos);
if (ch === ",") {
// ',' is a cookie separator if we have later first '=', not ';' or ','
lastComma = pos;
pos += 1;
skipWhitespace();
nextStart = pos;
while (pos < cookiesString.length && notSpecialChar()) {
pos += 1;
}
// currently special character
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
// we found cookies separator
cookiesSeparatorFound = true;
// pos is inside the next cookie, so back up and return it.
pos = nextStart;
cookiesStrings.push(cookiesString.substring(start, lastComma));
start = pos;
} else {
// in param ',' or param separator ';',
// we continue from that comma
pos = lastComma + 1;
}
} else {
pos += 1;
}
}
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
}
}
return cookiesStrings;
}
// named export for CJS
parseSetCookie.parseSetCookie = parseSetCookie;
// for backwards compatibility
parseSetCookie.parse = parseSetCookie;
parseSetCookie.parseString = parseString;
parseSetCookie.splitCookiesString = splitCookiesString;
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;
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 });
}
}
event_state.is_endpoint_request = true;
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 (browser) ;
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 (browser) ;
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" });`
);
}
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);
}
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}`)
);
data = void 0;
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
));
}
},
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
));
}
},
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);
return await with_request_store(
{ event: traced_event, state: event_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: () => {
},
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(() => {
});
return response;
};
}
async function stream_to_string(stream) {
let result = "";
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
result += text_decoder.decode(value);
}
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>`;
}
const s = JSON.stringify;
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 exec(match, params, matchers) {
const result = {};
const values = match.slice(1);
const values_needing_match = values.filter((value) => value !== void 0);
let buffered = 0;
for (let i = 0; i < params.length; i += 1) {
const param = params[i];
let value = values[i - buffered];
if (param.chained && param.rest && buffered) {
value = values.slice(i - buffered, i + 1).filter((s2) => s2).join("/");
buffered = 0;
}
if (value === void 0) {
if (param.rest) {
value = "";
} else {
continue;
}
}
if (!param.matcher || matchers[param.matcher](value)) {
result[param.name] = value;
const next_param = params[i + 1];
const next_value = values[i + 1];
if (next_param && !next_param.rest && next_param.optional && next_value && param.chained) {
buffered = 0;
}
if (!next_param && !next_value && Object.keys(result).length === values_needing_match.length) {
buffered = 0;
}
continue;
}
if (param.optional && param.chained) {
buffered++;
continue;
}
return;
}
if (buffered) return;
return result;
}
function find_route(path, routes, matchers) {
for (const route of routes) {
const match = route.pattern.exec(path);
if (!match) continue;
const matched = exec(match, route.params, matchers);
if (matched) {
return {
route,
params: decode_params(matched)
};
}
}
return null;
}
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 `${create_client_import(
/** @type {string} */
manifest._.client.start,
url
)}.then(x => x.load_css([${css}]));`;
}
const updated = {
...readable(false),
check: () => false
};
async function render_response({
branch,
fetched,
options: options2,
manifest,
state,
page_config,
status,
error: error2 = null,
event,
event_state,
resolve_opts,
action_result,
data_serializer
}) {
if (state.prerendering) {
if (options2.csp.mode === "nonce") {
throw new Error('Cannot use prerendering if config.kit.csp.mode === "nonce"');
}
if (options2.app_template_contains_nonce) {
throw new Error("Cannot use prerendering if page template contains %sveltekit.nonce%");
}
}
const { client } = manifest._;
const modulepreloads = new Set(client.imports);
const stylesheets = new Set(client.stylesheets);
const fonts = new Set(client.fonts);
const link_headers = /* @__PURE__ */ new Set();
const inline_styles = /* @__PURE__ */ new Map();
let rendered;
const form_value = action_result?.type === "success" || action_result?.type === "failure" ? action_result.data ?? null : null;
let base$1 = base;
let assets$1 = assets;
let base_expression = s(base);
const csp = new Csp(options2.csp, {
prerender: !!state.prerendering
});
{
if (!state.prerendering?.fallback) {
const segments = event.url.pathname.slice(base.length).split("/").slice(2);
base$1 = segments.map(() => "..").join("/") || ".";
base_expression = `new URL(${s(base$1)}, location).pathname.slice(0, -1)`;
if (!assets || assets[0] === "/" && assets !== SVELTE_KIT_ASSETS) {
assets$1 = base$1;
}
} else if (options2.hash_routing) {
base_expression = "new URL('.', location).pathname.slice(0, -1)";
}
}
if (page_config.ssr) {
const props = {
stores: {
page: writable(null),
navigating: writable(null),
updated
},
constructors: await Promise.all(
branch.map(({ node }) => {
if (!node.component) {
throw new Error(`Missing +page.svelte component for route ${event.route.id}`);
}
return node.component();
})
),
form: form_value
};
let data2 = {};
for (let i = 0; i < branch.length; i += 1) {
data2 = { ...data2, ...branch[i].data };
props[`data_${i}`] = data2;
}
props.page = {
error: error2,
params: (
/** @type {Record<string, any>} */
event.params
),
route: event.route,
status,
url: event.url,
data: data2,
form: form_value,
state: {}
};
const render_opts = {
context: /* @__PURE__ */ new Map([
[
"__request__",
{
page: props.page
}
]
]),
csp: csp.script_needs_nonce ? { nonce: csp.nonce } : { hash: csp.script_needs_hash }
};
try {
if (browser) ;
rendered = await with_request_store({ event, state: event_state }, async () => {
if (relative) override({ base: base$1, assets: assets$1 });
const maybe_promise = options2.root.render(props, render_opts);
const rendered2 = options2.async && "then" in maybe_promise ? (
/** @type {ReturnType<typeof options.root.render> & Promise<any>} */
maybe_promise.then((r) => r)
) : maybe_promise;
if (options2.async) {
reset();
}
const { head: head2, html: html2, css, hashes } = (
/** @type {ReturnType<typeof options.root.render>} */
options2.async ? await rendered2 : rendered2
);
if (hashes) {
csp.add_script_hashes(hashes.script);
}
return { head: head2, html: html2, css, hashes };
});
} finally {
reset();
}
for (const { node } of branch) {
for (const url of node.imports) modulepreloads.add(url);
for (const url of node.stylesheets) stylesheets.add(url);
for (const url of node.fonts) fonts.add(url);
if (node.inline_styles && !client.inline) {
Object.entries(await node.inline_styles()).forEach(([filename, css]) => {
if (typeof css === "string") {
inline_styles.set(filename, css);
return;
}
inline_styles.set(filename, css(`${assets$1}/${app_dir}/immutable/assets`, assets$1));
});
}
}
} else {
rendered = { head: "", html: "", css: { code: "", map: null }, hashes: { script: [] } };
}
const head = new Head(rendered.head, !!state.prerendering);
let body2 = rendered.html;
const prefixed = (path) => {
if (path.startsWith("/")) {
return base + path;
}
return `${assets$1}/${path}`;
};
const style = client.inline ? client.inline?.style : Array.from(inline_styles.values()).join("\n");
if (style) {
const attributes = [];
if (csp.style_needs_nonce) attributes.push(`nonce="${csp.nonce}"`);
csp.add_style(style);
head.add_style(style, attributes);
}
for (const dep of stylesheets) {
const path = prefixed(dep);
const attributes = ['rel="stylesheet"'];
if (inline_styles.has(dep)) {
attributes.push("disabled", 'media="(max-width: 0)"');
} else {
if (resolve_opts.preload({ type: "css", path })) {
link_headers.add(`<${encodeURI(path)}>; rel="preload"; as="style"; nopush`);
}
}
head.add_stylesheet(path, attributes);
}
for (const dep of fonts) {
const path = prefixed(dep);
if (resolve_opts.preload({ type: "font", path })) {
const ext = dep.slice(dep.lastIndexOf(".") + 1);
head.add_link_tag(path, ['rel="preload"', 'as="font"', `type="font/${ext}"`, "crossorigin"]);
link_headers.add(
`<${encodeURI(path)}>; rel="preload"; as="font"; type="font/${ext}"; crossorigin; nopush`
);
}
}
const global = get_global_name(options2);
const { data, chunks } = data_serializer.get_data(csp);
if (page_config.ssr && page_config.csr) {
body2 += `
${fetched.map(
(item) => serialize_data(item, resolve_opts.filterSerializedResponseHeaders, !!state.prerendering)
).join("\n ")}`;
}
if (page_config.csr) {
const route = manifest._.client.routes?.find((r) => r.id === event.route.id) ?? null;
if (client.uses_env_dynamic_public && state.prerendering) {
modulepreloads.add(`${app_dir}/env.js`);
}
if (!client.inline) {
const included_modulepreloads = Array.from(modulepreloads, (dep) => prefixed(dep)).filter(
(path) => resolve_opts.preload({ type: "js", path })
);
for (const path of included_modulepreloads) {
link_headers.add(`<${encodeURI(path)}>; rel="modulepreload"; nopush`);
if (options2.preload_strategy !== "modulepreload") {
head.add_script_preload(path);
} else {
head.add_link_tag(path, ['rel="modulepreload"']);
}
}
}
if (manifest._.client.routes && state.prerendering && !state.prerendering.fallback) {
const pathname = add_resolution_suffix(event.url.pathname);
state.prerendering.dependencies.set(
pathname,
create_server_routing_response(route, event.params, new URL(pathname, event.url), manifest)
);
}
const blocks = [];
const load_env_eagerly = client.uses_env_dynamic_public && state.prerendering;
const properties = [`base: ${base_expression}`];
if (assets) {
properties.push(`assets: ${s(assets)}`);
}
if (client.uses_env_dynamic_public) {
properties.push(`env: ${load_env_eagerly ? "null" : s(public_env)}`);
}
if (chunks) {
blocks.push("const deferred = new Map();");
properties.push(`defer: (id) => new Promise((fulfil, reject) => {
deferred.set(id, { fulfil, reject });
})`);
let app_declaration = "";
if (Object.keys(options2.hooks.transport).length > 0) {
if (client.inline) {
app_declaration = `const app = __sveltekit_${options2.version_hash}.app.app;`;
} else if (client.app) {
app_declaration = `const app = await import(${s(prefixed(client.app))});`;
} else {
app_declaration = `const { app } = await import(${s(prefixed(client.start))});`;
}
}
const prelude = app_declaration ? `${app_declaration}
const [data, error] = fn(app);` : `const [data, error] = fn();`;
properties.push(`resolve: async (id, fn) => {
${prelude}
const try_to_resolve = () => {
if (!deferred.has(id)) {
setTimeout(try_to_resolve, 0);
return;
}
const { fulfil, reject } = deferred.get(id);
deferred.delete(id);
if (error) reject(error);
else fulfil(data);
}
try_to_resolve();
}`);
}
blocks.push(`${global} = {
${properties.join(",\n ")}
};`);
const args = ["element"];
blocks.push("const element = document.currentScript.parentElement;");
if (page_config.ssr) {
const serialized = { form: "null", error: "null" };
if (form_value) {
serialized.form = uneval_action_response(
form_value,
/** @type {string} */
event.route.id,
options2.hooks.transport
);
}
if (error2) {
serialized.error = uneval(error2);
}
const hydrate = [
`node_ids: [${branch.map(({ node }) => node.index).join(", ")}]`,
`data: ${data}`,
`form: ${serialized.form}`,
`error: ${serialized.error}`
];
if (status !== 200) {
hydrate.push(`status: ${status}`);
}
if (manifest._.client.routes) {
if (route) {
const stringified = generate_route_object(route, event.url, manifest).replaceAll(
"\n",
"\n "
);
hydrate.push(`params: ${uneval(event.params)}`, `server_route: ${stringified}`);
}
} else if (options2.embedded) {
hydrate.push(`params: ${uneval(event.params)}`, `route: ${s(event.route)}`);
}
const indent = " ".repeat(load_env_eagerly ? 7 : 6);
args.push(`{
${indent} ${hydrate.join(`,
${indent} `)}
${indent}}`);
}
const { remote_data: remote_cache } = event_state;
let serialized_remote_data = "";
if (remote_cache) {
const remote = {};
for (const [info, cache] of remote_cache) {
if (!info.id) continue;
for (const key2 in cache) {
remote[create_remote_key(info.id, key2)] = await cache[key2];
}
}
const replacer = (thing) => {
for (const key2 in options2.hooks.transport) {
const encoded = options2.hooks.transport[key2].encode(thing);
if (encoded) {
return `app.decode('${key2}', ${uneval(encoded, replacer)})`;
}
}
};
serialized_remote_data = `${global}.data = ${uneval(remote, replacer)};
`;
}
const boot = client.inline ? `${client.inline.script}
${serialized_remote_data}${global}.app.start(${args.join(", ")});` : client.app ? `Promise.all([
import(${s(prefixed(client.start))}),
import(${s(prefixed(client.app))})
]).then(([kit, app]) => {
${serialized_remote_data}kit.start(app, ${args.join(", ")});
});` : `import(${s(prefixed(client.start))}).then((app) => {
${serialized_remote_data}app.start(${args.join(", ")})
});`;
if (load_env_eagerly) {
blocks.push(`import(${s(`${base$1}/${app_dir}/env.js`)}).then(({ env }) => {
${global}.env = env;
${boot.replace(/\n/g, "\n ")}
});`);
} else {
blocks.push(boot);
}
if (options2.service_worker) {
let opts = "";
if (options2.service_worker_options != null) {
const service_worker_options = { ...options2.service_worker_options };
opts = `, ${s(service_worker_options)}`;
}
blocks.push(`if ('serviceWorker' in navigator) {
addEventListener('load', function () {
navigator.serviceWorker.register('${prefixed("service-worker.js")}'${opts});
});
}`);
}
const init_app = `
{
${blocks.join("\n\n ")}
}
`;
csp.add_script(init_app);
body2 += `
<script${csp.script_needs_nonce ? ` nonce="${csp.nonce}"` : ""}>${init_app}<\/script>
`;
}
const headers2 = new Headers({
"x-sveltekit-page": "true",
"content-type": "text/html"
});
if (state.prerendering) {
const csp_headers = csp.csp_provider.get_meta();
if (csp_headers) {
head.add_http_equiv(csp_headers);
}
if (state.prerendering.cache) {
head.add_http_equiv(
`<meta http-equiv="cache-control" content="${state.prerendering.cache}">`
);
}
} else {
const csp_header = csp.csp_provider.get_header();
if (csp_header) {
headers2.set("content-security-policy", csp_header);
}
const report_only_header = csp.report_only_provider.get_header();
if (report_only_header) {
headers2.set("content-security-policy-report-only", report_only_header);
}
if (link_headers.size) {
headers2.set("link", Array.from(link_headers).join(", "));
}
}
const html = options2.templates.app({
head: head.build(),
body: body2,
assets: assets$1,
nonce: (
/** @type {string} */
csp.nonce
),
env: public_env
});
const transformed = await resolve_opts.transformPageChunk({
html,
done: true
}) || "";
if (!chunks) {
headers2.set("etag", `"${hash(transformed)}"`);
}
return !chunks ? text(transformed, {
status,
headers: headers2
}) : new Response(
new ReadableStream({
async start(controller) {
controller.enqueue(text_encoder.encode(transformed + "\n"));
for await (const chunk of chunks) {
if (chunk.length) controller.enqueue(text_encoder.encode(chunk));
}
controller.close();
},
type: "bytes"
}),
{
headers: headers2
}
);
}
class Head {
#rendered;
#prerendering;
/** @type {string[]} */
#http_equiv = [];
/** @type {string[]} */
#link_tags = [];
/** @type {string[]} */
#script_preloads = [];
/** @type {string[]} */
#style_tags = [];
/** @type {string[]} */
#stylesheet_links = [];
/**
* @param {string} rendered
* @param {boolean} prerendering
*/
constructor(rendered, prerendering) {
this.#rendered = rendered;
this.#prerendering = prerendering;
}
build() {
return [
...this.#http_equiv,
...this.#link_tags,
...this.#script_preloads,
this.#rendered,
...this.#style_tags,
...this.#stylesheet_links
].join("\n ");
}
/**
* @param {string} style
* @param {string[]} attributes
*/
add_style(style, attributes) {
this.#style_tags.push(
`<style${attributes.length ? " " + attributes.join(" ") : ""}>${style}</style>`
);
}
/**
* @param {string} href
* @param {string[]} attributes
*/
add_stylesheet(href, attributes) {
this.#stylesheet_links.push(`<link href="${href}" ${attributes.join(" ")}>`);
}
/** @param {string} href */
add_script_preload(href) {
this.#script_preloads.push(
`<link rel="preload" as="script" crossorigin="anonymous" href="${href}">`
);
}
/**
* @param {string} href
* @param {string[]} attributes
*/
add_link_tag(href, attributes) {
if (!this.#prerendering) return;
this.#link_tags.push(`<link href="${href}" ${attributes.join(" ")}>`);
}
/** @param {string} tag */
add_http_equiv(tag) {
if (!this.#prerendering) return;
this.#http_equiv.push(tag);
}
}
class PageNodes {
data;
/**
* @param {Array<import('types').SSRNode | undefined>} nodes
*/
constructor(nodes) {
this.data = nodes;
}
layouts() {
return this.data.slice(0, -1);
}
page() {
return this.data.at(-1);
}
validate() {
for (const layout of this.layouts()) {
if (layout) {
validate_layout_server_exports(
layout.server,
/** @type {string} */
layout.server_id
);
validate_layout_exports(
layout.universal,
/** @type {string} */
layout.universal_id
);
}
}
const page = this.page();
if (page) {
validate_page_server_exports(
page.server,
/** @type {string} */
page.server_id
);
validate_page_exports(
page.universal,
/** @type {string} */
page.universal_id
);
}
}
/**
* @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash'} Option
* @param {Option} option
* @returns {Value | undefined}
*/
#get_option(option) {
return this.data.reduce(
(value, node) => {
return node?.universal?.[option] ?? node?.server?.[option] ?? value;
},
/** @type {Value | undefined} */
void 0
);
}
csr() {
return this.#get_option("csr") ?? true;
}
ssr() {
return this.#get_option("ssr") ?? true;
}
prerender() {
return this.#get_option("prerender") ?? false;
}
trailing_slash() {
return this.#get_option("trailingSlash") ?? "never";
}
get_config() {
let current2 = {};
for (const node of this.data) {
if (!node?.universal?.config && !node?.server?.config) continue;
current2 = {
...current2,
// TODO: should we override the server config value with the universal value similar to other page options?
...node?.universal?.config,
...node?.server?.config
};
}
return Object.keys(current2).length ? current2 : void 0;
}
should_prerender_data() {
return this.data.some(
// prerender in case of trailingSlash because the client retrieves that value from the server
(node) => node?.server?.load || node?.server?.trailingSlash !== void 0
);
}
}
async function respond_with_error({
event,
event_state,
options: options2,
manifest,
state,
status,
error: error2,
resolve_opts
}) {
if (event.request.headers.get("x-sveltekit-error")) {
return static_error_page(
options2,
status,
/** @type {Error} */
error2.message
);
}
const fetched = [];
try {
const branch = [];
const default_layout = await manifest._.nodes[0]();
const nodes = new PageNodes([default_layout]);
const ssr = nodes.ssr();
const csr = nodes.csr();
const data_serializer = server_data_serializer(event, event_state, options2);
if (ssr) {
state.error = true;
const server_data_promise = load_server_data({
event,
event_state,
state,
node: default_layout,
// eslint-disable-next-line @typescript-eslint/require-await
parent: async () => ({})
});
const server_data = await server_data_promise;
data_serializer.add_node(0, server_data);
const data = await load_data({
event,
event_state,
fetched,
node: default_layout,
// eslint-disable-next-line @typescript-eslint/require-await
parent: async () => ({}),
resolve_opts,
server_data_promise,
state,
csr
});
branch.push(
{
node: default_layout,
server_data,
data
},
{
node: await manifest._.nodes[1](),
// 1 is always the root error
data: null,
server_data: null
}
);
}
return await render_response({
options: options2,
manifest,
state,
page_config: {
ssr,
csr
},
status,
error: await handle_error_and_jsonify(event, event_state, options2, error2),
branch,
fetched,
event,
event_state,
resolve_opts,
data_serializer
});
} catch (e) {
if (e instanceof Redirect) {
return redirect_response(e.status, e.location);
}
return static_error_page(
options2,
get_status(e),
(await handle_error_and_jsonify(event, event_state, options2, e)).message
);
}
}
async function handle_remote_call(event, state, options2, manifest, id) {
return record_span({
name: "sveltekit.remote.call",
attributes: {},
fn: (current2) => {
const traced_event = merge_tracing(event, current2);
return with_request_store(
{ event: traced_event, state },
() => handle_remote_call_internal(traced_event, state, options2, manifest, id)
);
}
});
}
async function handle_remote_call_internal(event, state, options2, manifest, id) {
const [hash2, name, additional_args] = id.split("/");
const remotes = manifest._.remotes;
if (!remotes[hash2]) error(404);
const module = await remotes[hash2]();
const fn = module.default[name];
if (!fn) error(404);
const info = fn.__;
const transport = options2.hooks.transport;
event.tracing.current.setAttributes({
"sveltekit.remote.call.type": info.type,
"sveltekit.remote.call.name": info.name
});
let form_client_refreshes;
try {
if (info.type === "query_batch") {
if (event.request.method !== "POST") {
throw new SvelteKitError(
405,
"Method Not Allowed",
`\`query.batch\` functions must be invoked via POST request, not ${event.request.method}`
);
}
const { payloads } = await event.request.json();
const args = await Promise.all(
payloads.map((payload2) => parse_remote_arg(payload2, transport))
);
const results = await with_request_store({ event, state }, () => info.run(args, options2));
return json(
/** @type {RemoteFunctionResponse} */
{
type: "result",
result: stringify(results, transport)
}
);
}
if (info.type === "form") {
if (event.request.method !== "POST") {
throw new SvelteKitError(
405,
"Method Not Allowed",
`\`form\` functions must be invoked via POST request, not ${event.request.method}`
);
}
if (!is_form_content_type(event.request)) {
throw new SvelteKitError(
415,
"Unsupported Media Type",
`\`form\` functions expect form-encoded data — received ${event.request.headers.get(
"content-type"
)}`
);
}
const { data: data2, meta, form_data } = await deserialize_binary_form(event.request);
if (additional_args && !("id" in data2)) {
data2.id = JSON.parse(decodeURIComponent(additional_args));
}
const fn2 = info.fn;
const result = await with_request_store({ event, state }, () => fn2(data2, meta, form_data));
return json(
/** @type {RemoteFunctionResponse} */
{
type: "result",
result: stringify(result, transport),
refreshes: result.issues ? void 0 : await serialize_refreshes(meta.remote_refreshes)
}
);
}
if (info.type === "command") {
const { payload: payload2, refreshes } = await event.request.json();
const arg = parse_remote_arg(payload2, transport);
const data2 = await with_request_store({ event, state }, () => fn(arg));
return json(
/** @type {RemoteFunctionResponse} */
{
type: "result",
result: stringify(data2, transport),
refreshes: await serialize_refreshes(refreshes)
}
);
}
const payload = info.type === "prerender" ? additional_args : (
/** @type {string} */
// new URL(...) necessary because we're hiding the URL from the user in the event object
new URL(event.request.url).searchParams.get("payload")
);
const data = await with_request_store(
{ event, state },
() => fn(parse_remote_arg(payload, transport))
);
return json(
/** @type {RemoteFunctionResponse} */
{
type: "result",
result: stringify(data, transport)
}
);
} catch (error2) {
if (error2 instanceof Redirect) {
return json(
/** @type {RemoteFunctionResponse} */
{
type: "redirect",
location: error2.location,
refreshes: await serialize_refreshes(form_client_refreshes)
}
);
}
const status = error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500;
return json(
/** @type {RemoteFunctionResponse} */
{
type: "error",
error: await handle_error_and_jsonify(event, state, options2, error2),
status
},
{
// By setting a non-200 during prerendering we fail the prerender process (unless handleHttpError handles it).
// Errors at runtime will be passed to the client and are handled there
status: state.prerendering ? status : void 0,
headers: {
"cache-control": "private, no-store"
}
}
);
}
async function serialize_refreshes(client_refreshes) {
const refreshes = state.refreshes ?? {};
if (client_refreshes) {
for (const key2 of client_refreshes) {
if (refreshes[key2] !== void 0) continue;
const [hash3, name2, payload] = key2.split("/");
const loader = manifest._.remotes[hash3];
const fn2 = (await loader?.())?.default?.[name2];
if (!fn2) error(400, "Bad Request");
refreshes[key2] = with_request_store(
{ event, state },
() => fn2(parse_remote_arg(payload, transport))
);
}
}
if (Object.keys(refreshes).length === 0) {
return void 0;
}
return stringify(
Object.fromEntries(
await Promise.all(
Object.entries(refreshes).map(async ([key2, promise]) => [key2, await promise])
)
),
transport
);
}
}
async function handle_remote_form_post(event, state, manifest, id) {
return record_span({
name: "sveltekit.remote.form.post",
attributes: {},
fn: (current2) => {
const traced_event = merge_tracing(event, current2);
return with_request_store(
{ event: traced_event, state },
() => handle_remote_form_post_internal(traced_event, state, manifest, id)
);
}
});
}
async function handle_remote_form_post_internal(event, state, manifest, id) {
const [hash2, name, action_id] = id.split("/");
const remotes = manifest._.remotes;
const module = await remotes[hash2]?.();
let form = (
/** @type {RemoteForm<any, any>} */
module?.default[name]
);
if (!form) {
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"}`
)
};
}
if (action_id) {
form = with_request_store({ event, state }, () => form.for(JSON.parse(action_id)));
}
try {
const fn = (
/** @type {RemoteInfo & { type: 'form' }} */
/** @type {any} */
form.__.fn
);
const { data, meta, form_data } = await deserialize_binary_form(event.request);
if (action_id && !("id" in data)) {
data.id = JSON.parse(decodeURIComponent(action_id));
}
await with_request_store({ event, state }, () => fn(data, meta, form_data));
return {
type: "success",
status: 200
};
} 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 get_remote_id(url) {
return url.pathname.startsWith(`${base}/${app_dir}/remote/`) && url.pathname.replace(`${base}/${app_dir}/remote/`, "");
}
function get_remote_action(url) {
return url.searchParams.get("/remote");
}
const MAX_DEPTH = 10;
async function render_page(event, event_state, page, options2, manifest, state, nodes, resolve_opts) {
if (state.depth > MAX_DEPTH) {
return text(`Not found: ${event.url.pathname}`, {
status: 404
// TODO in some cases this should be 500. not sure how to differentiate
});
}
if (is_action_json_request(event)) {
const node = await manifest._.nodes[page.leaf]();
return handle_action_json_request(event, event_state, options2, node?.server);
}
try {
const leaf_node = (
/** @type {import('types').SSRNode} */
nodes.page()
);
let status = 200;
let action_result = void 0;
if (is_action_request(event)) {
const remote_id = get_remote_action(event.url);
if (remote_id) {
action_result = await handle_remote_form_post(event, event_state, manifest, remote_id);
} else {
action_result = await handle_action_request(event, event_state, leaf_node.server);
}
if (action_result?.type === "redirect") {
return redirect_response(action_result.status, action_result.location);
}
if (action_result?.type === "error") {
status = get_status(action_result.error);
}
if (action_result?.type === "failure") {
status = action_result.status;
}
}
const should_prerender = nodes.prerender();
if (should_prerender) {
const mod = leaf_node.server;
if (mod?.actions) {
throw new Error("Cannot prerender pages with actions");
}
} else if (state.prerendering) {
return new Response(void 0, {
status: 204
});
}
state.prerender_default = should_prerender;
const should_prerender_data = nodes.should_prerender_data();
const data_pathname = add_data_suffix(event.url.pathname);
const fetched = [];
const ssr = nodes.ssr();
const csr = nodes.csr();
if (ssr === false && !(state.prerendering && should_prerender_data)) {
if (browser && action_result && !event.request.headers.has("x-sveltekit-action")) ;
return await render_response({
branch: [],
fetched,
page_config: {
ssr: false,
csr
},
status,
error: null,
event,
event_state,
options: options2,
manifest,
state,
resolve_opts,
data_serializer: server_data_serializer(event, event_state, options2)
});
}
const branch = [];
let load_error = null;
const data_serializer = server_data_serializer(event, event_state, options2);
const data_serializer_json = state.prerendering && should_prerender_data ? server_data_serializer_json(event, event_state, options2) : null;
const server_promises = nodes.data.map((node, i) => {
if (load_error) {
throw load_error;
}
return Promise.resolve().then(async () => {
try {
if (node === leaf_node && action_result?.type === "error") {
throw action_result.error;
}
const server_data = await load_server_data({
event,
event_state,
state,
node,
parent: async () => {
const data = {};
for (let j = 0; j < i; j += 1) {
const parent = await server_promises[j];
if (parent) Object.assign(data, parent.data);
}
return data;
}
});
if (node) {
data_serializer.add_node(i, server_data);
}
data_serializer_json?.add_node(i, server_data);
return server_data;
} catch (e) {
load_error = /** @type {Error} */
e;
throw load_error;
}
});
});
const load_promises = nodes.data.map((node, i) => {
if (load_error) throw load_error;
return Promise.resolve().then(async () => {
try {
return await load_data({
event,
event_state,
fetched,
node,
parent: async () => {
const data = {};
for (let j = 0; j < i; j += 1) {
Object.assign(data, await load_promises[j]);
}
return data;
},
resolve_opts,
server_data_promise: server_promises[i],
state,
csr
});
} catch (e) {
load_error = /** @type {Error} */
e;
throw load_error;
}
});
});
for (const p of server_promises) p.catch(() => {
});
for (const p of load_promises) p.catch(() => {
});
for (let i = 0; i < nodes.data.length; i += 1) {
const node = nodes.data[i];
if (node) {
try {
const server_data = await server_promises[i];
const data = await load_promises[i];
branch.push({ node, server_data, data });
} catch (e) {
const err = normalize_error(e);
if (err instanceof Redirect) {
if (state.prerendering && should_prerender_data) {
const body2 = JSON.stringify({
type: "redirect",
location: err.location
});
state.prerendering.dependencies.set(data_pathname, {
response: text(body2),
body: body2
});
}
return redirect_response(err.status, err.location);
}
const status2 = get_status(err);
const error2 = await handle_error_and_jsonify(event, event_state, options2, err);
while (i--) {
if (page.errors[i]) {
const index = (
/** @type {number} */
page.errors[i]
);
const node2 = await manifest._.nodes[index]();
let j = i;
while (!branch[j]) j -= 1;
data_serializer.set_max_nodes(j + 1);
const layouts = compact(branch.slice(0, j + 1));
const nodes2 = new PageNodes(layouts.map((layout) => layout.node));
return await render_response({
event,
event_state,
options: options2,
manifest,
state,
resolve_opts,
page_config: {
ssr: nodes2.ssr(),
csr: nodes2.csr()
},
status: status2,
error: error2,
branch: layouts.concat({
node: node2,
data: null,
server_data: null
}),
fetched,
data_serializer
});
}
}
return static_error_page(options2, status2, error2.message);
}
} else {
branch.push(null);
}
}
if (state.prerendering && data_serializer_json) {
let { data, chunks } = data_serializer_json.get_data();
if (chunks) {
for await (const chunk of chunks) {
data += chunk;
}
}
state.prerendering.dependencies.set(data_pathname, {
response: text(data),
body: data
});
}
return await render_response({
event,
event_state,
options: options2,
manifest,
state,
resolve_opts,
page_config: {
csr,
ssr
},
status,
error: null,
branch: ssr === false ? [] : compact(branch),
action_result,
fetched,
data_serializer: ssr === false ? server_data_serializer(event, event_state, options2) : data_serializer
});
} catch (e) {
if (e instanceof Redirect) {
return redirect_response(e.status, e.location);
}
return await respond_with_error({
event,
event_state,
options: options2,
manifest,
state,
status: e instanceof HttpError ? e.status : 500,
error: e,
resolve_opts
});
}
}
function once(fn) {
let done = false;
let result;
return () => {
if (done) return result;
done = true;
return result = fn();
};
}
async function render_data(event, event_state, route, options2, manifest, state, invalidated_data_nodes, trailing_slash) {
if (!route.page) {
return new Response(void 0, {
status: 404
});
}
try {
const node_ids = [...route.page.layouts, route.page.leaf];
const invalidated = invalidated_data_nodes ?? node_ids.map(() => true);
let aborted = false;
const url = new URL(event.url);
url.pathname = normalize_path(url.pathname, trailing_slash);
const new_event = { ...event, url };
const functions = node_ids.map((n, i) => {
return once(async () => {
try {
if (aborted) {
return (
/** @type {import('types').ServerDataSkippedNode} */
{
type: "skip"
}
);
}
const node = n == void 0 ? n : await manifest._.nodes[n]();
return load_server_data({
event: new_event,
event_state,
state,
node,
parent: async () => {
const data2 = {};
for (let j = 0; j < i; j += 1) {
const parent = (
/** @type {import('types').ServerDataNode | null} */
await functions[j]()
);
if (parent) {
Object.assign(data2, parent.data);
}
}
return data2;
}
});
} catch (e) {
aborted = true;
throw e;
}
});
});
const promises = functions.map(async (fn, i) => {
if (!invalidated[i]) {
return (
/** @type {import('types').ServerDataSkippedNode} */
{
type: "skip"
}
);
}
return fn();
});
let length = promises.length;
const nodes = await Promise.all(
promises.map(
(p, i) => p.catch(async (error2) => {
if (error2 instanceof Redirect) {
throw error2;
}
length = Math.min(length, i + 1);
return (
/** @type {import('types').ServerErrorNode} */
{
type: "error",
error: await handle_error_and_jsonify(event, event_state, options2, error2),
status: error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : void 0
}
);
})
)
);
const data_serializer = server_data_serializer_json(event, event_state, options2);
for (let i = 0; i < nodes.length; i++) data_serializer.add_node(i, nodes[i]);
const { data, chunks } = data_serializer.get_data();
if (!chunks) {
return json_response(data);
}
return new Response(
new ReadableStream({
async start(controller) {
controller.enqueue(text_encoder.encode(data));
for await (const chunk of chunks) {
controller.enqueue(text_encoder.encode(chunk));
}
controller.close();
},
type: "bytes"
}),
{
headers: {
// we use a proprietary content type to prevent buffering.
// the `text` prefix makes it inspectable
"content-type": "text/sveltekit-data",
"cache-control": "private, no-store"
}
}
);
} catch (e) {
const error2 = normalize_error(e);
if (error2 instanceof Redirect) {
return redirect_json_response(error2);
} else {
return json_response(await handle_error_and_jsonify(event, event_state, options2, error2), 500);
}
}
}
function json_response(json2, status = 200) {
return text(typeof json2 === "string" ? json2 : JSON.stringify(json2), {
status,
headers: {
"content-type": "application/json",
"cache-control": "private, no-store"
}
});
}
function redirect_json_response(redirect) {
return json_response(
/** @type {import('types').ServerRedirectNode} */
{
type: "redirect",
location: redirect.location
}
);
}
const INVALID_COOKIE_CHARACTER_REGEX = /[\x00-\x1F\x7F()<>@,;:"/[\]?={} \t]/;
function validate_options(options2) {
if (options2?.path === void 0) {
throw new Error("You must specify a `path` when setting, deleting or serializing cookies");
}
}
function generate_cookie_key(domain, path, name) {
return `${domain || ""}${path}?${encodeURIComponent(name)}`;
}
function get_cookies(request, url) {
const header = request.headers.get("cookie") ?? "";
const initial_cookies = cookieExports.parse(header, { decode: (value) => value });
let normalized_url;
const new_cookies = /* @__PURE__ */ new Map();
const defaults = {
httpOnly: true,
sameSite: "lax",
secure: url.hostname === "localhost" && url.protocol === "http:" ? false : true
};
const cookies = {
// The JSDoc param annotations appearing below for get, set and delete
// are necessary to expose the `cookie` library types to
// typescript users. `@type {import('@sveltejs/kit').Cookies}` above is not
// sufficient to do so.
/**
* @param {string} name
* @param {import('cookie').CookieParseOptions} [opts]
*/
get(name, opts) {
const best_match = Array.from(new_cookies.values()).filter((c) => {
return c.name === name && domain_matches(url.hostname, c.options.domain) && path_matches(url.pathname, c.options.path);
}).sort((a, b) => b.options.path.length - a.options.path.length)[0];
if (best_match) {
return best_match.options.maxAge === 0 ? void 0 : best_match.value;
}
const req_cookies = cookieExports.parse(header, { decode: opts?.decode });
const cookie = req_cookies[name];
return cookie;
},
/**
* @param {import('cookie').CookieParseOptions} [opts]
*/
getAll(opts) {
const cookies2 = cookieExports.parse(header, { decode: opts?.decode });
const lookup = /* @__PURE__ */ new Map();
for (const c of new_cookies.values()) {
if (domain_matches(url.hostname, c.options.domain) && path_matches(url.pathname, c.options.path)) {
const existing = lookup.get(c.name);
if (!existing || c.options.path.length > existing.options.path.length) {
lookup.set(c.name, c);
}
}
}
for (const c of lookup.values()) {
cookies2[c.name] = c.value;
}
return Object.entries(cookies2).map(([name, value]) => ({ name, value }));
},
/**
* @param {string} name
* @param {string} value
* @param {import('./page/types.js').Cookie['options']} options
*/
set(name, value, options2) {
const illegal_characters = name.match(INVALID_COOKIE_CHARACTER_REGEX);
if (illegal_characters) {
console.warn(
`The cookie name "${name}" will be invalid in SvelteKit 3.0 as it contains ${illegal_characters.join(
" and "
)}. See RFC 2616 for more details https://datatracker.ietf.org/doc/html/rfc2616#section-2.2`
);
}
validate_options(options2);
set_internal(name, value, { ...defaults, ...options2 });
},
/**
* @param {string} name
* @param {import('./page/types.js').Cookie['options']} options
*/
delete(name, options2) {
validate_options(options2);
cookies.set(name, "", { ...options2, maxAge: 0 });
},
/**
* @param {string} name
* @param {string} value
* @param {import('./page/types.js').Cookie['options']} options
*/
serialize(name, value, options2) {
validate_options(options2);
let path = options2.path;
if (!options2.domain || options2.domain === url.hostname) {
if (!normalized_url) {
throw new Error("Cannot serialize cookies until after the route is determined");
}
path = resolve(normalized_url, path);
}
return cookieExports.serialize(name, value, { ...defaults, ...options2, path });
}
};
function get_cookie_header(destination, header2) {
const combined_cookies = {
// cookies sent by the user agent have lowest precedence
...initial_cookies
};
for (const cookie of new_cookies.values()) {
if (!domain_matches(destination.hostname, cookie.options.domain)) continue;
if (!path_matches(destination.pathname, cookie.options.path)) continue;
const encoder = cookie.options.encode || encodeURIComponent;
combined_cookies[cookie.name] = encoder(cookie.value);
}
if (header2) {
const parsed = cookieExports.parse(header2, { decode: (value) => value });
for (const name in parsed) {
combined_cookies[name] = parsed[name];
}
}
return Object.entries(combined_cookies).map(([name, value]) => `${name}=${value}`).join("; ");
}
const internal_queue = [];
function set_internal(name, value, options2) {
if (!normalized_url) {
internal_queue.push(() => set_internal(name, value, options2));
return;
}
let path = options2.path;
if (!options2.domain || options2.domain === url.hostname) {
path = resolve(normalized_url, path);
}
const cookie_key = generate_cookie_key(options2.domain, path, name);
const cookie = { name, value, options: { ...options2, path } };
new_cookies.set(cookie_key, cookie);
}
function set_trailing_slash(trailing_slash) {
normalized_url = normalize_path(url.pathname, trailing_slash);
internal_queue.forEach((fn) => fn());
}
return { cookies, new_cookies, get_cookie_header, set_internal, set_trailing_slash };
}
function domain_matches(hostname, constraint) {
if (!constraint) return true;
const normalized = constraint[0] === "." ? constraint.slice(1) : constraint;
if (hostname === normalized) return true;
return hostname.endsWith("." + normalized);
}
function path_matches(path, constraint) {
if (!constraint) return true;
const normalized = constraint.endsWith("/") ? constraint.slice(0, -1) : constraint;
if (path === normalized) return true;
return path.startsWith(normalized + "/");
}
function add_cookies_to_headers(headers2, cookies) {
for (const new_cookie of cookies) {
const { name, value, options: options2 } = new_cookie;
headers2.append("set-cookie", cookieExports.serialize(name, value, options2));
if (options2.path.endsWith(".html")) {
const path = add_data_suffix(options2.path);
headers2.append("set-cookie", cookieExports.serialize(name, value, { ...options2, path }));
}
}
}
function create_fetch({ event, options: options2, manifest, state, get_cookie_header, set_internal }) {
const server_fetch = async (info, init2) => {
const original_request = normalize_fetch_input(info, init2, event.url);
let mode = (info instanceof Request ? info.mode : init2?.mode) ?? "cors";
let credentials = (info instanceof Request ? info.credentials : init2?.credentials) ?? "same-origin";
return options2.hooks.handleFetch({
event,
request: original_request,
fetch: async (info2, init3) => {
const request = normalize_fetch_input(info2, init3, event.url);
const url = new URL(request.url);
if (!request.headers.has("origin")) {
request.headers.set("origin", event.url.origin);
}
if (info2 !== original_request) {
mode = (info2 instanceof Request ? info2.mode : init3?.mode) ?? "cors";
credentials = (info2 instanceof Request ? info2.credentials : init3?.credentials) ?? "same-origin";
}
if ((request.method === "GET" || request.method === "HEAD") && (mode === "no-cors" && url.origin !== event.url.origin || url.origin === event.url.origin)) {
request.headers.delete("origin");
}
const decoded = decodeURIComponent(url.pathname);
if (url.origin !== event.url.origin || base && decoded !== base && !decoded.startsWith(`${base}/`)) {
if (`.${url.hostname}`.endsWith(`.${event.url.hostname}`) && credentials !== "omit") {
const cookie = get_cookie_header(url, request.headers.get("cookie"));
if (cookie) request.headers.set("cookie", cookie);
}
return fetch(request);
}
const prefix = assets || base;
const filename = (decoded.startsWith(prefix) ? decoded.slice(prefix.length) : decoded).slice(1);
const filename_html = `${filename}/index.html`;
const is_asset = manifest.assets.has(filename) || filename in manifest._.server_assets;
const is_asset_html = manifest.assets.has(filename_html) || filename_html in manifest._.server_assets;
if (is_asset || is_asset_html) {
const file = is_asset ? filename : filename_html;
if (state.read) {
const type = is_asset ? manifest.mimeTypes[filename.slice(filename.lastIndexOf("."))] : "text/html";
return new Response(state.read(file), {
headers: type ? { "content-type": type } : {}
});
} else if (read_implementation && file in manifest._.server_assets) {
const length = manifest._.server_assets[file];
const type = manifest.mimeTypes[file.slice(file.lastIndexOf("."))];
return new Response(read_implementation(file), {
headers: {
"Content-Length": "" + length,
"Content-Type": type
}
});
}
return await fetch(request);
}
if (has_prerendered_path(manifest, base + decoded)) {
return await fetch(request);
}
if (credentials !== "omit") {
const cookie = get_cookie_header(url, request.headers.get("cookie"));
if (cookie) {
request.headers.set("cookie", cookie);
}
const authorization = event.request.headers.get("authorization");
if (authorization && !request.headers.has("authorization")) {
request.headers.set("authorization", authorization);
}
}
if (!request.headers.has("accept")) {
request.headers.set("accept", "*/*");
}
if (!request.headers.has("accept-language")) {
request.headers.set(
"accept-language",
/** @type {string} */
event.request.headers.get("accept-language")
);
}
const response = await internal_fetch(request, options2, manifest, state);
const set_cookie = response.headers.get("set-cookie");
if (set_cookie) {
for (const str of splitCookiesString(set_cookie)) {
const { name, value, ...options3 } = parseString(str, {
decodeValues: false
});
const path = options3.path ?? (url.pathname.split("/").slice(0, -1).join("/") || "/");
set_internal(name, value, {
path,
encode: (value2) => value2,
.../** @type {import('cookie').CookieSerializeOptions} */
options3
});
}
}
return response;
}
});
};
return (input, init2) => {
const response = server_fetch(input, init2);
response.catch(() => {
});
return response;
};
}
function normalize_fetch_input(info, init2, url) {
if (info instanceof Request) {
return info;
}
return new Request(typeof info === "string" ? new URL(info, url) : info, init2);
}
async function internal_fetch(request, options2, manifest, state) {
if (request.signal) {
if (request.signal.aborted) {
throw new DOMException("The operation was aborted.", "AbortError");
}
let remove_abort_listener = () => {
};
const abort_promise = new Promise((_, reject) => {
const on_abort = () => {
reject(new DOMException("The operation was aborted.", "AbortError"));
};
request.signal.addEventListener("abort", on_abort, { once: true });
remove_abort_listener = () => request.signal.removeEventListener("abort", on_abort);
});
const result = await Promise.race([
respond(request, options2, manifest, {
...state,
depth: state.depth + 1
}),
abort_promise
]);
remove_abort_listener();
return result;
} else {
return await respond(request, options2, manifest, {
...state,
depth: state.depth + 1
});
}
}
let body;
let etag;
let headers;
function get_public_env(request) {
body ??= `export const env=${JSON.stringify(public_env)}`;
etag ??= `W/${Date.now()}`;
headers ??= new Headers({
"content-type": "application/javascript; charset=utf-8",
etag
});
if (request.headers.get("if-none-match") === etag) {
return new Response(void 0, { status: 304, headers });
}
return new Response(body, { headers });
}
const default_transform = ({ html }) => html;
const default_filter = () => false;
const default_preload = ({ type }) => type === "js" || type === "css";
const page_methods = /* @__PURE__ */ new Set(["GET", "HEAD", "POST"]);
const allowed_page_methods = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
const respond = propagate_context(internal_respond);
async function internal_respond(request, options2, manifest, state) {
const url = new URL(request.url);
const is_route_resolution_request = has_resolution_suffix(url.pathname);
const is_data_request = has_data_suffix(url.pathname);
const remote_id = get_remote_id(url);
{
const request_origin = request.headers.get("origin");
if (remote_id) {
if (request.method !== "GET" && request_origin !== url.origin) {
const message = "Cross-site remote requests are forbidden";
return json({ message }, { status: 403 });
}
} else if (options2.csrf_check_origin) {
const forbidden = is_form_content_type(request) && (request.method === "POST" || request.method === "PUT" || request.method === "PATCH" || request.method === "DELETE") && request_origin !== url.origin && (!request_origin || !options2.csrf_trusted_origins.includes(request_origin));
if (forbidden) {
const message = `Cross-site ${request.method} form submissions are forbidden`;
const opts = { status: 403 };
if (request.headers.get("accept") === "application/json") {
return json({ message }, opts);
}
return text(message, opts);
}
}
}
if (options2.hash_routing && url.pathname !== base + "/" && url.pathname !== "/[fallback]") {
return text("Not found", { status: 404 });
}
let invalidated_data_nodes;
if (is_route_resolution_request) {
url.pathname = strip_resolution_suffix(url.pathname);
} else if (is_data_request) {
url.pathname = strip_data_suffix(url.pathname) + (url.searchParams.get(TRAILING_SLASH_PARAM) === "1" ? "/" : "") || "/";
url.searchParams.delete(TRAILING_SLASH_PARAM);
invalidated_data_nodes = url.searchParams.get(INVALIDATED_PARAM)?.split("").map((node) => node === "1");
url.searchParams.delete(INVALIDATED_PARAM);
} else if (remote_id) {
url.pathname = request.headers.get("x-sveltekit-pathname") ?? base;
url.search = request.headers.get("x-sveltekit-search") ?? "";
}
const headers2 = {};
const { cookies, new_cookies, get_cookie_header, set_internal, set_trailing_slash } = get_cookies(
request,
url
);
const event_state = {
prerendering: state.prerendering,
transport: options2.hooks.transport,
handleValidationError: options2.hooks.handleValidationError,
tracing: {
record_span
},
is_in_remote_function: false
};
const event = {
cookies,
// @ts-expect-error `fetch` needs to be created after the `event` itself
fetch: null,
getClientAddress: state.getClientAddress || (() => {
throw new Error(
`${"@sveltejs/adapter-node"} does not specify getClientAddress. Please raise an issue`
);
}),
locals: {},
params: {},
platform: state.platform,
request,
route: { id: null },
setHeaders: (new_headers) => {
for (const key2 in new_headers) {
const lower = key2.toLowerCase();
const value = new_headers[key2];
if (lower === "set-cookie") {
throw new Error(
"Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies"
);
} else if (lower in headers2) {
if (lower === "server-timing") {
headers2[lower] += ", " + value;
} else {
throw new Error(`"${key2}" header is already set`);
}
} else {
headers2[lower] = value;
if (state.prerendering && lower === "cache-control") {
state.prerendering.cache = /** @type {string} */
value;
}
}
}
},
url,
isDataRequest: is_data_request,
isSubRequest: state.depth > 0,
isRemoteRequest: !!remote_id
};
event.fetch = create_fetch({
event,
options: options2,
manifest,
state,
get_cookie_header,
set_internal
});
if (state.emulator?.platform) {
event.platform = await state.emulator.platform({
config: {},
prerender: !!state.prerendering?.fallback
});
}
let resolved_path = url.pathname;
if (!remote_id) {
const prerendering_reroute_state = state.prerendering?.inside_reroute;
try {
if (state.prerendering) state.prerendering.inside_reroute = true;
resolved_path = await options2.hooks.reroute({ url: new URL(url), fetch: event.fetch }) ?? url.pathname;
} catch {
return text("Internal Server Error", {
status: 500
});
} finally {
if (state.prerendering) state.prerendering.inside_reroute = prerendering_reroute_state;
}
}
try {
resolved_path = decode_pathname(resolved_path);
} catch {
return text("Malformed URI", { status: 400 });
}
if (
// the resolved path has been decoded so it should be compared to the decoded url pathname
resolved_path !== decode_pathname(url.pathname) && !state.prerendering?.fallback && has_prerendered_path(manifest, resolved_path)
) {
const url2 = new URL(request.url);
url2.pathname = is_data_request ? add_data_suffix(resolved_path) : is_route_resolution_request ? add_resolution_suffix(resolved_path) : resolved_path;
try {
const response = await fetch(url2, request);
const headers22 = new Headers(response.headers);
if (headers22.has("content-encoding")) {
headers22.delete("content-encoding");
headers22.delete("content-length");
}
return new Response(response.body, {
headers: headers22,
status: response.status,
statusText: response.statusText
});
} catch (error2) {
return await handle_fatal_error(event, event_state, options2, error2);
}
}
let route = null;
if (base && !state.prerendering?.fallback) {
if (!resolved_path.startsWith(base)) {
return text("Not found", { status: 404 });
}
resolved_path = resolved_path.slice(base.length) || "/";
}
if (is_route_resolution_request) {
return resolve_route(resolved_path, new URL(request.url), manifest);
}
if (resolved_path === `/${app_dir}/env.js`) {
return get_public_env(request);
}
if (!remote_id && resolved_path.startsWith(`/${app_dir}`)) {
const headers22 = new Headers();
headers22.set("cache-control", "public, max-age=0, must-revalidate");
return text("Not found", { status: 404, headers: headers22 });
}
if (!state.prerendering?.fallback) {
const matchers = await manifest._.matchers();
const result = find_route(resolved_path, manifest._.routes, matchers);
if (result) {
route = result.route;
event.route = { id: route.id };
event.params = result.params;
}
}
let resolve_opts = {
transformPageChunk: default_transform,
filterSerializedResponseHeaders: default_filter,
preload: default_preload
};
let trailing_slash = "never";
try {
const page_nodes = route?.page ? new PageNodes(await load_page_nodes(route.page, manifest)) : void 0;
if (route && !remote_id) {
if (url.pathname === base || url.pathname === base + "/") {
trailing_slash = "always";
} else if (page_nodes) {
if (browser) ;
trailing_slash = page_nodes.trailing_slash();
} else if (route.endpoint) {
const node = await route.endpoint();
trailing_slash = node.trailingSlash ?? "never";
if (browser) ;
}
if (!is_data_request) {
const normalized = normalize_path(url.pathname, trailing_slash);
if (normalized !== url.pathname && !state.prerendering?.fallback) {
return new Response(void 0, {
status: 308,
headers: {
"x-sveltekit-normalize": "1",
location: (
// ensure paths starting with '//' are not treated as protocol-relative
(normalized.startsWith("//") ? url.origin + normalized : normalized) + (url.search === "?" ? "" : url.search)
)
}
});
}
}
if (state.before_handle || state.emulator?.platform) {
let config = {};
let prerender = false;
if (route.endpoint) {
const node = await route.endpoint();
config = node.config ?? config;
prerender = node.prerender ?? prerender;
} else if (page_nodes) {
config = page_nodes.get_config() ?? config;
prerender = page_nodes.prerender();
}
if (state.before_handle) {
state.before_handle(event, config, prerender);
}
if (state.emulator?.platform) {
event.platform = await state.emulator.platform({ config, prerender });
}
}
}
set_trailing_slash(trailing_slash);
if (state.prerendering && !state.prerendering.fallback && !state.prerendering.inside_reroute) {
disable_search(url);
}
const response = await record_span({
name: "sveltekit.handle.root",
attributes: {
"http.route": event.route.id || "unknown",
"http.method": event.request.method,
"http.url": event.url.href,
"sveltekit.is_data_request": is_data_request,
"sveltekit.is_sub_request": event.isSubRequest
},
fn: async (root_span) => {
const traced_event = {
...event,
tracing: {
enabled: false,
root: root_span,
current: root_span
}
};
return await with_request_store(
{ event: traced_event, state: event_state },
() => options2.hooks.handle({
event: traced_event,
resolve: (event2, opts) => {
return record_span({
name: "sveltekit.resolve",
attributes: {
"http.route": event2.route.id || "unknown"
},
fn: (resolve_span) => {
return with_request_store(
null,
() => resolve2(merge_tracing(event2, resolve_span), page_nodes, opts).then(
(response2) => {
for (const key2 in headers2) {
const value = headers2[key2];
response2.headers.set(
key2,
/** @type {string} */
value
);
}
add_cookies_to_headers(response2.headers, new_cookies.values());
if (state.prerendering && event2.route.id !== null) {
response2.headers.set("x-sveltekit-routeid", encodeURI(event2.route.id));
}
resolve_span.setAttributes({
"http.response.status_code": response2.status,
"http.response.body.size": response2.headers.get("content-length") || "unknown"
});
return response2;
}
)
);
}
});
}
})
);
}
});
if (response.status === 200 && response.headers.has("etag")) {
let if_none_match_value = request.headers.get("if-none-match");
if (if_none_match_value?.startsWith('W/"')) {
if_none_match_value = if_none_match_value.substring(2);
}
const etag2 = (
/** @type {string} */
response.headers.get("etag")
);
if (if_none_match_value === etag2) {
const headers22 = new Headers({ etag: etag2 });
for (const key2 of [
"cache-control",
"content-location",
"date",
"expires",
"vary",
"set-cookie"
]) {
const value = response.headers.get(key2);
if (value) headers22.set(key2, value);
}
return new Response(void 0, {
status: 304,
headers: headers22
});
}
}
if (is_data_request && response.status >= 300 && response.status <= 308) {
const location = response.headers.get("location");
if (location) {
return redirect_json_response(new Redirect(
/** @type {any} */
response.status,
location
));
}
}
return response;
} catch (e) {
if (e instanceof Redirect) {
const response = is_data_request || remote_id ? redirect_json_response(e) : route?.page && is_action_json_request(event) ? action_json_redirect(e) : redirect_response(e.status, e.location);
add_cookies_to_headers(response.headers, new_cookies.values());
return response;
}
return await handle_fatal_error(event, event_state, options2, e);
}
async function resolve2(event2, page_nodes, opts) {
try {
if (opts) {
resolve_opts = {
transformPageChunk: opts.transformPageChunk || default_transform,
filterSerializedResponseHeaders: opts.filterSerializedResponseHeaders || default_filter,
preload: opts.preload || default_preload
};
}
if (options2.hash_routing || state.prerendering?.fallback) {
return await render_response({
event: event2,
event_state,
options: options2,
manifest,
state,
page_config: { ssr: false, csr: true },
status: 200,
error: null,
branch: [],
fetched: [],
resolve_opts,
data_serializer: server_data_serializer(event2, event_state, options2)
});
}
if (remote_id) {
return await handle_remote_call(event2, event_state, options2, manifest, remote_id);
}
if (route) {
const method = (
/** @type {import('types').HttpMethod} */
event2.request.method
);
let response2;
if (is_data_request) {
response2 = await render_data(
event2,
event_state,
route,
options2,
manifest,
state,
invalidated_data_nodes,
trailing_slash
);
} else if (route.endpoint && (!route.page || is_endpoint_request(event2))) {
response2 = await render_endpoint(event2, event_state, await route.endpoint(), state);
} else if (route.page) {
if (!page_nodes) {
throw new Error("page_nodes not found. This should never happen");
} else if (page_methods.has(method)) {
response2 = await render_page(
event2,
event_state,
route.page,
options2,
manifest,
state,
page_nodes,
resolve_opts
);
} else {
const allowed_methods = new Set(allowed_page_methods);
const node = await manifest._.nodes[route.page.leaf]();
if (node?.server?.actions) {
allowed_methods.add("POST");
}
if (method === "OPTIONS") {
response2 = new Response(null, {
status: 204,
headers: {
allow: Array.from(allowed_methods.values()).join(", ")
}
});
} else {
const mod = [...allowed_methods].reduce(
(acc, curr) => {
acc[curr] = true;
return acc;
},
/** @type {Record<string, any>} */
{}
);
response2 = method_not_allowed(mod, method);
}
}
} else {
throw new Error("Route is neither page nor endpoint. This should never happen");
}
if (request.method === "GET" && route.page && route.endpoint) {
const vary = response2.headers.get("vary")?.split(",")?.map((v) => v.trim().toLowerCase());
if (!(vary?.includes("accept") || vary?.includes("*"))) {
response2 = new Response(response2.body, {
status: response2.status,
statusText: response2.statusText,
headers: new Headers(response2.headers)
});
response2.headers.append("Vary", "Accept");
}
}
return response2;
}
if (state.error && event2.isSubRequest) {
const headers22 = new Headers(request.headers);
headers22.set("x-sveltekit-error", "true");
return await fetch(request, { headers: headers22 });
}
if (state.error) {
return text("Internal Server Error", {
status: 500
});
}
if (state.depth === 0) {
if (browser && event2.url.pathname === "/.well-known/appspecific/com.chrome.devtools.json") ;
return await respond_with_error({
event: event2,
event_state,
options: options2,
manifest,
state,
status: 404,
error: new SvelteKitError(404, "Not Found", `Not found: ${event2.url.pathname}`),
resolve_opts
});
}
if (state.prerendering) {
return text("not found", { status: 404 });
}
const response = await fetch(request);
return new Response(response.body, response);
} catch (e) {
return await handle_fatal_error(event2, event_state, options2, e);
} finally {
event2.cookies.set = () => {
throw new Error("Cannot use `cookies.set(...)` after the response has been generated");
};
event2.setHeaders = () => {
throw new Error("Cannot use `setHeaders(...)` after the response has been generated");
};
}
}
}
function load_page_nodes(page, manifest) {
return Promise.all([
// we use == here rather than === because [undefined] serializes as "[null]"
...page.layouts.map((n) => n == void 0 ? n : manifest._.nodes[n]()),
manifest._.nodes[page.leaf]()
]);
}
function propagate_context(fn) {
return async (req, ...rest) => {
{
return fn(req, ...rest);
}
};
}
function filter_env(env, allowed, disallowed) {
return Object.fromEntries(
Object.entries(env).filter(
([k]) => k.startsWith(allowed) && (disallowed === "" || !k.startsWith(disallowed))
)
);
}
function set_app(value) {
}
let init_promise;
let current = null;
class Server {
/** @type {import('types').SSROptions} */
#options;
/** @type {import('@sveltejs/kit').SSRManifest} */
#manifest;
/** @param {import('@sveltejs/kit').SSRManifest} manifest */
constructor(manifest) {
this.#options = options;
this.#manifest = manifest;
if (IN_WEBCONTAINER) {
const respond2 = this.respond.bind(this);
this.respond = async (...args) => {
const { promise, resolve: resolve2 } = (
/** @type {PromiseWithResolvers<void>} */
with_resolvers()
);
const previous = current;
current = promise;
await previous;
return respond2(...args).finally(resolve2);
};
}
}
/**
* @param {import('@sveltejs/kit').ServerInitOptions} opts
*/
async init({ env, read }) {
const { env_public_prefix, env_private_prefix } = this.#options;
set_private_env(filter_env(env, env_private_prefix, env_public_prefix));
set_public_env(filter_env(env, env_public_prefix, env_private_prefix));
if (read) {
const wrapped_read = (file) => {
const result = read(file);
if (result instanceof ReadableStream) {
return result;
} else {
return new ReadableStream({
async start(controller) {
try {
const stream = await Promise.resolve(result);
if (!stream) {
controller.close();
return;
}
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
controller.enqueue(value);
}
controller.close();
} catch (error2) {
controller.error(error2);
}
}
});
}
};
set_read_implementation(wrapped_read);
}
await (init_promise ??= (async () => {
try {
const module = await get_hooks();
this.#options.hooks = {
handle: module.handle || (({ event, resolve: resolve2 }) => resolve2(event)),
handleError: module.handleError || (({ status, error: error2, event }) => {
const error_message = format_server_error(
status,
/** @type {Error} */
error2,
event
);
console.error(error_message);
}),
handleFetch: module.handleFetch || (({ request, fetch: fetch2 }) => fetch2(request)),
handleValidationError: module.handleValidationError || (({ issues }) => {
console.error("Remote function schema validation failed:", issues);
return { message: "Bad Request" };
}),
reroute: module.reroute || (() => {
}),
transport: module.transport || {}
};
set_app({
decoders: module.transport ? Object.fromEntries(Object.entries(module.transport).map(([k, v]) => [k, v.decode])) : {}
});
if (module.init) {
await module.init();
}
} catch (e) {
{
throw e;
}
}
})());
}
/**
* @param {Request} request
* @param {import('types').RequestOptions} options
*/
async respond(request, options2) {
return respond(request, this.#options, this.#manifest, {
...options2,
error: false,
depth: 0
});
}
}
export { Server };
//# sourceMappingURL=index.js.map