Repository: sveltejs/kit
Pull request #7811 (2022-11-25 20:58:54)

Make console.warn named function
We have some code that relies on introspecting the `name` of `console.warn`— some metaprogramming to provide dev-only logs. This update to make `console.warn` an anonymous function means it no longer has a name, which breaks that assumption.

Normally:
```js
console.warn.name
> 'warn'
```
In SvelteKit dev:
```js
console.warn.name
> ''
```

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: c76f3465b3b7c0fd746cded0aba646b8dc0d5ec4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/wtachau/kit/new/patch-1?filename=.changeset/metal-beans-rule.md&value=---%0A%22%40sveltejs%2Fkit%22%3A%20patch%0A---%0A%0AMake%20console.warn%20named%20function%0A)


dummdidumm: What's the reason for this? Stack trace?
wtachau: > What's the reason for this? Stack trace?

@dummdidumm Sorry for the delay! I created this PR in github.dev and it didn't prompt me for a description. Just updated the PR.

Patch:
diff --git a/.changeset/calm-peaches-enjoy.md b/.changeset/calm-peaches-enjoy.md
new file mode 100644
index 000000000..aafb78f21
--- /dev/null
+++ b/.changeset/calm-peaches-enjoy.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+[fix] handle redirects in handle hook while processing data request
diff --git a/.changeset/chilled-drinks-hug.md b/.changeset/chilled-drinks-hug.md
new file mode 100644
index 000000000..a7a2d220a
--- /dev/null
+++ b/.changeset/chilled-drinks-hug.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Make touchstart listener passive
diff --git a/.changeset/grumpy-maps-complain.md b/.changeset/grumpy-maps-complain.md
new file mode 100644
index 000000000..72100d146
--- /dev/null
+++ b/.changeset/grumpy-maps-complain.md
@@ -0,0 +1,5 @@
+---
+"@sveltejs/kit": patch
+---
+
+[breaking] remove `getStaticDirectory()` from builder API
diff --git a/.changeset/itchy-beers-suffer.md b/.changeset/itchy-beers-suffer.md
new file mode 100644
index 000000000..2681994a5
--- /dev/null
+++ b/.changeset/itchy-beers-suffer.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+Make console.warn wrapper named rather than anonymous
diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js
index 39f78fda3..e9e0dbf71 100644
--- a/packages/kit/src/core/adapt/builder.js
+++ b/packages/kit/src/core/adapt/builder.js
@@ -126,10 +126,6 @@ export function create_builder({ config, build_data, routes, prerendered, log })
 			return `${config.kit.outDir}/output/server`;
 		},
 
-		getStaticDirectory() {
-			return config.kit.files.assets;
-		},
-
 		getAppPath() {
 			return build_data.app_path;
 		},
diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js
index 7d05d6490..7d8c8ea94 100644
--- a/packages/kit/src/runtime/client/client.js
+++ b/packages/kit/src/runtime/client/client.js
@@ -1385,7 +1385,7 @@ export function create_client({ target, base }) {
 				}, 20);
 			};
 
-			target.addEventListener('touchstart', trigger_prefetch);
+			target.addEventListener('touchstart', trigger_prefetch, { passive: true });
 			target.addEventListener('mousemove', handle_mousemove);
 			target.addEventListener('sveltekit:trigger_prefetch', trigger_prefetch);
 
@@ -1717,8 +1717,8 @@ function reset_focus() {
 
 if (__SVELTEKIT_DEV__) {
 	// Nasty hack to silence harmless warnings the user can do nothing about
-	const warn = console.warn;
-	console.warn = (...args) => {
+	const console_warn = console.warn;
+	console.warn = function warn(...args) {
 		if (
 			args.length === 1 &&
 			/<(Layout|Page)(_[\w$]+)?> was created (with unknown|without expected) prop '(data|form)'/.test(
@@ -1727,6 +1727,6 @@ if (__SVELTEKIT_DEV__) {
 		) {
 			return;
 		}
-		warn(...args);
+		console_warn(...args);
 	};
 }
diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js
index 44a0fe296..3b0f7e97c 100644
--- a/packages/kit/src/runtime/server/data/index.js
+++ b/packages/kit/src/runtime/server/data/index.js
@@ -117,12 +117,7 @@ export async function render_data(event, route, options, state, trailing_slash)
 		const error = normalize_error(e);
 
 		if (error instanceof Redirect) {
-			return json_response(
-				JSON.stringify({
-					type: 'redirect',
-					location: error.location
-				})
-			);
+			return redirect_json_response(error);
 		} else {
 			// TODO make it clearer that this was an unexpected error
 			return json_response(JSON.stringify(handle_error_and_jsonify(event, options, error)));
@@ -143,3 +138,15 @@ function json_response(json, status = 200) {
 		}
 	});
 }
+
+/**
+ * @param {Redirect} redirect
+ */
+export function redirect_json_response(redirect) {
+	return json_response(
+		JSON.stringify({
+			type: 'redirect',
+			location: redirect.location
+		})
+	);
+}
diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js
index f5554c4c6..4b9119258 100644
--- a/packages/kit/src/runtime/server/index.js
+++ b/packages/kit/src/runtime/server/index.js
@@ -13,7 +13,7 @@ import {
 	strip_data_suffix
 } from '../../utils/url.js';
 import { exec } from '../../utils/routing.js';
-import { INVALIDATED_HEADER, render_data } from './data/index.js';
+import { INVALIDATED_HEADER, redirect_json_response, render_data } from './data/index.js';
 import { add_cookies_to_headers, get_cookies } from './cookie.js';
 import { create_fetch } from './fetch.js';
 import { Redirect } from '../control.js';
@@ -289,10 +289,23 @@ export async function respond(request, options, state) {
 			}
 		}
 
+		// Edge case: If user does `return Response(30x)` in handle hook while processing a data request,
+		// we need to transform the redirect response to a corresponding JSON response.
+		if (is_data_request && response.status >= 300 && response.status <= 308) {
+			const location = response.headers.get('location');
+			if (location) {
+				return redirect_json_response(new Redirect(/** @type {any} */ (response.status), location));
+			}
+		}
+
 		return response;
 	} catch (error) {
 		if (error instanceof Redirect) {
-			return redirect_response(error.status, error.location);
+			if (is_data_request) {
+				return redirect_json_response(error);
+			} else {
+				return redirect_response(error.status, error.location);
+			}
 		}
 		return handle_fatal_error(event, options, error);
 	}
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index cdfe21595..ea7672e19 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -77,7 +77,6 @@ export interface Builder {
 	getBuildDirectory(name: string): string;
 	getClientDirectory(): string;
 	getServerDirectory(): string;
-	getStaticDirectory(): string;
 	/** The application path including any configured base path */
 	getAppPath(): string;
 


Test patch:
diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js
index d7541ef1d..2e5938aa5 100644
--- a/packages/kit/test/apps/basics/src/hooks.server.js
+++ b/packages/kit/test/apps/basics/src/hooks.server.js
@@ -1,7 +1,7 @@
 import fs from 'fs';
 import { sequence } from '@sveltejs/kit/hooks';
 import { HttpError } from '../../../../src/runtime/control';
-import { error } from '@sveltejs/kit';
+import { error, redirect } from '@sveltejs/kit';
 
 /**
  * Transform an error into a POJO, by copying its `name`, `message`
@@ -80,6 +80,17 @@ export const handle = sequence(
 		} catch {}
 
 		return response;
+	},
+	async ({ event, resolve }) => {
+		if (event.url.pathname.includes('/redirect/in-handle')) {
+			if (event.url.search === '?throw') {
+				throw redirect(307, event.url.origin + '/redirect/c');
+			} else {
+				return new Response(undefined, { status: 307, headers: { location: '/redirect/c' } });
+			}
+		}
+
+		return resolve(event);
 	}
 );
 
diff --git a/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte b/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte
index 70f0a624f..852940e4e 100644
--- a/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte
+++ b/packages/kit/test/apps/basics/src/routes/redirect/+page.svelte
@@ -7,3 +7,6 @@
 
 <a href="/redirect/missing-status/a">a (missing-status)</a>
 <a href="/redirect/missing-status/b">b (missing-status)</a>
+
+<a href="/redirect/in-handle?throw">in-handle (throw redirect)</a>
+<a href="/redirect/in-handle?response">in-handle (return Response)</a>
diff --git a/packages/kit/test/apps/basics/src/routes/redirect/in-handle/+page.server.js b/packages/kit/test/apps/basics/src/routes/redirect/in-handle/+page.server.js
new file mode 100644
index 000000000..23addb029
--- /dev/null
+++ b/packages/kit/test/apps/basics/src/routes/redirect/in-handle/+page.server.js
@@ -0,0 +1,1 @@
+export function load() {}
diff --git a/packages/kit/test/apps/basics/src/routes/redirect/in-handle/+page.svelte b/packages/kit/test/apps/basics/src/routes/redirect/in-handle/+page.svelte
new file mode 100644
index 000000000..6a72cbc95
--- /dev/null
+++ b/packages/kit/test/apps/basics/src/routes/redirect/in-handle/+page.svelte
@@ -0,0 +1,1 @@
+<h1>in-handle</h1>
diff --git a/packages/kit/test/apps/basics/test/client.test.js b/packages/kit/test/apps/basics/test/client.test.js
index 65aa6cdc7..103855f34 100644
--- a/packages/kit/test/apps/basics/test/client.test.js
+++ b/packages/kit/test/apps/basics/test/client.test.js
@@ -607,9 +607,7 @@ test.describe('Load', () => {
 	});
 
 	if (process.env.DEV) {
-		test('using window.fetch causes a warning', async ({ page }) => {
-			const port = 5173;
-
+		test('using window.fetch causes a warning', async ({ page, baseURL }) => {
 			/** @type {string[]} */
 			const warnings = [];
 
@@ -623,7 +621,7 @@ test.describe('Load', () => {
 			expect(await page.textContent('h1')).toBe('42');
 
 			expect(warnings).toContain(
-				`Loading http://localhost:${port}/load/window-fetch/data.json using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
+				`Loading ${baseURL}/load/window-fetch/data.json using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
 			);
 
 			warnings.length = 0;
@@ -632,7 +630,7 @@ test.describe('Load', () => {
 			expect(await page.textContent('h1')).toBe('42');
 
 			expect(warnings).not.toContain(
-				`Loading http://localhost:${port}/load/window-fetch/data.json using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
+				`Loading ${baseURL}/load/window-fetch/data.json using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/load#making-fetch-requests`
 			);
 		});
 	}
diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js
index 8678d1b1a..633ea3b7a 100644
--- a/packages/kit/test/apps/basics/test/test.js
+++ b/packages/kit/test/apps/basics/test/test.js
@@ -1337,6 +1337,32 @@ test.describe('Redirects', () => {
 			expect(await page.textContent('h1')).toBe('Hazaa!');
 		}
 	});
+
+	test('redirect response in handle hook', async ({ baseURL, clicknav, page }) => {
+		await page.goto('/redirect');
+
+		await clicknav('[href="/redirect/in-handle?response"]');
+
+		await page.waitForURL('/redirect/c');
+		expect(await page.textContent('h1')).toBe('c');
+		expect(page.url()).toBe(`${baseURL}/redirect/c`);
+
+		await page.goBack();
+		expect(page.url()).toBe(`${baseURL}/redirect`);
+	});
+
+	test('throw redirect in handle hook', async ({ baseURL, clicknav, page }) => {
+		await page.goto('/redirect');
+
+		await clicknav('[href="/redirect/in-handle?throw"]');
+
+		await page.waitForURL('/redirect/c');
+		expect(await page.textContent('h1')).toBe('c');
+		expect(page.url()).toBe(`${baseURL}/redirect/c`);
+
+		await page.goBack();
+		expect(page.url()).toBe(`${baseURL}/redirect`);
+	});
 });
 
 test.describe('Routing', () => {