Socket
Socket
Sign inDemoInstall

@sveltejs/kit

Package Overview
Dependencies
Maintainers
4
Versions
784
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sveltejs/kit - npm Package Compare versions

Comparing version 1.27.5 to 2.0.6

src/core/sync/write_non_ambient.js

55

package.json
{
"name": "@sveltejs/kit",
"version": "1.27.5",
"version": "2.0.6",
"description": "The fastest way to build Svelte apps",

@@ -14,34 +14,33 @@ "repository": {

"dependencies": {
"@sveltejs/vite-plugin-svelte": "^2.5.0",
"@types/cookie": "^0.5.1",
"cookie": "^0.5.0",
"devalue": "^4.3.1",
"@types/cookie": "^0.6.0",
"cookie": "^0.6.0",
"devalue": "^4.3.2",
"esm-env": "^1.0.0",
"kleur": "^4.1.5",
"magic-string": "^0.30.0",
"mrmime": "^1.0.1",
"magic-string": "^0.30.5",
"mrmime": "^2.0.0",
"sade": "^1.8.1",
"set-cookie-parser": "^2.6.0",
"sirv": "^2.0.2",
"tiny-glob": "^0.2.9",
"undici": "~5.26.2"
"sirv": "^2.0.4",
"tiny-glob": "^0.2.9"
},
"devDependencies": {
"@playwright/test": "1.30.0",
"@types/connect": "^3.4.35",
"@types/node": "^16.18.6",
"@types/sade": "^1.7.4",
"@types/set-cookie-parser": "^2.4.2",
"dts-buddy": "^0.2.4",
"marked": "^9.0.0",
"rollup": "^3.29.4",
"svelte": "^4.2.2",
"svelte-preprocess": "^5.0.4",
"typescript": "^4.9.4",
"vite": "^4.4.9",
"vitest": "^0.34.5"
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@types/connect": "^3.4.38",
"@types/node": "^18.19.3",
"@types/sade": "^1.7.8",
"@types/set-cookie-parser": "^2.4.7",
"dts-buddy": "^0.4.3",
"rollup": "^4.8.0",
"svelte": "^4.2.8",
"svelte-preprocess": "^5.1.2",
"typescript": "^5.3.3",
"vite": "^5.0.8",
"vitest": "^1.0.4"
},
"peerDependencies": {
"svelte": "^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0",
"vite": "^4.0.0"
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"svelte": "^4.0.0 || ^5.0.0-next.0",
"vite": "^5.0.3"
},

@@ -85,9 +84,9 @@ "bin": {

"engines": {
"node": "^16.14 || >=18"
"node": ">=18.13"
},
"scripts": {
"lint": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore",
"check": "tsc",
"lint": "prettier --config ../../.prettierrc --check .",
"check": "tsc && cd ./test/types && tsc",
"check:all": "tsc && pnpm -r --filter=\"./**\" check",
"format": "prettier --write . --config ../../.prettierrc --ignore-path .gitignore",
"format": "prettier --config ../../.prettierrc --write .",
"test": "pnpm test:unit && pnpm test:integration",

@@ -94,0 +93,0 @@ "test:integration": "pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test",

@@ -5,3 +5,3 @@ # The fastest way to build Svelte apps

The quickest way to get started is via the [create-svelte](https://github.com/sveltejs/kit/tree/master/packages/create-svelte) package:
The quickest way to get started is via the [create-svelte](https://github.com/sveltejs/kit/tree/main/packages/create-svelte) package:

@@ -19,2 +19,2 @@ ```bash

[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).
[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md).

@@ -9,12 +9,4 @@ /**

export const ENDPOINT_METHODS = new Set([
'GET',
'POST',
'PUT',
'PATCH',
'DELETE',
'OPTIONS',
'HEAD'
]);
export const ENDPOINT_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD'];
export const PAGE_METHODS = new Set(['GET', 'POST', 'HEAD']);
export const PAGE_METHODS = ['GET', 'POST', 'HEAD'];

@@ -159,2 +159,9 @@ import { existsSync, statSync, createReadStream, createWriteStream } from 'node:fs';

generateEnvModule() {
const dest = `${config.kit.outDir}/output/prerendered/dependencies/${config.kit.appDir}/env.js`;
const env = get_env(config.kit.env, vite_config.mode);
write(dest, `export const env=${JSON.stringify(env.public)}`);
},
generateManifest({ relativePath, routes: subset }) {

@@ -217,3 +224,3 @@ return generate_manifest({

}
})
})
: zlib.createGzip({ level: zlib.constants.Z_BEST_COMPRESSION });

@@ -220,0 +227,0 @@

@@ -72,3 +72,11 @@ import fs from 'node:fs';

return process_config(config.default, { cwd });
try {
return process_config(config.default, { cwd });
} catch (e) {
const error = /** @type {Error} */ (e);
// redact the stack trace — it's not helpful to users
error.stack = `Could not load svelte.config.js: ${error.message}\n`;
throw error;
}
}

@@ -75,0 +83,0 @@

@@ -114,7 +114,2 @@ import { join } from 'node:path';

dangerZone: object({
// TODO 2.0: Remove this
trackServerFetches: boolean(false)
}),
embedded: boolean(false),

@@ -183,9 +178,3 @@

}),
relative: validate(undefined, (input, keypath) => {
if (typeof input !== 'boolean') {
throw new Error(`${keypath} option must be a boolean or undefined`);
}
return input;
})
relative: boolean(true)
}),

@@ -192,0 +181,0 @@

@@ -13,7 +13,6 @@ import { join } from 'node:path';

import { forked } from '../../utils/fork.js';
import { should_polyfill } from '../../utils/platform.js';
import { installPolyfills } from '../../exports/node/polyfills.js';
import { resolvePath } from '../../exports/index.js';
import { ENDPOINT_METHODS } from '../../constants.js';
import { filter_private_env, filter_public_env } from '../../utils/env.js';
import { resolve_route } from '../../utils/routing.js';

@@ -40,14 +39,15 @@ export default forked(import.meta.url, analyse);

if (should_polyfill) {
installPolyfills();
}
installPolyfills();
// configure `import { building } from '$app/environment'` —
// essential we do this before analysing the code
internal.set_building(true);
internal.set_building();
// set env, in case it's used in initialisation
const { publicPrefix: public_prefix, privatePrefix: private_prefix } = config.env;
internal.set_private_env(filter_private_env(env, { public_prefix, private_prefix }));
internal.set_public_env(filter_public_env(env, { public_prefix, private_prefix }));
const private_env = filter_private_env(env, { public_prefix, private_prefix });
const public_env = filter_public_env(env, { public_prefix, private_prefix });
internal.set_private_env(private_env);
internal.set_public_env(public_env);
internal.set_safe_public_env(public_env);

@@ -60,6 +60,6 @@ /** @type {import('types').ServerMetadata} */

const nodes = await Promise.all(manifest._.nodes.map((loader) => loader()));
// analyse nodes
for (const loader of manifest._.nodes) {
const node = await loader();
for (const node of nodes) {
metadata.nodes[node.index] = {

@@ -72,74 +72,31 @@ has_server_load: node.server?.load !== undefined || node.server?.trailingSlash !== undefined

for (const route of manifest._.routes) {
/** @type {Array<'GET' | 'POST'>} */
const page_methods = [];
const page =
route.page &&
analyse_page(
route.page.layouts.map((n) => (n === undefined ? n : nodes[n])),
nodes[route.page.leaf]
);
/** @type {(import('types').HttpMethod | '*')[]} */
const api_methods = [];
const endpoint = route.endpoint && analyse_endpoint(route, await route.endpoint());
/** @type {import('types').PrerenderOption | undefined} */
let prerender = undefined;
/** @type {any} */
let config = undefined;
/** @type {import('types').PrerenderEntryGenerator | undefined} */
let entries = undefined;
if (page?.prerender && endpoint?.prerender) {
throw new Error(`Cannot prerender a route with both +page and +server files (${route.id})`);
}
if (route.endpoint) {
const mod = await route.endpoint();
if (mod.prerender !== undefined) {
validate_server_exports(mod, route.id);
if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
if (page?.config && endpoint?.config) {
for (const key in { ...page.config, ...endpoint.config }) {
if (JSON.stringify(page.config[key]) !== JSON.stringify(endpoint.config[key])) {
throw new Error(
`Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})`
`Mismatched route config for ${route.id} — the +page and +server files must export the same config, if any`
);
}
prerender = mod.prerender;
}
Object.values(mod).forEach((/** @type {import('types').HttpMethod} */ method) => {
if (mod[method] && ENDPOINT_METHODS.has(method)) {
api_methods.push(method);
} else if (mod.fallback) {
api_methods.push('*');
}
});
config = mod.config;
entries = mod.entries;
}
if (route.page) {
const nodes = await Promise.all(
[...route.page.layouts, route.page.leaf].map((n) => {
if (n !== undefined) return manifest._.nodes[n]();
})
);
const page_methods = page?.methods ?? [];
const api_methods = endpoint?.methods ?? [];
const entries = page?.entries ?? endpoint?.entries;
const layouts = nodes.slice(0, -1);
const page = nodes.at(-1);
for (const layout of layouts) {
if (layout) {
validate_layout_server_exports(layout.server, layout.server_id);
validate_layout_exports(layout.universal, layout.universal_id);
}
}
if (page) {
page_methods.push('GET');
if (page.server?.actions) page_methods.push('POST');
validate_page_server_exports(page.server, page.server_id);
validate_page_exports(page.universal, page.universal_id);
}
prerender = get_option(nodes, 'prerender') ?? false;
config = get_config(nodes);
entries ??= get_option(nodes, 'entries');
}
metadata.routes.set(route.id, {
config,
config: page?.config ?? endpoint?.config,
methods: Array.from(new Set([...page_methods, ...api_methods])),

@@ -152,5 +109,5 @@ page: {

},
prerender,
prerender: page?.prerender ?? endpoint?.prerender,
entries:
entries && (await entries()).map((entry_object) => resolvePath(route.id, entry_object))
entries && (await entries()).map((entry_object) => resolve_route(route.id, entry_object))
});

@@ -163,2 +120,61 @@ }

/**
* @param {import('types').SSRRoute} route
* @param {import('types').SSREndpoint} mod
*/
function analyse_endpoint(route, mod) {
validate_server_exports(mod, route.id);
if (mod.prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) {
throw new Error(
`Cannot prerender a +server file with POST, PATCH, PUT, or DELETE (${route.id})`
);
}
/** @type {Array<import('types').HttpMethod | '*'>} */
const methods = [];
for (const method of /** @type {import('types').HttpMethod[]} */ (ENDPOINT_METHODS)) {
if (mod[method]) methods.push(method);
}
if (mod.fallback) {
methods.push('*');
}
return {
config: mod.config,
entries: mod.entries,
methods,
prerender: mod.prerender ?? false
};
}
/**
* @param {Array<import('types').SSRNode | undefined>} layouts
* @param {import('types').SSRNode} leaf
*/
function analyse_page(layouts, leaf) {
for (const layout of layouts) {
if (layout) {
validate_layout_server_exports(layout.server, layout.server_id);
validate_layout_exports(layout.universal, layout.universal_id);
}
}
/** @type {Array<'GET' | 'POST'>} */
const methods = ['GET'];
if (leaf.server?.actions) methods.push('POST');
validate_page_server_exports(leaf.server, leaf.server_id);
validate_page_exports(leaf.universal, leaf.universal_id);
return {
config: get_config([...layouts, leaf]),
entries: leaf.universal?.entries ?? leaf.server?.entries,
methods,
prerender: get_option([...layouts, leaf], 'prerender') ?? false
};
}
/**
* Do a shallow merge (first level) of the config object

@@ -168,11 +184,13 @@ * @param {Array<import('types').SSRNode | undefined>} nodes

function get_config(nodes) {
/** @type {any} */
let current = {};
for (const node of nodes) {
const config = node?.universal?.config ?? node?.server?.config;
if (config) {
current = {
...current,
...config
};
}
if (!node?.universal?.config && !node?.server?.config) continue;
current = {
...current,
...node?.universal?.config,
...node?.server?.config
};
}

@@ -179,0 +197,0 @@

@@ -33,3 +33,3 @@ import { readFileSync } from 'node:fs';

set_building(true);
set_building();

@@ -36,0 +36,0 @@ const server = new Server(manifest);

@@ -6,3 +6,2 @@ import { existsSync, readFileSync, statSync, writeFileSync } from 'node:fs';

import { mkdirp, posixify, walk } from '../../utils/filesystem.js';
import { should_polyfill } from '../../utils/platform.js';
import { decode_uri, is_root_relative, resolve } from '../../utils/url.js';

@@ -41,3 +40,4 @@ import { escape_html_attr } from '../../utils/escape.js';

// essential we do this before analysing the code
internal.set_building(true);
internal.set_building();
internal.set_prerendering();

@@ -99,5 +99,3 @@ /**

if (should_polyfill) {
installPolyfills();
}
installPolyfills();

@@ -107,5 +105,2 @@ /** @type {Map<string, string>} */

const server = new Server(manifest);
await server.init({ env });
const handle_http_error = normalise_error_handler(

@@ -160,2 +155,3 @@ log,

const files = new Set(walk(`${out}/client`).map(posixify));
files.add(`${config.appDir}/env.js`);

@@ -423,12 +419,23 @@ const immutable = `${config.appDir}/immutable`;

let has_prerenderable_routes = false;
for (const value of prerender_map.values()) {
if (value) {
has_prerenderable_routes = true;
break;
}
}
if (
config.prerender.entries.length > 1 ||
config.prerender.entries[0] !== '*' ||
route_level_entries.length > 0 ||
prerender_map.size > 0
(config.prerender.entries.length === 0 && route_level_entries.length === 0) ||
!has_prerenderable_routes
) {
// Only log if we're actually going to do something to not confuse users
log.info('Prerendering');
return { prerendered, prerender_map };
}
log.info('Prerendering');
const server = new Server(manifest);
await server.init({ env });
for (const entry of config.prerender.entries) {

@@ -438,4 +445,8 @@ if (entry === '*') {

if (prerender) {
if (id.includes('[')) continue;
const path = `/${get_route_segments(id).join('/')}`;
// remove optional parameters from the route
const segments = get_route_segments(id).filter((segment) => !segment.startsWith('[['));
const processed_id = '/' + segments.join('/');
if (processed_id.includes('[')) continue;
const path = `/${get_route_segments(processed_id).join('/')}`;
enqueue(null, config.paths.base + path);

@@ -482,6 +493,6 @@ }

if (not_prerendered.length > 0) {
const list = not_prerendered.map((id) => ` - ${id}`).join('\n');
throw new Error(
`The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${not_prerendered.map(
(id) => ` - ${id}`
)}\n\nSee https://kit.svelte.dev/docs/page-options#prerender-troubleshooting for info on how to solve this`
`The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}\n\nSee https://kit.svelte.dev/docs/page-options#prerender-troubleshooting for info on how to solve this`
);

@@ -488,0 +499,0 @@ }

@@ -8,2 +8,3 @@ import path from 'node:path';

import { write_ambient } from './write_ambient.js';
import { write_non_ambient } from './write_non_ambient.js';
import { write_server } from './write_server.js';

@@ -19,2 +20,3 @@

write_ambient(config.kit, mode);
write_non_ambient(config.kit);
}

@@ -21,0 +23,0 @@

@@ -42,14 +42,25 @@ import { dedent, isSvelte5Plus, write_if_changed } from './utils.js';

<!-- This file is generated by @sveltejs/kit — do not edit it! -->
${isSvelte5Plus() ? '<svelte:options runes={true} />' : ''}
<script>
import { setContext, afterUpdate, onMount, tick } from 'svelte';
import { setContext, ${isSvelte5Plus() ? '' : 'afterUpdate, '}onMount, tick } from 'svelte';
import { browser } from '$app/environment';
// stores
export let stores;
export let page;
${
isSvelte5Plus()
? dedent`
let { stores, page, constructors, components = [], form, ${levels
.map((l) => `data_${l} = null`)
.join(', ')} } = $props();
`
: dedent`
export let stores;
export let page;
export let constructors;
export let components = [];
export let form;
${levels.map((l) => `export let data_${l} = null;`).join('\n')}
export let constructors;
export let components = [];
export let form;
${levels.map((l) => `export let data_${l} = null;`).join('\n')}
`
}

@@ -60,8 +71,27 @@ if (!browser) {

$: stores.page.set(page);
afterUpdate(stores.page.notify);
${
isSvelte5Plus()
? dedent`
if (browser) {
$effect.pre(() => stores.page.set(page));
} else {
stores.page.set(page);
}
`
: '$: stores.page.set(page);'
}
${
isSvelte5Plus()
? dedent`
$effect(() => {
stores;page;constructors;components;form;${levels.map((l) => `data_${l}`).join(';')};
stores.page.notify();
});
`
: 'afterUpdate(stores.page.notify);'
}
let mounted = false;
let navigated = false;
let title = null;
let mounted = ${isSvelte5Plus() ? '$state(false)' : 'false'};
let navigated = ${isSvelte5Plus() ? '$state(false)' : 'false'};
let title = ${isSvelte5Plus() ? '$state(null)' : 'null'};

@@ -68,0 +98,0 @@ onMount(() => {

@@ -29,11 +29,11 @@ import path from 'node:path';

import root from '../root.${isSvelte5Plus() ? 'js' : 'svelte'}';
import { set_building } from '__sveltekit/environment';
import { set_building, set_prerendering } from '__sveltekit/environment';
import { set_assets } from '__sveltekit/paths';
import { set_private_env, set_public_env } from '${runtime_directory}/shared-server.js';
import { set_private_env, set_public_env, set_safe_public_env } from '${runtime_directory}/shared-server.js';
export const options = {
app_dir: ${s(config.kit.appDir)},
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
csp: ${s(config.kit.csp)},
csrf_check_origin: ${s(config.kit.csrf.checkOrigin)},
track_server_fetches: ${s(config.kit.dangerZone.trackServerFetches)},
embedded: ${config.kit.embedded},

@@ -67,3 +67,3 @@ env_public_prefix: '${config.kit.env.publicPrefix}',

export { set_assets, set_building, set_private_env, set_public_env };
export { set_assets, set_building, set_prerendering, set_private_env, set_public_env, set_safe_public_env };
`;

@@ -70,0 +70,0 @@

@@ -6,3 +6,2 @@ import fs from 'node:fs';

import { write_if_changed } from './utils.js';
import { ts } from './ts.js';

@@ -46,34 +45,5 @@ /**

const user_config = load_user_tsconfig(cwd);
if (user_config) validate_user_config(kit, cwd, out, user_config);
if (user_config) validate_user_config(cwd, out, user_config);
// only specify baseUrl if a) the user doesn't specify their own baseUrl
// and b) they have non-relative paths. this causes problems with auto-imports,
// so we print a suggestion that they use relative paths instead
// TODO(v2): never include base URL, and skip the check below
let include_base_url = false;
if (user_config && !user_config.options.compilerOptions?.baseUrl) {
const non_relative_paths = new Set();
for (const paths of Object.values(user_config?.options.compilerOptions?.paths || {})) {
for (const path of paths) {
if (!path.startsWith('.')) non_relative_paths.add(path);
}
}
if (non_relative_paths.size) {
include_base_url = true;
console.log(colors.bold().yellow('Please replace non-relative compilerOptions.paths:\n'));
for (const path of non_relative_paths) {
console.log(` - "${path}" -> "./${path}"`);
}
console.log(
'\nDoing so allows us to omit "baseUrl" — which causes problems with imports — from the generated tsconfig.json. See https://github.com/sveltejs/kit/pull/8437 for more information.'
);
}
}
write_if_changed(out, JSON.stringify(get_tsconfig(kit, include_base_url), null, '\t'));
write_if_changed(out, JSON.stringify(get_tsconfig(kit), null, '\t'));
}

@@ -84,5 +54,4 @@

* @param {import('types').ValidatedKitConfig} kit
* @param {boolean} include_base_url
*/
export function get_tsconfig(kit, include_base_url) {
export function get_tsconfig(kit) {
/** @param {string} file */

@@ -93,2 +62,3 @@ const config_relative = (file) => posixify(path.relative(kit.outDir, file));

'ambient.d.ts',
'non-ambient.d.ts',
'./types/**/$types.d.ts',

@@ -117,3 +87,3 @@ config_relative('vite.config.js'),

const exclude = [config_relative('node_modules/**'), './[!ambient.d.ts]**'];
const exclude = [config_relative('node_modules/**')];
if (path.extname(kit.files.serviceWorker)) {

@@ -130,4 +100,3 @@ exclude.push(config_relative(kit.files.serviceWorker));

// generated options
baseUrl: include_base_url ? config_relative('.') : undefined,
paths: get_tsconfig_paths(kit, include_base_url),
paths: get_tsconfig_paths(kit),
rootDirs: [config_relative('.'), './types'],

@@ -138,8 +107,7 @@

// to enforce using \`import type\` instead of \`import\` for Types.
importsNotUsedAsValues: 'error',
// Also, TypeScript doesn't know about import usages in the template because it only sees the
// script of a Svelte file. Therefore preserve all value imports.
verbatimModuleSyntax: true,
// Vite compiles modules one at a time
isolatedModules: true,
// TypeScript doesn't know about import usages in the template because it only sees the
// script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher.
preserveValueImports: true,

@@ -149,8 +117,6 @@ // This is required for svelte-package to work as expected

lib: ['esnext', 'DOM', 'DOM.Iterable'],
moduleResolution: 'node',
moduleResolution: 'bundler',
module: 'esnext',
target: 'esnext',
// TODO(v2): use the new flag verbatimModuleSyntax instead (requires support by Vite/Esbuild)
ignoreDeprecations: ts && Number(ts.version.split('.')[0]) >= 5 ? '5.0' : undefined
noEmit: true, // prevent tsconfig error "overwriting input files" - Vite handles the build and ignores this
target: 'esnext'
},

@@ -180,3 +146,2 @@ include: [...include],

/**
* @param {import('types').ValidatedKitConfig} kit
* @param {string} cwd

@@ -186,3 +151,3 @@ * @param {string} out

*/
function validate_user_config(kit, cwd, out, config) {
function validate_user_config(cwd, out, config) {
// we need to check that the user's tsconfig extends the framework config

@@ -194,4 +159,4 @@ const extend = config.options.extends;

: Array.isArray(extend)
? extend.some((e) => path.resolve(cwd, e) === out)
: false;
? extend.some((e) => path.resolve(cwd, e) === out)
: false;

@@ -201,25 +166,13 @@ const options = config.options.compilerOptions || {};

if (extends_framework_config) {
const { paths: user_paths } = options;
const { paths, baseUrl } = options;
if (user_paths && fs.existsSync(kit.files.lib)) {
/** @type {string[]} */
const lib = user_paths['$lib'] || [];
/** @type {string[]} */
const lib_ = user_paths['$lib/*'] || [];
// TODO(v2): check needs to be adjusted when we remove the base path
const missing_lib_paths =
!lib.some((relative) => path.resolve(cwd, relative) === kit.files.lib) ||
!lib_.some((relative) => path.resolve(cwd, relative) === path.join(kit.files.lib, '/*'));
if (missing_lib_paths) {
console.warn(
colors
.bold()
.yellow(`Your compilerOptions.paths in ${config.kind} should include the following:`)
);
let relative = posixify(path.relative('.', kit.files.lib));
if (!relative.startsWith('.')) relative = `./${relative}`;
console.warn(`{\n "$lib":["${relative}"],\n "$lib/*":["${relative}/*"]\n}`);
}
if (baseUrl || paths) {
console.warn(
colors
.bold()
.yellow(
`You have specified a baseUrl and/or paths in your ${config.kind} which interferes with SvelteKit's auto-generated tsconfig.json. ` +
'Remove it to avoid problems with intellisense. For path aliases, use `kit.alias` instead: https://kit.svelte.dev/docs/configuration#alias'
)
);
}

@@ -249,5 +202,4 @@ } else {

* @param {import('types').ValidatedKitConfig} config
* @param {boolean} include_base_url
*/
function get_tsconfig_paths(config, include_base_url) {
function get_tsconfig_paths(config) {
/** @param {string} file */

@@ -271,5 +223,3 @@ const config_relative = (file) => posixify(path.relative(config.outDir, file));

const rel_path = (include_base_url ? project_relative : config_relative)(
remove_trailing_slashstar(value)
);
const rel_path = config_relative(remove_trailing_slashstar(value));
const slashstar = key_match[2];

@@ -276,0 +226,0 @@

@@ -483,3 +483,3 @@ import fs from 'node:fs';

: path_to_original(outdir, file_path);
const type = `Kit.AwaitedProperties<Awaited<ReturnType<typeof import('${from}').load>>>`;
const type = `Kit.LoadProperties<Awaited<ReturnType<typeof import('${from}').load>>>`;
return expand ? `Expand<OptionalUnion<EnsureDefined<${type}>>>` : type;

@@ -486,0 +486,0 @@ } else {

@@ -114,3 +114,3 @@ /**

preload
})
})
: resolve(event, { transformPageChunk, filterSerializedResponseHeaders, preload });

@@ -117,0 +117,0 @@ }

import { HttpError, Redirect, ActionFailure } from '../runtime/control.js';
import { BROWSER, DEV } from 'esm-env';
import { get_route_segments } from '../utils/routing.js';

@@ -8,22 +7,54 @@ export { VERSION } from '../version.js';

/**
* @template {number} TNumber
* @template {any[]} [TArray=[]]
* @typedef {TNumber extends TArray['length'] ? TArray[number] : LessThan<TNumber, [...TArray, TArray['length']]>} LessThan
*/
/**
* @template {number} TStart
* @template {number} TEnd
* @typedef {Exclude<TEnd | LessThan<TEnd>, LessThan<TStart>>} NumericRange
*/
// we have to repeat the JSDoc because the display for function overloads is broken
// see https://github.com/microsoft/TypeScript/issues/55056
/**
* Throws an error with a HTTP status code and an optional message.
* When called during request handling, this will cause SvelteKit to
* return an error response without invoking `handleError`.
* Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
* @param {NumericRange<400, 599>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
* @param {App.Error} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
* @overload
* @param {number} status
* @param {NumericRange<400, 599>} status
* @param {App.Error} body
* @return {HttpError}
* @return {never}
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
* @throws {Error} If the provided status is invalid (not between 400 and 599).
*/
/**
* Throws an error with a HTTP status code and an optional message.
* When called during request handling, this will cause SvelteKit to
* return an error response without invoking `handleError`.
* Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
* @param {NumericRange<400, 599>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
* @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body] An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
* @overload
* @param {number} status
* @param {NumericRange<400, 599>} status
* @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} [body]
* @return {HttpError}
* @return {never}
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
* @throws {Error} If the provided status is invalid (not between 400 and 599).
*/
/**
* Creates an `HttpError` object with an HTTP status code and an optional message.
* This object, if thrown during request handling, will cause SvelteKit to
* Throws an error with a HTTP status code and an optional message.
* When called during request handling, this will cause SvelteKit to
* return an error response without invoking `handleError`.
* Make sure you're not catching the thrown error, which would prevent SvelteKit from handling it.
* @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
* @param {NumericRange<400, 599>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
* @param {{ message: string } extends App.Error ? App.Error | string | undefined : never} body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
* @return {never}
* @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling.
* @throws {Error} If the provided status is invalid (not between 400 and 599).
*/

@@ -35,10 +66,25 @@ export function error(status, body) {

return new HttpError(status, body);
throw new HttpError(status, body);
}
/**
* Create a `Redirect` object. If thrown during request handling, SvelteKit will return a redirect response.
* Checks whether this is an error thrown by {@link error}.
* @template {number} T
* @param {unknown} e
* @param {T} [status] The status to filter for.
* @return {e is (HttpError & { status: T extends undefined ? never : T })}
*/
export function isHttpError(e, status) {
if (!(e instanceof HttpError)) return false;
return !status || e.status === status;
}
/**
* Redirect a request. When called during request handling, SvelteKit will return a redirect response.
* Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it.
* @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
* @param {NumericRange<300, 308>} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
* @param {string | URL} location The location to redirect to.
* @throws {Redirect} This error instructs SvelteKit to redirect to the specified location.
* @throws {Error} If the provided status is invalid.
* @return {never}
*/

@@ -50,6 +96,15 @@ export function redirect(status, location) {

return new Redirect(status, location.toString());
throw new Redirect(status, location.toString());
}
/**
* Checks whether this is a redirect thrown by {@link redirect}.
* @param {unknown} e The object to check.
* @return {e is Redirect}
*/
export function isRedirect(e) {
return e instanceof Redirect;
}
/**
* Create a JSON `Response` object from the supplied data.

@@ -108,55 +163,26 @@ * @param {any} data The value that will be serialized as JSON.

* Create an `ActionFailure` object.
* @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
* @overload
* @param {number} status
* @returns {import('./public.js').ActionFailure<undefined>}
*/
/**
* Create an `ActionFailure` object.
* @template {Record<string, unknown> | undefined} [T=undefined]
* @param {number} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
* @param {T} [data] Data associated with the failure (e.g. validation errors)
* @returns {ActionFailure<T>}
* @param {T} data Data associated with the failure (e.g. validation errors)
* @overload
* @param {number} status
* @param {T} data
* @returns {import('./public.js').ActionFailure<T>}
*/
/**
* Create an `ActionFailure` object.
* @param {number} status
* @param {any} [data]
* @returns {import('./public.js').ActionFailure<any>}
*/
export function fail(status, data) {
// @ts-expect-error unique symbol missing
return new ActionFailure(status, data);
}
const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
/**
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
* resolvePath(
* `/blog/[slug]/[...somethingElse]`,
* {
* slug: 'hello-world',
* somethingElse: 'something/else'
* }
* ); // `/blog/hello-world/something/else`
* ```
* @param {string} id
* @param {Record<string, string | undefined>} params
* @returns {string}
*/
export function resolvePath(id, params) {
const segments = get_route_segments(id);
return (
'/' +
segments
.map((segment) =>
segment.replace(basic_param_pattern, (_, optional, rest, name) => {
const param_value = params[name];
// This is nested so TS correctly narrows the type
if (!param_value) {
if (optional) return '';
if (rest && param_value !== undefined) return '';
throw new Error(`Missing parameter '${name}' in route ${id}`);
}
if (param_value.startsWith('/') || param_value.endsWith('/'))
throw new Error(
`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
);
return param_value;
})
)
.filter(Boolean)
.join('/')
);
}
import * as set_cookie_parser from 'set-cookie-parser';
import { error } from '../index.js';
import { SvelteKitError } from '../../runtime/control.js';

@@ -25,15 +25,2 @@ /**

let length = content_length;
if (body_size_limit) {
if (!length) {
length = body_size_limit;
} else if (length > body_size_limit) {
throw error(
413,
`Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`
);
}
}
if (req.destroyed) {

@@ -50,2 +37,13 @@ const readable = new ReadableStream();

start(controller) {
if (body_size_limit !== undefined && content_length > body_size_limit) {
const error = new SvelteKitError(
413,
'Payload Too Large',
`Content-length of ${content_length} exceeds limit of ${body_size_limit} bytes.`
);
controller.error(error);
return;
}
req.on('error', (error) => {

@@ -65,12 +63,11 @@ cancelled = true;

size += chunk.length;
if (size > length) {
if (size > content_length) {
cancelled = true;
controller.error(
error(
413,
`request body size exceeded ${
content_length ? "'content-length'" : 'BODY_SIZE_LIMIT'
} of ${length}`
)
);
const constraint = content_length ? 'content-length' : 'BODY_SIZE_LIMIT';
const message = `request body size exceeded ${constraint} of ${content_length}`;
const error = new SvelteKitError(413, 'Payload Too Large', message);
controller.error(error);
return;

@@ -130,3 +127,3 @@ }

/** @type {string}*/ (response.headers.get(key))
)
)
: value

@@ -133,0 +130,0 @@ );

@@ -1,11 +0,9 @@

import { ReadableStream, TransformStream, WritableStream } from 'node:stream/web';
import buffer from 'node:buffer';
import { webcrypto as crypto } from 'node:crypto';
import { fetch, Response, Request, Headers, FormData, File as UndiciFile } from 'undici';
// `buffer.File` was added in Node 18.13.0 while the `File` global was added in Node 20.0.0
const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File ?? UndiciFile;
const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File;
/** @type {Record<string, any>} */
const globals_post_node_18_11 = {
const globals = {
crypto,

@@ -15,17 +13,2 @@ File

/** @type {Record<string, any>} */
// TODO: remove this once we only support Node 18.11+ (the version multipart/form-data was added)
const globals_pre_node_18_11 = {
crypto,
fetch,
Response,
Request,
Headers,
ReadableStream,
TransformStream,
WritableStream,
FormData,
File
};
// exported for dev/preview and node environments

@@ -35,20 +18,8 @@ /**

* - `crypto`
* - `fetch` (only in node < 18.11)
* - `Headers` (only in node < 18.11)
* - `Request` (only in node < 18.11)
* - `Response` (only in node < 18.11)
* - `File`
*/
export function installPolyfills() {
// Be defensive (we don't know in which environments this is called) and always apply if something goes wrong
let globals = globals_pre_node_18_11;
try {
const version = process.versions.node.split('.').map((n) => parseInt(n, 10));
if ((version[0] === 18 && version[1] >= 11) || version[0] > 18) {
globals = globals_post_node_18_11;
}
} catch (e) {
// ignore
}
for (const name in globals) {
if (name in globalThis) continue;
for (const name in globals) {
Object.defineProperty(globalThis, name, {

@@ -55,0 +26,0 @@ enumerable: true,

@@ -5,3 +5,3 @@ import 'svelte'; // pick up `declare module "*.svelte"`

import { CompileOptions } from 'svelte/types/compiler/interfaces';
import { CompileOptions } from 'svelte/compiler';
import {

@@ -21,3 +21,2 @@ AdapterEntry,

} from '../types/private.js';
import { ActionFailure } from '../runtime/control.js';
import { BuildData, SSRNodeLoader, SSRRoute, ValidatedConfig } from 'types';

@@ -27,3 +26,2 @@ import type { PluginOptions } from '@sveltejs/vite-plugin-svelte';

export { PrerenderOption } from '../types/private.js';
export { ActionFailure };

@@ -45,17 +43,8 @@ /**

type AwaitedPropertiesUnion<input extends Record<string, any> | void> = input extends void
export type LoadProperties<input extends Record<string, any> | void> = input extends void
? undefined // needs to be undefined, because void will break intellisense
: input extends Record<string, any>
? {
[key in keyof input]: Awaited<input[key]>;
}
: {} extends input // handles the any case
? input
: unknown;
? input
: unknown;
export type AwaitedProperties<input extends Record<string, any> | void> =
AwaitedPropertiesUnion<input> extends Record<string, any>
? OptionalUnion<AwaitedPropertiesUnion<input>>
: AwaitedPropertiesUnion<input>;
export type AwaitedActions<T extends Record<string, (...args: any) => any>> = OptionalUnion<

@@ -74,7 +63,15 @@ {

declare const uniqueSymbol: unique symbol;
export interface ActionFailure<T extends Record<string, unknown> | undefined = undefined> {
status: number;
data: T;
[uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure
}
type UnpackValidationError<T> = T extends ActionFailure<infer X>
? X
: T extends void
? undefined // needs to be undefined, because void will corrupt union type
: T;
? undefined // needs to be undefined, because void will corrupt union type
: T;

@@ -113,2 +110,7 @@ /**

/**
* Generate a module exposing build-time environment variables as `$env/dynamic/public`.
*/
generateEnvModule(): void;
/**
* Generate a server-side manifest to initialise the SvelteKit [server](https://kit.svelte.dev/docs/types#public-types-server) with.

@@ -221,3 +223,3 @@ * @param opts a relative path to the base directory of the app and optionally in which format (esm or cjs) the manifest should be generated

*
* By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.
* You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
* @param name the name of the cookie

@@ -227,3 +229,7 @@ * @param value the cookie value

*/
set(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): void;
set(
name: string,
value: string,
opts: import('cookie').CookieSerializeOptions & { path: string }
): void;

@@ -233,7 +239,7 @@ /**

*
* By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.
* You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
* @param name the name of the cookie
* @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options)
*/
delete(name: string, opts?: import('cookie').CookieSerializeOptions): void;
delete(name: string, opts: import('cookie').CookieSerializeOptions & { path: string }): void;

@@ -245,3 +251,3 @@ /**

*
* By default, the `path` of a cookie is the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.
* You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children
*

@@ -252,3 +258,7 @@ * @param name the name of the cookie

*/
serialize(name: string, value: string, opts?: import('cookie').CookieSerializeOptions): string;
serialize(
name: string,
value: string,
opts: import('cookie').CookieSerializeOptions & { path: string }
): string;
}

@@ -293,3 +303,5 @@

/**
* The directory relative to `paths.assets` where the built JS and CSS (and imported assets) are served from. (The filenames therein contain content-based hashes, meaning they can be cached indefinitely). Must not start or end with `/`.
* The directory where SvelteKit keeps its stuff, including static assets (such as JS and CSS) and internally-used routes.
*
* If `paths.assets` is specified, there will be two app directories — `${paths.assets}/${appDir}` and `${paths.base}/${appDir}`.
* @default "_app"

@@ -359,12 +371,2 @@ */

/**
* Here be dragons. Enable at your peril.
*/
dangerZone?: {
/**
* Automatically add server-side `fetch`ed URLs to the `dependencies` map of `load` functions. This will expose secrets
* to the client if your URL contains them.
*/
trackServerFetches?: boolean;
};
/**
* Whether or not the app is embedded inside a larger app. If `true`, SvelteKit will add its event listeners related to navigation etc on the parent of `%sveltekit.body%` instead of `window`, and will pass `params` from the server rather than inferring them from `location.pathname`.

@@ -489,11 +491,16 @@ * @default false

/**
* Whether to use relative asset paths. By default, if `paths.assets` is not external, SvelteKit will replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` will be as specified in your config.
* Whether to use relative asset paths.
*
* If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in portable HTML.
* If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in more portable HTML.
* If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL
*
* [Single-page app](https://kit.svelte.dev/docs/single-page-apps) fallback pages will always use absolute paths, regardless of this setting.
*
* If your app uses a `<base>` element, you should set this to `false`, otherwise asset URLs will incorrectly be resolved against the `<base>` URL rather than the current page.
* @default undefined
*
* In 1.0, `undefined` was a valid value, which was set by default. In that case, if `paths.assets` was not external, SvelteKit would replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` would be as specified in your config.
*
* @default true
*/
relative?: boolean | undefined;
relative?: boolean;
};

@@ -515,3 +522,3 @@ /**

/**
* An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]`, because SvelteKit doesn't know what value the parameters should have).
* An array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all routes containing no required `[parameters]` with optional parameters included as being empty (since SvelteKit doesn't know what value any parameters should have).
* @default ["*"]

@@ -668,2 +675,4 @@ */

event: RequestEvent;
status: number;
message: string;
}) => MaybePromise<void | App.Error>;

@@ -680,2 +689,4 @@

event: NavigationEvent;
status: number;
message: string;
}) => MaybePromise<void | App.Error>;

@@ -799,3 +810,17 @@

*/
depends(...deps: string[]): void;
depends(...deps: Array<`${string}:${string}`>): void;
/**
* Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example:
*
* ```js
* /// file: src/routes/+page.server.js
* export async function load({ untrack, url }) {
* // Untrack url.pathname so that path changes don't trigger a rerun
* if (untrack(() => url.pathname === '/')) {
* return { message: 'Welcome!' };
* }
* }
* ```
*/
untrack<T>(fn: () => T): T;
}

@@ -867,3 +892,3 @@

* - `form`: The user submitted a `<form>`
* - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document
* - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring
* - `link`: Navigation was triggered by a link click

@@ -973,2 +998,6 @@ * - `goto`: Navigation was triggered by a `goto(...)` call or a redirect

/**
* The page state, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`.
*/
state: App.PageState;
/**
* Filled only after a form submission. See [form actions](https://kit.svelte.dev/docs/form-actions) for more info.

@@ -1204,2 +1233,16 @@ */

depends(...deps: string[]): void;
/**
* Use this function to opt out of dependency tracking for everything that is synchronously called within the callback. Example:
*
* ```js
* /// file: src/routes/+page.js
* export async function load({ untrack, url }) {
* // Untrack url.pathname so that path changes don't trigger a rerun
* if (untrack(() => url.pathname === '/')) {
* return { message: 'Welcome!' };
* }
* }
* ```
*/
untrack<T>(fn: () => T): T;
}

@@ -1271,13 +1314,3 @@

action: URL;
/**
* use `formData` instead of `data`
* @deprecated
*/
data: FormData;
formData: FormData;
/**
* use `formElement` instead of `form`
* @deprecated
*/
form: HTMLFormElement;
formElement: HTMLFormElement;

@@ -1290,13 +1323,3 @@ controller: AbortController;

| ((opts: {
/**
* use `formData` instead of `data`
* @deprecated
*/
data: FormData;
formData: FormData;
/**
* use `formElement` instead of `form`
* @deprecated
*/
form: HTMLFormElement;
formElement: HTMLFormElement;

@@ -1303,0 +1326,0 @@ action: URL;

@@ -6,3 +6,2 @@ import fs from 'node:fs';

import { get_config_aliases } from '../utils.js';
import { assets_base } from './utils.js';

@@ -68,12 +67,13 @@ /**

await vite.build({
base: assets_base(kit),
build: {
lib: {
entry: /** @type {string} */ (service_worker_entry_file),
name: 'app',
formats: ['es']
},
modulePreload: false,
rollupOptions: {
input: {
'service-worker': service_worker_entry_file
},
output: {
entryFileNames: 'service-worker.js'
// .mjs so that esbuild doesn't incorrectly inject `export` https://github.com/vitejs/vite/issues/15379
entryFileNames: 'service-worker.mjs',
assetFileNames: `${kit.appDir}/immutable/assets/[name].[hash][extname]`,
inlineDynamicImports: true
}

@@ -89,4 +89,14 @@ },

alias: [...get_config_aliases(kit), { find: '$service-worker', replacement: service_worker }]
},
experimental: {
renderBuiltUrl(filename) {
return {
runtime: `new URL(${JSON.stringify(filename)}, location.href).pathname`
};
}
}
});
// rename .mjs to .js to avoid incorrect MIME types with ancient webservers
fs.renameSync(`${out}/client/service-worker.mjs`, `${out}/client/service-worker.js`);
}

@@ -86,3 +86,14 @@ import fs from 'node:fs';

const method_names = new Set(['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH', 'OPTIONS']);
// If we'd written this in TypeScript, it could be easy...
/**
* @param {string} str
* @returns {str is import('types').HttpMethod}
*/
export function is_http_method(str) {
return method_names.has(str);
}
/**
* @param {import('types').ValidatedKitConfig} config

@@ -89,0 +100,0 @@ * @returns {string}

@@ -11,3 +11,2 @@ import fs from 'node:fs';

import { posixify, resolve_entry, to_fs } from '../../../utils/filesystem.js';
import { should_polyfill } from '../../../utils/platform.js';
import { load_error_page } from '../../../core/config/index.js';

@@ -30,5 +29,3 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js';

export async function dev(vite, vite_config, svelte_config) {
if (should_polyfill) {
installPolyfills();
}
installPolyfills();

@@ -128,3 +125,4 @@ const fetch = globalThis.fetch;

stylesheets: [],
fonts: []
fonts: [],
uses_env_dynamic_public: true
},

@@ -229,3 +227,3 @@ nodes: manifest_data.nodes.map((node, index) => {

return await loud_ssr_load_module(url);
}
}
: null,

@@ -364,3 +362,4 @@ endpoint_id: endpoint?.file

HttpError: control_module_vite.HttpError,
Redirect: control_module_vite.Redirect
Redirect: control_module_vite.Redirect,
SvelteKitError: control_module_vite.SvelteKitError
});

@@ -481,14 +480,7 @@ }

let request;
const request = await getRequest({
base,
request: req
});
try {
request = await getRequest({
base,
request: req
});
} catch (/** @type {any} */ err) {
res.statusCode = err.status || 400;
return res.end('Invalid request body');
}
if (manifest_error) {

@@ -546,3 +538,3 @@ console.error(colors.bold().red(manifest_error.message));

function remove_static_middlewares(server) {
const static_middlewares = ['viteServeStaticMiddleware'];
const static_middlewares = ['viteServeStaticMiddleware', 'viteServePublicMiddleware'];
for (let i = server.stack.length - 1; i > 0; i--) {

@@ -549,0 +541,0 @@ // @ts-expect-error using internals

import path from 'node:path';
import { posixify } from '../../../utils/filesystem.js';
import { strip_virtual_prefix } from '../utils.js';
import { env_dynamic_private, env_static_private } from '../module_ids.js';
const ILLEGAL_IMPORTS = new Set([
'\0virtual:$env/dynamic/private',
'\0virtual:$env/static/private'
]);
const ILLEGAL_IMPORTS = new Set([env_dynamic_private, env_static_private]);
const ILLEGAL_MODULE_NAME_PATTERN = /.*\.server\..+/;

@@ -10,0 +8,0 @@

@@ -28,5 +28,12 @@ import fs from 'node:fs';

import { dedent, isSvelte5Plus } from '../../core/sync/utils.js';
import {
env_dynamic_private,
env_dynamic_public,
env_static_private,
env_static_public,
service_worker,
sveltekit_environment,
sveltekit_paths
} from './module_ids.js';
export { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const cwd = process.cwd();

@@ -76,3 +83,3 @@

/** @type {import('@sveltejs/vite-plugin-svelte').PreprocessorGroup} */
/** @type {import('svelte/compiler').PreprocessorGroup} */
const warning_preprocessor = {

@@ -103,6 +110,10 @@ script: ({ content, filename }) => {

const basename = path.basename(filename);
if (basename.startsWith('+layout.') && !content.includes('<slot')) {
const has_children =
content.includes('<slot') || (isSvelte5Plus() && content.includes('{@render'));
if (basename.startsWith('+layout.') && !has_children) {
const message =
`\n${colors.bold().red(path.relative('.', filename))}\n` +
'`<slot />` missing — inner content will not be rendered';
`\`<slot />\`${isSvelte5Plus() ? ' or `{@render ...}` tag' : ''}` +
' missing — inner content will not be rendered';

@@ -328,6 +339,2 @@ if (!warned.has(message)) {

vite_config = config;
// This is a hack to prevent Vite from nuking useful logs,
// pending https://github.com/vitejs/vite/issues/9378
config.logger.warn('');
}

@@ -370,9 +377,9 @@ };

switch (id) {
case '\0virtual:$env/static/private':
case env_static_private:
return create_static_module('$env/static/private', env.private);
case '\0virtual:$env/static/public':
case env_static_public:
return create_static_module('$env/static/public', env.public);
case '\0virtual:$env/dynamic/private':
case env_dynamic_private:
return create_dynamic_module(

@@ -383,6 +390,6 @@ 'private',

case '\0virtual:$env/dynamic/public':
case env_dynamic_public:
// populate `$env/dynamic/public` from `window`
if (browser) {
return `export const env = ${global}.env;`;
return `export const env = ${global}.env ?? (await import(/* @vite-ignore */ ${global}.base + '/' + '${kit.appDir}/env.js')).env;`;
}

@@ -395,3 +402,3 @@

case '\0virtual:$service-worker':
case service_worker:
return create_service_worker_module(svelte_config);

@@ -401,3 +408,3 @@

// we use this alias so that we won't collide with user aliases
case '\0virtual:__sveltekit/paths': {
case sveltekit_paths: {
const { assets, base } = svelte_config.kit.paths;

@@ -440,3 +447,3 @@

case '\0virtual:__sveltekit/environment': {
case sveltekit_environment: {
const { version } = svelte_config.kit;

@@ -447,2 +454,3 @@

export let building = false;
export let prerendering = false;

@@ -452,2 +460,6 @@ export function set_building() {

}
export function set_prerendering() {
prerendering = true;
}
`;

@@ -584,3 +596,3 @@ }

ssrEmitAssets: true,
target: ssr ? 'node16.14' : undefined
target: ssr ? 'node18.13' : 'es2022'
},

@@ -753,3 +765,6 @@ publicDir: kit.files.assets,

stylesheets: [...start.stylesheets, ...app.stylesheets],
fonts: [...start.fonts, ...app.fonts]
fonts: [...start.fonts, ...app.fonts],
uses_env_dynamic_public: output.some(
(chunk) => chunk.type === 'chunk' && chunk.modules[env_dynamic_public]
)
};

@@ -756,0 +771,0 @@

@@ -10,3 +10,2 @@ import fs from 'node:fs';

import { SVELTE_KIT_ASSETS } from '../../../constants.js';
import { should_polyfill } from '../../../utils/platform.js';
import { not_found } from '../utils.js';

@@ -24,5 +23,3 @@

export async function preview(vite, vite_config, svelte_config) {
if (should_polyfill) {
installPolyfills();
}
installPolyfills();

@@ -59,2 +56,14 @@ const { paths } = svelte_config.kit;

return () => {
// Remove the base middleware. It screws with the URL.
// It also only lets through requests beginning with the base path, so that requests beginning
// with the assets URL never reach us. We could serve assets separately before the base
// middleware, but we'd need that to occur after the compression and cors middlewares, so would
// need to insert it manually into the stack, which would be at least as bad as doing this.
for (let i = vite.middlewares.stack.length - 1; i > 0; i--) {
// @ts-expect-error using internals
if (vite.middlewares.stack[i].handle.name === 'viteBaseMiddleware') {
vite.middlewares.stack.splice(i, 1);
}
}
// generated client assets and the contents of `static`

@@ -77,4 +86,16 @@ vite.middlewares.use(

const original_url = /** @type {string} */ (req.url);
const { pathname } = new URL(original_url, 'http://dummy');
const { pathname, search } = new URL(original_url, 'http://dummy');
// if `paths.base === '/a/b/c`, then the root route is `/a/b/c/`,
// regardless of the `trailingSlash` route option
if (base.length > 1 && pathname === base) {
let location = base + '/';
if (search) location += search;
res.writeHead(307, {
location
});
res.end();
return;
}
if (pathname.startsWith(base)) {

@@ -109,3 +130,3 @@ next();

const { pathname } = new URL(/** @type {string} */ (req.url), 'http://dummy');
const { pathname, search } = new URL(/** @type {string} */ (req.url), 'http://dummy');

@@ -121,2 +142,3 @@ let filename = normalizePath(

/** @type {string | undefined} */
let redirect;

@@ -136,2 +158,3 @@

if (redirect) {
if (search) redirect += search;
res.writeHead(307, {

@@ -164,14 +187,7 @@ location: redirect

let request;
const request = await getRequest({
base: `${protocol}://${host}`,
request: req
});
try {
request = await getRequest({
base: `${protocol}://${host}`,
request: req
});
} catch (/** @type {any} */ err) {
res.statusCode = err.status || 400;
return res.end('Invalid request body');
}
setResponse(

@@ -201,3 +217,3 @@ res,

maxAge: 0
})
})
: (_req, _res, next) => next();

@@ -204,0 +220,0 @@

@@ -53,16 +53,2 @@ import * as devalue from 'devalue';

/**
* @param {string} old_name
* @param {string} new_name
* @param {string} call_location
* @returns void
*/
function warn_on_access(old_name, new_name, call_location) {
if (!DEV) return;
// TODO 2.0: Remove this code
console.warn(
`\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})`
);
}
/**
* Shallow clone an element, so that we can access e.g. `form.action` without worrying

@@ -161,7 +147,5 @@ * that someone has added an `<input name="action">` (https://github.com/sveltejs/kit/issues/7593)

if (value instanceof File) {
// TODO 2.0: Upgrade to `throw Error`
console.warn(
'Your form contains <input type="file"> fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.'
throw new Error(
'Your form contains <input type="file"> fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.'
);
break;
}

@@ -181,3 +165,2 @@ }

// TODO 2.0: Remove `data` and `form`
const callback =

@@ -188,11 +171,3 @@ (await submit({

controller,
get data() {
warn_on_access('data', 'formData', 'use:enhance submit function');
return form_data;
},
formData: form_data,
get form() {
warn_on_access('form', 'formElement', 'use:enhance submit function');
return form_element;
},
formElement: form_element,

@@ -227,11 +202,3 @@ submitter: event.submitter

action,
get data() {
warn_on_access('data', 'formData', 'callback returned from use:enhance submit function');
return form_data;
},
formData: form_data,
get form() {
warn_on_access('form', 'formElement', 'callback returned from use:enhance submit function');
return form_element;
},
formElement: form_element,

@@ -238,0 +205,0 @@ update: (opts) =>

@@ -14,9 +14,3 @@ import { client_method } from '../client/singletons.js';

*
* @type {(url: string | URL, opts?: {
* replaceState?: boolean;
* noScroll?: boolean;
* keepFocus?: boolean;
* invalidateAll?: boolean;
* state?: any
* }) => Promise<void>}
* @type {(url: string | URL, opts?: { replaceState?: boolean; noScroll?: boolean; keepFocus?: boolean; invalidateAll?: boolean; state?: App.PageState }) => Promise<void>}
* @param {string | URL} url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://kit.svelte.dev/docs/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app.

@@ -27,4 +21,4 @@ * @param {Object} [opts] Options related to the navigation

* @param {boolean} [opts.keepFocus] If `true`, the currently focused element will retain focus after navigation. Otherwise, focus will be reset to the body
* @param {boolean} [invalidateAll] If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#rerunning-load-functions for more info on invalidation.
* @param {any} [opts.state] The state of the new/updated history entry
* @param {boolean} [opts.invalidateAll] If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#rerunning-load-functions for more info on invalidation.
* @param {App.PageState} [opts.state] An optional object that will be available on the `$page.state` store
* @returns {Promise<void>}

@@ -69,7 +63,7 @@ */

* If the next navigation is to `href`, the values returned from load will be used, making navigation instantaneous.
* Returns a Promise that resolves when the preload is complete.
* Returns a Promise that resolves with the result of running the new route's `load` functions once the preload is complete.
*
* @type {(href: string) => Promise<void>}
* @type {(href: string) => Promise<Record<string, any>>}
* @param {string} href Page to preload
* @returns {Promise<void>}
* @returns {Promise<{ type: 'loaded'; status: number; data: Record<string, any> } | { type: 'redirect'; location: string }>}
*/

@@ -87,4 +81,4 @@ export const preloadData = /* @__PURE__ */ client_method('preload_data');

*
* @type {(...urls: string[]) => Promise<void>}
* @param {...string[]} urls
* @type {(url: string) => Promise<void>}
* @param {string} url
* @returns {Promise<void>}

@@ -96,7 +90,9 @@ */

* A navigation interceptor that triggers before we navigate to a new URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls.
* Calling `cancel()` will prevent the navigation from completing. If the navigation would have directly unloaded the current page, calling `cancel` will trigger the native
* browser unload confirmation dialog. In these cases, `navigation.willUnload` is `true`.
*
* When a navigation isn't client side, `navigation.to.route.id` will be `null`.
* Calling `cancel()` will prevent the navigation from completing. If `navigation.type === 'leave'` — meaning the user is navigating away from the app (or closing the tab) — calling `cancel` will trigger the native browser unload confirmation dialog. In this case, the navigation may or may not be cancelled depending on the user's response.
*
* When a navigation isn't to a SvelteKit-owned route (and therefore controlled by SvelteKit's client-side router), `navigation.to.route.id` will be `null`.
*
* If the navigation will (if not cancelled) cause the document to unload — in other words `'leave'` navigations and `'link'` navigations where `navigation.to.route === null` — `navigation.willUnload` is `true`.
*
* `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted.

@@ -110,3 +106,3 @@ * @type {(callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void) => void}

/**
* A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL.
* A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations.
*

@@ -118,3 +114,3 @@ * If you return a `Promise`, SvelteKit will wait for it to resolve before completing the navigation. This allows you to — for example — use `document.startViewTransition`. Avoid promises that are slow to resolve, since navigation will appear stalled to the user.

* `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted.
* @type {(callback: (navigation: import('@sveltejs/kit').OnNavigate) => import('../../types/internal.js').MaybePromise<(() => void) | void>) => void}
* @type {(callback: (navigation: import('@sveltejs/kit').OnNavigate) => import('types').MaybePromise<(() => void) | void>) => void}
* @param {(navigation: import('@sveltejs/kit').OnNavigate) => void} callback

@@ -134,1 +130,21 @@ * @returns {void}

export const afterNavigate = /* @__PURE__ */ client_method('after_navigate');
/**
* Programmatically create a new history entry with the given `$page.state`. To use the current URL, you can pass `''` as the first argument. Used for [shallow routing](https://kit.svelte.dev/docs/shallow-routing).
*
* @type {(url: string | URL, state: App.PageState) => void}
* @param {string | URL} url
* @param {App.PageState} state
* @returns {void}
*/
export const pushState = /* @__PURE__ */ client_method('push_state');
/**
* Programmatically replace the current history entry with the given `$page.state`. To use the current URL, you can pass `''` as the first argument. Used for [shallow routing](https://kit.svelte.dev/docs/shallow-routing).
*
* @type {(url: string | URL, state: App.PageState) => void}
* @param {string | URL} url
* @param {App.PageState} state
* @returns {void}
*/
export const replaceState = /* @__PURE__ */ client_method('replace_state');
export { base, assets } from '__sveltekit/paths';
import { base } from '__sveltekit/paths';
import { resolve_route } from '../../utils/routing.js';
/**
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
* resolveRoute(
* `/blog/[slug]/[...somethingElse]`,
* {
* slug: 'hello-world',
* somethingElse: 'something/else'
* }
* ); // `/blog/hello-world/something/else`
* ```
* @param {string} id
* @param {Record<string, string | undefined>} params
* @returns {string}
*/
export function resolveRoute(id, params) {
return base + resolve_route(id, params);
}
export const SNAPSHOT_KEY = 'sveltekit:snapshot';
export const SCROLL_KEY = 'sveltekit:scroll';
export const INDEX_KEY = 'sveltekit:index';
export const STATES_KEY = 'sveltekit:states';
export const PAGE_URL_KEY = 'sveltekit:pageurl';
export const HISTORY_INDEX = 'sveltekit:history';
export const NAVIGATION_INDEX = 'sveltekit:navigation';
export const PRELOAD_PRIORITIES = /** @type {const} */ ({

@@ -10,3 +14,4 @@ tap: 1,

eager: 4,
off: -1
off: -1,
false: -1
});

@@ -79,2 +79,18 @@ import { DEV } from 'esm-env';

/**
* @param {string} text
* @returns {ArrayBufferLike}
*/
function b64_decode(text) {
const d = atob(text);
const u8 = new Uint8Array(d.length);
for (let i = 0; i < d.length; i++) {
u8[i] = d.charCodeAt(i);
}
return u8.buffer;
}
/**
* Should be called on the initial run of load functions that hydrate the page.

@@ -90,6 +106,12 @@ * Saves any requests with cache-control max-age to the cache.

if (script?.textContent) {
const { body, ...init } = JSON.parse(script.textContent);
let { body, ...init } = JSON.parse(script.textContent);
const ttl = script.getAttribute('data-ttl');
if (ttl) cache.set(selector, { body, init, ttl: 1000 * Number(ttl) });
const b64 = script.getAttribute('data-b64');
if (b64 !== null) {
// Can't use native_fetch('data:...;base64,${body}')
// csp can block the request
body = b64_decode(body);
}

@@ -96,0 +118,0 @@ return Promise.resolve(new Response(body, init));

/**
* Read a value from `sessionStorage`
* @param {string} key
* @param {(value: string) => any} parse
*/
export function get(key) {
export function get(key, parse = JSON.parse) {
try {
return JSON.parse(sessionStorage[key]);
return parse(sessionStorage[key]);
} catch {

@@ -17,7 +18,8 @@ // do nothing

* @param {any} value
* @param {(value: any) => string} stringify
*/
export function set(key, value) {
const json = JSON.stringify(value);
export function set(key, value, stringify = JSON.stringify) {
const data = stringify(value);
try {
sessionStorage[key] = json;
sessionStorage[key] = data;
} catch {

@@ -24,0 +26,0 @@ // do nothing

@@ -24,3 +24,9 @@ import { writable } from 'svelte/store';

if (!BROWSER) {
if (key === 'before_navigate' || key === 'after_navigate' || key === 'on_navigate') {
if (
key === 'before_navigate' ||
key === 'after_navigate' ||
key === 'on_navigate' ||
key === 'push_state' ||
key === 'replace_state'
) {
// @ts-expect-error doesn't recognize that both keys here return void so expects a async function

@@ -27,0 +33,0 @@ return () => {};

@@ -10,3 +10,5 @@ import { applyAction } from '../app/forms.js';

preloadCode,
preloadData
preloadData,
pushState,
replaceState
} from '../app/navigation.js';

@@ -55,2 +57,4 @@ import { SvelteComponent } from 'svelte';

preload_data: typeof preloadData;
push_state: typeof pushState;
replace_state: typeof replaceState;
apply_action: typeof applyAction;

@@ -97,3 +101,3 @@

components?: Array<SvelteComponent>;
page?: Page;
page: Page;
form?: Record<string, any> | null;

@@ -100,0 +104,0 @@ [key: `data_${number}`]: Record<string, any>;

@@ -11,12 +11,14 @@ import { BROWSER, DEV } from 'esm-env';

/** @param {HTMLDocument} doc */
export function get_base_uri(doc) {
let baseURI = doc.baseURI;
/** @param {string | URL} url */
export function resolve_url(url) {
if (url instanceof URL) return url;
let baseURI = document.baseURI;
if (!baseURI) {
const baseTags = doc.getElementsByTagName('base');
baseURI = baseTags.length ? baseTags[0].href : doc.URL;
const baseTags = document.getElementsByTagName('base');
baseURI = baseTags.length ? baseTags[0].href : document.URL;
}
return baseURI;
return new URL(url, baseURI);
}

@@ -36,4 +38,4 @@

const valid_link_options = /** @type {const} */ ({
'preload-code': ['', 'off', 'tap', 'hover', 'viewport', 'eager'],
'preload-data': ['', 'off', 'tap', 'hover'],
'preload-code': ['', 'off', 'false', 'tap', 'hover', 'viewport', 'eager'],
'preload-data': ['', 'off', 'false', 'tap', 'hover'],
keepfocus: ['', 'true', 'off', 'false'],

@@ -152,3 +154,3 @@ noscroll: ['', 'true', 'off', 'false'],

/** @type {ValidLinkOptions<'keepfocus'> | null} */
let keep_focus = null;
let keepfocus = null;

@@ -176,3 +178,3 @@ /** @type {ValidLinkOptions<'noscroll'> | null} */

if (preload_data === null) preload_data = link_option(el, 'preload-data');
if (keep_focus === null) keep_focus = link_option(el, 'keepfocus');
if (keepfocus === null) keepfocus = link_option(el, 'keepfocus');
if (noscroll === null) noscroll = link_option(el, 'noscroll');

@@ -195,3 +197,3 @@ if (reload === null) reload = link_option(el, 'reload');

default:
return null;
return undefined;
}

@@ -203,3 +205,3 @@ }

preload_data: levels[preload_data ?? 'off'],
keep_focus: get_option_state(keep_focus),
keepfocus: get_option_state(keepfocus),
noscroll: get_option_state(noscroll),

@@ -206,0 +208,0 @@ reload: get_option_state(reload),

@@ -34,2 +34,20 @@ export class HttpError {

/**
* An error that was thrown from within the SvelteKit runtime that is not fatal and doesn't result in a 500, such as a 404.
* `SvelteKitError` goes through `handleError`.
* @extends Error
*/
export class SvelteKitError extends Error {
/**
* @param {number} status
* @param {string} text
* @param {string} message
*/
constructor(status, text, message) {
super(message);
this.status = status;
this.text = text;
}
}
/**
* @template {Record<string, unknown> | undefined} [T=undefined]

@@ -40,3 +58,3 @@ */

* @param {number} status
* @param {T} [data]
* @param {T} data
*/

@@ -59,2 +77,3 @@ constructor(status, data) {

* Redirect: typeof Redirect;
* SvelteKitError: typeof SvelteKitError;
* }} implementations

@@ -69,2 +88,4 @@ */

Redirect = implementations.Redirect; // eslint-disable-line no-class-assign
// @ts-expect-error
SvelteKitError = implementations.SvelteKitError; // eslint-disable-line no-class-assign
}
import { parse, serialize } from 'cookie';
import { normalize_path } from '../../utils/url.js';
import { add_data_suffix, normalize_path, resolve } from '../../utils/url.js';

@@ -17,2 +17,10 @@ /**

// TODO 3.0 remove this check
/** @param {import('./page/types.js').Cookie['options']} options */
function validate_options(options) {
if (options?.path === undefined) {
throw new Error('You must specify a `path` when setting, deleting or serializing cookies');
}
}
/**

@@ -28,4 +36,2 @@ * @param {Request} request

const normalized_url = normalize_path(url.pathname, trailing_slash);
// Emulate browser-behavior: if the cookie is set at '/foo/bar', its path is '/foo'
const default_path = normalized_url.split('/').slice(0, -1).join('/') || '/';

@@ -109,6 +115,7 @@ /** @type {Record<string, import('./page/types.js').Cookie>} */

* @param {string} value
* @param {import('cookie').CookieSerializeOptions} opts
* @param {import('./page/types.js').Cookie['options']} options
*/
set(name, value, opts = {}) {
set_internal(name, value, { ...defaults, ...opts });
set(name, value, options) {
validate_options(options);
set_internal(name, value, { ...defaults, ...options });
},

@@ -118,9 +125,7 @@

* @param {string} name
* @param {import('cookie').CookieSerializeOptions} opts
* @param {import('./page/types.js').Cookie['options']} options
*/
delete(name, opts = {}) {
cookies.set(name, '', {
...opts,
maxAge: 0
});
delete(name, options) {
validate_options(options);
cookies.set(name, '', { ...options, maxAge: 0 });
},

@@ -131,9 +136,14 @@

* @param {string} value
* @param {import('cookie').CookieSerializeOptions} opts
* @param {import('./page/types.js').Cookie['options']} options
*/
serialize(name, value, opts) {
return serialize(name, value, {
...defaults,
...opts
});
serialize(name, value, options) {
validate_options(options);
let path = options.path;
if (!options.domain || options.domain === url.hostname) {
path = resolve(normalized_url, path);
}
return serialize(name, value, { ...defaults, ...options, path });
}

@@ -179,16 +189,13 @@ };

* @param {string} value
* @param {import('cookie').CookieSerializeOptions} opts
* @param {import('./page/types.js').Cookie['options']} options
*/
function set_internal(name, value, opts) {
const path = opts.path ?? default_path;
function set_internal(name, value, options) {
let path = options.path;
new_cookies[name] = {
name,
value,
options: {
...opts,
path
}
};
if (!options.domain || options.domain === url.hostname) {
path = resolve(normalized_url, path);
}
new_cookies[name] = { name, value, options: { ...options, path } };
if (__SVELTEKIT_DEV__) {

@@ -247,2 +254,10 @@ const serialized = serialize(name, value, new_cookies[name].options);

headers.append('set-cookie', serialize(name, value, options));
// special case — for routes ending with .html, the route data lives in a sibling
// `.html__data.json` file rather than a child `/__data.json` file, which means
// we need to duplicate the cookie
if (options.path.endsWith('.html')) {
const path = add_data_suffix(options.path);
headers.append('set-cookie', serialize(name, value, { ...options, path }));
}
}

@@ -249,0 +264,0 @@ }

@@ -1,2 +0,2 @@

import { HttpError, Redirect } from '../../control.js';
import { HttpError, SvelteKitError, Redirect } from '../../control.js';
import { normalize_error } from '../../../utils/error.js';

@@ -79,4 +79,3 @@ import { once } from '../../../utils/functions.js';

return data;
},
track_server_fetches: options.track_server_fetches
}
});

@@ -114,3 +113,6 @@ } catch (e) {

error: await handle_error_and_jsonify(event, options, error),
status: error instanceof HttpError ? error.status : undefined
status:
error instanceof HttpError || error instanceof SvelteKitError
? error.status
: undefined
});

@@ -117,0 +119,0 @@ })

@@ -84,3 +84,3 @@ import { ENDPOINT_METHODS, PAGE_METHODS } from '../../constants.js';

// These methods exist exclusively for endpoints
if (ENDPOINT_METHODS.has(method) && !PAGE_METHODS.has(method)) {
if (ENDPOINT_METHODS.includes(method) && !PAGE_METHODS.includes(method)) {
return true;

@@ -87,0 +87,0 @@ }

@@ -12,3 +12,3 @@ import * as set_cookie_parser from 'set-cookie-parser';

* get_cookie_header: (url: URL, header: string | null) => string;
* set_internal: (name: string, value: string, opts: import('cookie').CookieSerializeOptions) => void;
* set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void;
* }} opts

@@ -18,3 +18,6 @@ * @returns {typeof fetch}

export function create_fetch({ event, options, manifest, state, get_cookie_header, set_internal }) {
return async (info, init) => {
/**
* @type {typeof fetch}
*/
const server_fetch = async (info, init) => {
const original_request = normalize_fetch_input(info, init, event.url);

@@ -28,3 +31,3 @@

return await options.hooks.handleFetch({
return options.hooks.handleFetch({
event,

@@ -137,8 +140,9 @@ request: original_request,

const path = options.path ?? (url.pathname.split('/').slice(0, -1).join('/') || '/');
// options.sameSite is string, something more specific is required - type cast is safe
set_internal(
name,
value,
/** @type {import('cookie').CookieSerializeOptions} */ (options)
);
set_internal(name, value, {
path,
.../** @type {import('cookie').CookieSerializeOptions} */ (options)
});
}

@@ -151,2 +155,11 @@ }

};
// Don't make this function `async`! Otherwise, the user has to `catch` promises they use for streaming responses or else
// it will be an unhandled rejection. Instead, we add a `.catch(() => {})` ourselves below to this from happening.
return (input, init) => {
// See docs in fetch.js for why we need to do this
const response = server_fetch(input, init);
response.catch(() => {});
return response;
};
}

@@ -153,0 +166,0 @@

import { respond } from './respond.js';
import { set_private_env, set_public_env } from '../shared-server.js';
import { set_private_env, set_public_env, set_safe_public_env } from '../shared-server.js';
import { options, get_hooks } from '__SERVER__/internal.js';
import { DEV } from 'esm-env';
import { filter_private_env, filter_public_env } from '../../utils/env.js';
import { prerendering } from '__sveltekit/environment';
/** @type {ProxyHandler<{ type: 'public' | 'private' }>} */
const prerender_env_handler = {
get({ type }, prop) {
throw new Error(
`Cannot read values from $env/dynamic/${type} while prerendering (attempted to read env.${prop.toString()}). Use $env/static/${type} instead`
);
}
};
export class Server {

@@ -30,15 +40,19 @@ /** @type {import('types').SSROptions} */

// been done already.
// set env, in case it's used in initialisation
const prefixes = {
public_prefix: this.#options.env_public_prefix,
private_prefix: this.#options.env_private_prefix
};
const private_env = filter_private_env(env, prefixes);
const public_env = filter_public_env(env, prefixes);
set_private_env(
filter_private_env(env, {
public_prefix: this.#options.env_public_prefix,
private_prefix: this.#options.env_private_prefix
})
prerendering ? new Proxy({ type: 'private' }, prerender_env_handler) : private_env
);
set_public_env(
filter_public_env(env, {
public_prefix: this.#options.env_public_prefix,
private_prefix: this.#options.env_private_prefix
})
prerendering ? new Proxy({ type: 'public' }, prerender_env_handler) : public_env
);
set_safe_public_env(public_env);

@@ -75,9 +89,2 @@ if (!this.#options.hooks) {

async respond(request, options) {
// TODO this should probably have been removed for 1.0 — i think we can get rid of it?
if (!(request instanceof Request)) {
throw new Error(
'The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details'
);
}
return respond(request, this.#options, this.#manifest, {

@@ -84,0 +91,0 @@ ...options,

import * as devalue from 'devalue';
import { error, json } from '../../../exports/index.js';
import { normalize_error } from '../../../utils/error.js';
import { json } from '../../../exports/index.js';
import { get_status, normalize_error } from '../../../utils/error.js';
import { is_form_content_type, negotiate } from '../../../utils/http.js';
import { HttpError, Redirect, ActionFailure } from '../../control.js';
import { HttpError, Redirect, ActionFailure, SvelteKitError } from '../../control.js';
import { handle_error_and_jsonify } from '../utils.js';

@@ -27,4 +27,7 @@

if (!actions) {
// TODO should this be a different error altogether?
const no_actions_error = error(405, 'POST method not allowed. No actions exist for this page');
const no_actions_error = new SvelteKitError(
405,
'Method Not Allowed',
'POST method not allowed. No actions exist for this page'
);
return action_json(

@@ -85,3 +88,3 @@ {

{
status: err instanceof HttpError ? err.status : 500
status: get_status(err)
}

@@ -144,3 +147,7 @@ );

type: 'error',
error: error(405, 'POST method not allowed. No actions exist for this page')
error: new SvelteKitError(
405,
'Method Not Allowed',
'POST method not allowed. No actions exist for this page'
)
};

@@ -204,3 +211,3 @@ }

* @param {NonNullable<import('types').SSRNode['server']['actions']>} actions
* @throws {Redirect | ActionFailure | HttpError | Error}
* @throws {Redirect | HttpError | SvelteKitError | Error}
*/

@@ -223,8 +230,12 @@ async function call_action(event, actions) {

if (!action) {
throw new Error(`No action with name '${name}' found`);
throw new SvelteKitError(404, 'Not Found', `No action with name '${name}' found`);
}
if (!is_form_content_type(event.request)) {
throw new Error(
`Actions expect form-encoded data (received ${event.request.headers.get('content-type')})`
throw new SvelteKitError(
415,
'Unsupported Media Type',
`Form actions expect form-encoded data — received ${event.request.headers.get(
'content-type'
)}`
);

@@ -239,9 +250,7 @@ }

if (data instanceof Redirect) {
throw new Error('Cannot `return redirect(...)` — use `throw redirect(...)` instead');
throw new Error('Cannot `return redirect(...)` — use `redirect(...)` instead');
}
if (data instanceof HttpError) {
throw new Error(
'Cannot `return error(...)` — use `throw error(...)` or `return fail(...)` instead'
);
throw new Error('Cannot `return error(...)` — use `error(...)` or `return fail(...)` instead');
}

@@ -248,0 +257,0 @@ }

import { text } from '../../../exports/index.js';
import { compact } from '../../../utils/array.js';
import { normalize_error } from '../../../utils/error.js';
import { get_status, normalize_error } from '../../../utils/error.js';
import { add_data_suffix } from '../../../utils/url.js';
import { HttpError, Redirect } from '../../control.js';
import { Redirect } from '../../control.js';
import { redirect_response, static_error_page, handle_error_and_jsonify } from '../utils.js';

@@ -68,4 +68,3 @@ import {

if (action_result?.type === 'error') {
const error = action_result.error;
status = error instanceof HttpError ? error.status : 500;
status = get_status(action_result.error);
}

@@ -77,3 +76,3 @@ if (action_result?.type === 'failure') {

const should_prerender_data = nodes.some((node) => node?.server);
const should_prerender_data = nodes.some((node) => node?.server?.load);
const data_pathname = add_data_suffix(event.url.pathname);

@@ -83,3 +82,3 @@

// SvelteKit will erroneously believe that the path has been prerendered,
// causing functions to be omitted from the manifesst generated later
// causing functions to be omitted from the manifest generated later
const should_prerender = get_option(nodes, 'prerender') ?? false;

@@ -105,3 +104,6 @@ if (should_prerender) {

if (get_option(nodes, 'ssr') === false && !state.prerendering) {
// renders an empty 'shell' page if SSR is turned off and if there is
// no server data to prerender. As a result, the load functions and rendering
// only occur client-side.
if (get_option(nodes, 'ssr') === false && !(state.prerendering && should_prerender_data)) {
return await render_response({

@@ -157,4 +159,3 @@ branch: [],

return data;
},
track_server_fetches: options.track_server_fetches
}
});

@@ -230,3 +231,3 @@ } catch (e) {

const status = err instanceof HttpError ? err.status : 500;
const status = get_status(err);
const error = await handle_error_and_jsonify(event, options, err);

@@ -292,2 +293,4 @@

const ssr = get_option(nodes, 'ssr') ?? true;
return await render_response({

@@ -301,7 +304,7 @@ event,

csr: get_option(nodes, 'csr') ?? true,
ssr: true
ssr
},
status,
error: null,
branch: compact(branch),
branch: ssr === false ? [] : compact(branch),
action_result,

@@ -308,0 +311,0 @@ fetched

@@ -0,4 +1,3 @@

import { DEV } from 'esm-env';
import { disable_search, make_trackable } from '../../../utils/url.js';
import { unwrap_promises } from '../../../utils/promises.js';
import { DEV } from 'esm-env';
import { validate_depends } from '../../shared.js';

@@ -13,17 +12,10 @@

* parent: () => Promise<Record<string, any>>;
* track_server_fetches: boolean;
* }} opts
* @returns {Promise<import('types').ServerDataNode | null>}
*/
export async function load_server_data({
event,
state,
node,
parent,
// TODO 2.0: Remove this
track_server_fetches
}) {
export async function load_server_data({ event, state, node, parent }) {
if (!node?.server) return null;
let done = false;
let is_tracking = true;

@@ -35,15 +27,32 @@ const uses = {

route: false,
url: false
url: false,
search_params: new Set()
};
const url = make_trackable(event.url, () => {
if (DEV && done && !uses.url) {
console.warn(
`${node.server_id}: Accessing URL properties in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the URL changes`
);
const url = make_trackable(
event.url,
() => {
if (DEV && done && !uses.url) {
console.warn(
`${node.server_id}: Accessing URL properties in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the URL changes`
);
}
if (is_tracking) {
uses.url = true;
}
},
(param) => {
if (DEV && done && !uses.search_params.has(param)) {
console.warn(
`${node.server_id}: Accessing URL properties in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the URL changes`
);
}
if (is_tracking) {
uses.search_params.add(param);
}
}
);
uses.url = true;
});
if (state.prerendering) {

@@ -64,7 +73,3 @@ disable_search(url);

// TODO 2.0: Remove this
if (track_server_fetches) {
uses.dependencies.add(url.href);
}
// Note: server fetches are not added to uses.depends due to security concerns
return event.fetch(info, init);

@@ -100,3 +105,5 @@ },

uses.params.add(key);
if (is_tracking) {
uses.params.add(key);
}
return target[/** @type {string} */ (key)];

@@ -112,3 +119,5 @@ }

uses.parent = true;
if (is_tracking) {
uses.parent = true;
}
return parent();

@@ -126,12 +135,21 @@ },

uses.route = true;
if (is_tracking) {
uses.route = true;
}
return target[/** @type {'id'} */ (key)];
}
}),
url
url,
untrack(fn) {
is_tracking = false;
try {
return fn();
} finally {
is_tracking = true;
}
}
});
const data = result ? await unwrap_promises(result) : null;
if (__SVELTEKIT_DEV__) {
validate_load_response(data, /** @type {string} */ (event.route.id));
validate_load_response(result, node.server_id);
}

@@ -143,3 +161,3 @@

type: 'data',
data,
data: result ?? null,
uses,

@@ -188,14 +206,33 @@ slash: node.server.trailingSlash

depends: () => {},
parent
parent,
untrack: (fn) => fn()
});
const data = result ? await unwrap_promises(result) : null;
if (__SVELTEKIT_DEV__) {
validate_load_response(data, /** @type {string} */ (event.route.id));
validate_load_response(result, node.universal_id);
}
return data;
return result ?? null;
}
/**
* @param {ArrayBuffer} buffer
* @returns {string}
*/
function b64_encode(buffer) {
if (globalThis.Buffer) {
return Buffer.from(buffer).toString('base64');
}
const little_endian = new Uint8Array(new Uint16Array([1]).buffer)[0] > 0;
// The Uint16Array(Uint8Array(...)) ensures the code points are padded with 0's
return btoa(
new TextDecoder(little_endian ? 'utf-16le' : 'utf-16be').decode(
new Uint16Array(new Uint8Array(buffer))
)
);
}
/**
* @param {Pick<import('@sveltejs/kit').RequestEvent, 'fetch' | 'url' | 'request' | 'route'>} event

@@ -206,2 +243,3 @@ * @param {import('types').SSRState} state

* @param {Pick<Required<import('@sveltejs/kit').ResolveOptions>, 'filterSerializedResponseHeaders'>} resolve_opts
* @returns {typeof fetch}
*/

@@ -213,3 +251,3 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts) {

*/
return async (input, init) => {
const universal_fetch = async (input, init) => {
const cloned_body = input instanceof Request && input.body ? input.clone().body : null;

@@ -258,34 +296,29 @@

get(response, key, _receiver) {
async function text() {
const body = await response.text();
if (!body || typeof body === 'string') {
const status_number = Number(response.status);
if (isNaN(status_number)) {
throw new Error(
`response.status is not a number. value: "${
response.status
}" type: ${typeof response.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)
: init?.body
),
request_headers: cloned_headers,
response_body: body,
response
});
/**
* @param {string} body
* @param {boolean} is_b64
*/
async function push_fetched(body, is_b64) {
const status_number = Number(response.status);
if (isNaN(status_number)) {
throw new Error(
`response.status is not a number. value: "${
response.status
}" type: ${typeof response.status}`
);
}
if (dependency) {
dependency.body = body;
}
return body;
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)
: init?.body
),
request_headers: cloned_headers,
response_body: body,
response,
is_b64
});
}

@@ -301,4 +334,5 @@

// TODO should buffer be inlined into the page (albeit base64'd)?
// any conditions in which it shouldn't be?
if (buffer instanceof ArrayBuffer) {
await push_fetched(b64_encode(buffer), true);
}

@@ -309,2 +343,16 @@ return buffer;

async function text() {
const body = await response.text();
if (!body || typeof body === 'string') {
await push_fetched(body, false);
}
if (dependency) {
dependency.body = body;
}
return body;
}
if (key === 'text') {

@@ -345,2 +393,11 @@ return text;

};
// Don't make this function `async`! Otherwise, the user has to `catch` promises they use for streaming responses or else
// it will be an unhandled rejection. Instead, we add a `.catch(() => {})` ourselves below to this from happening.
return (input, init) => {
// See docs in fetch.js for why we need to do this
const response = universal_fetch(input, init);
response.catch(() => {});
return response;
};
}

@@ -367,15 +424,15 @@

* @param {any} data
* @param {string} [routeId]
* @param {string} [id]
*/
function validate_load_response(data, routeId) {
function validate_load_response(data, id) {
if (data != null && Object.getPrototypeOf(data) !== Object.prototype) {
throw new Error(
`a load function related to route '${routeId}' returned ${
`a load function in ${id} returned ${
typeof data !== 'object'
? `a ${typeof data}`
: data instanceof Response
? 'a Response object'
: Array.isArray(data)
? 'an array'
: 'a non-plain object'
? 'a Response object'
: Array.isArray(data)
? 'an array'
: 'a non-plain object'
}, but must return a plain object at the top level (i.e. \`return {...}\`)`

@@ -382,0 +439,0 @@ );

@@ -11,3 +11,3 @@ import * as devalue from 'devalue';

import { clarify_devalue_error, stringify_uses, handle_error_and_jsonify } from '../utils.js';
import { public_env } from '../../shared-server.js';
import { public_env, safe_public_env } from '../../shared-server.js';
import { text } from '../../../exports/index.js';

@@ -99,3 +99,3 @@ import { create_async_iterator } from '../../../utils/streaming.js';

// if appropriate, use relative paths for greater portability
if (paths.relative !== false && !state.prerendering?.fallback) {
if (paths.relative && !state.prerendering?.fallback) {
const segments = event.url.pathname.slice(paths.base.length).split('/').slice(2);

@@ -146,3 +146,4 @@

data,
form: form_value
form: form_value,
state: {}
};

@@ -282,2 +283,6 @@

if (page_config.csr) {
if (client.uses_env_dynamic_public && state.prerendering) {
modulepreloads.add(`${options.app_dir}/env.js`);
}
const included_modulepreloads = Array.from(modulepreloads, (dep) => prefixed(dep)).filter(

@@ -302,3 +307,3 @@ (path) => resolve_opts.preload({ type: 'js', path })

`base: ${base_expression}`,
`env: ${s(public_env)}`
`env: ${!client.uses_env_dynamic_public || state.prerendering ? null : s(public_env)}`
].filter(Boolean);

@@ -439,3 +444,3 @@

nonce: /** @type {string} */ (csp.nonce),
env: public_env
env: safe_public_env
});

@@ -476,3 +481,3 @@

headers
})
})
: new Response(

@@ -495,3 +500,3 @@ new ReadableStream({

}
);
);
}

@@ -498,0 +503,0 @@

@@ -5,3 +5,4 @@ import { render_response } from './render.js';

import { get_option } from '../../../utils/options.js';
import { HttpError, Redirect } from '../../control.js';
import { Redirect } from '../../control.js';
import { get_status } from '../../../utils/error.js';

@@ -53,4 +54,3 @@ /**

node: default_layout,
parent: async () => ({}),
track_server_fetches: options.track_server_fetches
parent: async () => ({})
});

@@ -91,3 +91,3 @@

ssr,
csr: get_option([default_layout], 'csr') ?? true
csr
},

@@ -110,3 +110,3 @@ status,

options,
e instanceof HttpError ? e.status : 500,
get_status(e),
(await handle_error_and_jsonify(event, options, e)).message

@@ -113,0 +113,0 @@ );

@@ -76,2 +76,6 @@ import { escape_html_attr } from '../../../utils/escape.js';

if (fetched.is_b64) {
attrs.push('data-b64');
}
if (fetched.request_headers || fetched.request_body) {

@@ -78,0 +82,0 @@ /** @type {import('types').StrictBody[]} */

@@ -11,2 +11,3 @@ import { CookieSerializeOptions } from 'cookie';

response: Response;
is_b64?: boolean;
}

@@ -35,3 +36,3 @@

value: string;
options: CookieSerializeOptions;
options: CookieSerializeOptions & { path: string };
}

@@ -21,3 +21,3 @@ import { DEV } from 'esm-env';

import { create_fetch } from './fetch.js';
import { Redirect } from '../control.js';
import { HttpError, Redirect, SvelteKitError } from '../control.js';
import {

@@ -31,5 +31,6 @@ validate_layout_exports,

import { get_option } from '../../utils/options.js';
import { error, json, text } from '../../exports/index.js';
import { json, text } from '../../exports/index.js';
import { action_json_redirect, is_action_json_request } from './page/actions.js';
import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM } from '../shared.js';
import { get_public_env } from './env_module.js';

@@ -72,3 +73,6 @@ /* global __SVELTEKIT_ADAPTER_NAME__ */

if (forbidden) {
const csrf_error = error(403, `Cross-site ${request.method} form submissions are forbidden`);
const csrf_error = new HttpError(
403,
`Cross-site ${request.method} form submissions are forbidden`
);
if (request.headers.get('accept') === 'application/json') {

@@ -101,2 +105,6 @@ return json(csrf_error.body, { status: csrf_error.status });

if (decoded === `/${options.app_dir}/env.js`) {
return get_public_env(request);
}
const is_data_request = has_data_suffix(decoded);

@@ -348,4 +356,4 @@ /** @type {boolean[] | undefined} */

: route?.page && is_action_json_request(event)
? action_json_redirect(e)
: redirect_response(e.status, e.location);
? action_json_redirect(e)
: redirect_response(e.status, e.location);
add_cookies_to_headers(response.headers, Object.values(cookies_to_add));

@@ -364,8 +372,2 @@ return response;

if (opts) {
if ('ssr' in opts) {
throw new Error(
'ssr has been removed, set it in the appropriate +layout.js instead. See the PR for more information: https://github.com/sveltejs/kit/pull/6197'
);
}
resolve_opts = {

@@ -489,3 +491,3 @@ transformPageChunk: opts.transformPageChunk || default_transform,

status: 404,
error: new Error(`Not found: ${event.url.pathname}`),
error: new SvelteKitError(404, 'Not Found', `Not found: ${event.url.pathname}`),
resolve_opts

@@ -492,0 +494,0 @@ });

import { DEV } from 'esm-env';
import { json, text } from '../../exports/index.js';
import { coalesce_to_error } from '../../utils/error.js';
import { coalesce_to_error, get_message, get_status } from '../../utils/error.js';
import { negotiate } from '../../utils/http.js';

@@ -38,3 +38,3 @@ import { HttpError } from '../control.js';

export function allowed_methods(mod) {
const allowed = Array.from(ENDPOINT_METHODS).filter((method) => method in mod);
const allowed = ENDPOINT_METHODS.filter((method) => method in mod);

@@ -74,3 +74,3 @@ if ('GET' in mod || 'HEAD' in mod) allowed.push('HEAD');

error = error instanceof HttpError ? error : coalesce_to_error(error);
const status = error instanceof HttpError ? error.status : 500;
const status = get_status(error);
const body = await handle_error_and_jsonify(event, options, error);

@@ -102,13 +102,12 @@

return error.body;
} else {
if (__SVELTEKIT_DEV__ && typeof error == 'object') {
fix_stack_trace(error);
}
}
return (
(await options.hooks.handleError({ error, event })) ?? {
message: event.route.id != null ? 'Internal Error' : 'Not Found'
}
);
if (__SVELTEKIT_DEV__ && typeof error == 'object') {
fix_stack_trace(error);
}
const status = get_status(error);
const message = get_message(error);
return (await options.hooks.handleError({ error, event, status, message })) ?? { message };
}

@@ -155,2 +154,6 @@

if (node.uses && node.uses.search_params.size > 0) {
uses.push(`"search_params":${JSON.stringify(Array.from(node.uses.search_params))}`);
}
if (node.uses && node.uses.params.size > 0) {

@@ -166,1 +169,15 @@ uses.push(`"params":${JSON.stringify(Array.from(node.uses.params))}`);

}
/**
* @param {string} message
* @param {number} offset
*/
export function warn_with_callsite(message, offset = 0) {
if (DEV) {
const stack = fix_stack_trace(new Error()).split('\n');
const line = stack.at(3 + offset);
message += `\n${line}`;
}
console.warn(message);
}

@@ -1,7 +0,19 @@

/** @type {Record<string, string>} */
/**
* `$env/dynamic/private`
* @type {Record<string, string>}
*/
export let private_env = {};
/** @type {Record<string, string>} */
/**
* `$env/dynamic/public`. When prerendering, this will be a proxy that forbids reads
* @type {Record<string, string>}
*/
export let public_env = {};
/**
* The same as `public_env`, but without the proxy. Use for `%sveltekit.env.PUBLIC_FOO%`
* @type {Record<string, string>}
*/
export let safe_public_env = {};
/** @param {any} error */

@@ -20,2 +32,7 @@ export let fix_stack_trace = (error) => error?.stack;

/** @type {(environment: Record<string, string>) => void} */
export function set_safe_public_env(environment) {
safe_public_env = environment;
}
/** @param {(error: Error) => string} value */

@@ -22,0 +39,0 @@ export function set_fix_stack_trace(value) {

@@ -10,2 +10,3 @@ /**

* // interface PageData {}
* // interface PageState {}
* // interface Platform {}

@@ -44,2 +45,7 @@ * }

/**
* The shape of the `$page.state` object, which can be manipulated using the [`pushState`](https://kit.svelte.dev/docs/modules#$app-navigation-pushstate) and [`replaceState`](https://kit.svelte.dev/docs/modules#$app-navigation-replacestate) functions from `$app/navigation`.
*/
export interface PageState {}
/**
* If your adapter provides [platform-specific context](https://kit.svelte.dev/docs/adapters#platform-specific-context) via `event.platform`, you can specify it here.

@@ -86,2 +92,6 @@ */

/**
* True during prerendering, false otherwise.
*/
export const prerendering: boolean;
/**
* The value of `config.kit.version.name`.

@@ -91,2 +101,3 @@ */

export function set_building(): void;
export function set_prerendering(): void;
}

@@ -108,3 +119,3 @@

export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets';
export let relative: boolean | undefined; // TODO in 2.0, make this a `boolean` that defaults to `true`
export let relative: boolean;
export function reset(): void;

@@ -111,0 +122,0 @@ export function override(paths: { base: string; assets: string }): void;

@@ -30,6 +30,8 @@ import { SvelteComponent } from 'svelte';

export interface ServerInternalModule {
set_building(building: boolean): void;
set_assets(path: string): void;
set_building(): void;
set_prerendering(): void;
set_private_env(environment: Record<string, string>): void;
set_public_env(environment: Record<string, string>): void;
set_safe_public_env(environment: Record<string, string>): void;
set_version(version: string): void;

@@ -63,2 +65,3 @@ set_fix_stack_trace(fix_stack_trace: (error: unknown) => string): void;

fonts: string[];
uses_env_dynamic_public: boolean;
} | null;

@@ -335,6 +338,6 @@ server_manifest: import('vite').Manifest;

export interface SSROptions {
app_dir: string;
app_template_contains_nonce: boolean;
csp: ValidatedConfig['kit']['csp'];
csrf_check_origin: boolean;
track_server_fetches: boolean;
embedded: boolean;

@@ -414,2 +417,3 @@ env_public_prefix: string;

url: boolean;
search_params: Set<string>;
}

@@ -416,0 +420,0 @@

@@ -1,5 +0,7 @@

This module provides access to runtime environment variables, as defined by the platform you're running on. For example if you're using [`adapter-node`](https://github.com/sveltejs/kit/tree/master/packages/adapter-node) (or running [`vite preview`](https://kit.svelte.dev/docs/cli)), this is equivalent to `process.env`. This module only includes variables that _do not_ begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) _and do_ start with [`config.kit.env.privatePrefix`](https://kit.svelte.dev/docs/configuration#env) (if configured).
This module provides access to runtime environment variables, as defined by the platform you're running on. For example if you're using [`adapter-node`](https://github.com/sveltejs/kit/tree/main/packages/adapter-node) (or running [`vite preview`](https://kit.svelte.dev/docs/cli)), this is equivalent to `process.env`. This module only includes variables that _do not_ begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) _and do_ start with [`config.kit.env.privatePrefix`](https://kit.svelte.dev/docs/configuration#env) (if configured).
This module cannot be imported into client-side code.
Dynamic environment variables cannot be used during prerendering.
```ts

@@ -6,0 +8,0 @@ import { env } from '$env/dynamic/private';

@@ -5,2 +5,4 @@ Similar to [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private), but only includes variables that begin with [`config.kit.env.publicPrefix`](https://kit.svelte.dev/docs/configuration#env) (which defaults to `PUBLIC_`), and can therefore safely be exposed to client-side code.

Dynamic environment variables cannot be used during prerendering.
```ts

@@ -7,0 +9,0 @@ import { env } from '$env/dynamic/public';

@@ -0,1 +1,3 @@

import { HttpError, SvelteKitError } from '../runtime/control.js';
/**

@@ -19,5 +21,19 @@ * @param {unknown} err

export function normalize_error(error) {
return /** @type {import('../runtime/control.js').Redirect | import('../runtime/control.js').HttpError | Error} */ (
return /** @type {import('../runtime/control.js').Redirect | HttpError | SvelteKitError | Error} */ (
error
);
}
/**
* @param {unknown} error
*/
export function get_status(error) {
return error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500;
}
/**
* @param {unknown} error
*/
export function get_message(error) {
return error instanceof SvelteKitError ? error.text : 'Internal Error';
}

@@ -35,3 +35,3 @@ import { fileURLToPath } from 'node:url';

*/
const fn = function (opts) {
return function (opts) {
return new Promise((fulfil, reject) => {

@@ -57,3 +57,3 @@ const worker = new Worker(fileURLToPath(module), {

if (data?.type === 'result' && data.module === module) {
worker.terminate();
worker.unref();
fulfil(data.payload);

@@ -71,4 +71,2 @@ }

};
return fn;
}

@@ -94,3 +94,3 @@ const param_pattern = /^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;

.join('')}/?$`
);
);

@@ -218,1 +218,47 @@ return { pattern, params };

}
const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
/**
* Populate a route ID with params to resolve a pathname.
* @example
* ```js
* resolveRoute(
* `/blog/[slug]/[...somethingElse]`,
* {
* slug: 'hello-world',
* somethingElse: 'something/else'
* }
* ); // `/blog/hello-world/something/else`
* ```
* @param {string} id
* @param {Record<string, string | undefined>} params
* @returns {string}
*/
export function resolve_route(id, params) {
const segments = get_route_segments(id);
return (
'/' +
segments
.map((segment) =>
segment.replace(basic_param_pattern, (_, optional, rest, name) => {
const param_value = params[name];
// This is nested so TS correctly narrows the type
if (!param_value) {
if (optional) return '';
if (rest && param_value !== undefined) return '';
throw new Error(`Missing parameter '${name}' in route ${id}`);
}
if (param_value.startsWith('/') || param_value.endsWith('/'))
throw new Error(
`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
);
return param_value;
})
)
.filter(Boolean)
.join('/')
);
}

@@ -9,3 +9,3 @@ import { BROWSER } from 'esm-env';

const absolute = /^([a-z]+:)?\/?\//;
const internal = new URL('sveltekit-internal://');

@@ -17,27 +17,9 @@ /**

export function resolve(base, path) {
if (SCHEME.test(path)) return path;
if (path[0] === '#') return base + path;
// special case
if (path[0] === '/' && path[1] === '/') return path;
const base_match = absolute.exec(base);
const path_match = absolute.exec(path);
let url = new URL(base, internal);
url = new URL(path, url);
if (!base_match) {
throw new Error(`bad base path: "${base}"`);
}
const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/');
const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/');
baseparts.pop();
for (let i = 0; i < pathparts.length; i += 1) {
const part = pathparts[i];
if (part === '.') continue;
else if (part === '..') baseparts.pop();
else baseparts.push(part);
}
const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || '';
return `${prefix}${baseparts.join('/')}`;
return url.protocol === internal.protocol ? url.pathname + url.search + url.hash : url.href;
}

@@ -101,2 +83,10 @@

/**
* Returns everything up to the first `#` in a URL
* @param {{href: string}} url_like
*/
export function strip_hash({ href }) {
return href.split('#')[0];
}
/**
* URL properties that could change during the lifetime of the page,

@@ -109,3 +99,2 @@ * which excludes things like `origin`

'search',
'searchParams',
'toString',

@@ -118,6 +107,29 @@ 'toJSON'

* @param {() => void} callback
* @param {(search_param: string) => void} search_params_callback
*/
export function make_trackable(url, callback) {
export function make_trackable(url, callback, search_params_callback) {
const tracked = new URL(url);
Object.defineProperty(tracked, 'searchParams', {
value: new Proxy(tracked.searchParams, {
get(obj, key) {
if (key === 'get' || key === 'getAll' || key === 'has') {
return (/**@type {string}*/ param) => {
search_params_callback(param);
return obj[key](param);
};
}
// if they try to access something different from what is in `tracked_search_params_properties`
// we track the whole url (entries, values, keys etc)
callback();
const value = Reflect.get(obj, key);
return typeof value === 'function' ? value.bind(obj) : value;
}
}),
enumerable: true,
configurable: true
});
for (const property of tracked_url_properties) {

@@ -193,6 +205,7 @@ Object.defineProperty(tracked, property, {

const DATA_SUFFIX = '/__data.json';
const HTML_DATA_SUFFIX = '.html__data.json';
/** @param {string} pathname */
export function has_data_suffix(pathname) {
return pathname.endsWith(DATA_SUFFIX);
return pathname.endsWith(DATA_SUFFIX) || pathname.endsWith(HTML_DATA_SUFFIX);
}

@@ -202,2 +215,3 @@

export function add_data_suffix(pathname) {
if (pathname.endsWith('.html')) return pathname.replace(/\.html$/, HTML_DATA_SUFFIX);
return pathname.replace(/\/$/, '') + DATA_SUFFIX;

@@ -208,3 +222,7 @@ }

export 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);
}
// generated during release, do not modify
/** @type {string} */
export const VERSION = '1.27.5';
export const VERSION = '2.0.6';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc