Repository: sveltejs/kit
Pull request #7809 (2022-11-25 18:22:07)

Removed getStaticDirectory() 
### Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
- [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [x] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.

Removes getStaticDirectory() because of no more usage, as stated in #7800.

### Tests
- [x] Run the tests with `pnpm test` and lint the project with `pnpm lint` and `pnpm check`

### Changesets
- [x] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `pnpm changeset` and following the prompts. All changesets should be `patch` until SvelteKit 1.0


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

Latest commit: 1d30386fc954b42a0e4a8b78f4c6266d72627b34

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/mjh316/kit/new/master?filename=.changeset/grumpy-maps-complain.md&value=---%0A%22%40sveltejs%2Fkit%22%3A%20patch%0A---%0A%0ARemoved%20getStaticDirectory()%20%0A)


mjh316: It seems [svelte-adapter-firebase](https://github.com/jthegedus/svelte-adapter-firebase) has [one usage](https://github.com/jthegedus/svelte-adapter-firebase/blob/main/src/index.js).
Other than that, all the adapters on https://sveltesociety.dev/components#adapters do not use it.
dummdidumm: Thank you! We should ask them for what exactly they need it and if they can use something else to achieve what they want before merging this.
benmccann: @jthegedus it would be interesting to get your input on this PR. thanks!
jthegedus: We are using this in the Firebase adapter to resolve https://github.com/sveltejs/kit/issues/587 in our own way, but I believe we can work around it regardless. I need to do a big update/rewrite of the adapter now a lot of things have changed in Firebase and Kit.

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/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/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/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/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', () => {