@sveltejs/kit 1.22.5 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/postbuild/analyse.js +1 -1
- package/src/core/sync/create_manifest_data/index.js +26 -2
- package/src/core/sync/write_client_manifest.js +14 -0
- package/src/core/sync/write_server.js +15 -4
- package/src/exports/index.js +2 -2
- package/src/exports/public.d.ts +4 -4
- package/src/runtime/client/client.js +6 -3
- package/src/runtime/server/respond.js +5 -2
- package/src/runtime/shared.js +2 -0
- package/src/utils/url.js +17 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +5 -5
package/package.json
CHANGED
|
@@ -60,7 +60,7 @@ async function analyse({ manifest_path, env }) {
|
|
|
60
60
|
const node = await loader();
|
|
61
61
|
|
|
62
62
|
metadata.nodes[node.index] = {
|
|
63
|
-
has_server_load: node.server?.load !== undefined
|
|
63
|
+
has_server_load: node.server?.load !== undefined || node.server?.trailingSlash !== undefined
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import colors from 'kleur';
|
|
3
4
|
import mime from 'mime';
|
|
4
5
|
import { list_files, runtime_directory } from '../../utils.js';
|
|
5
6
|
import { posixify } from '../../../utils/filesystem.js';
|
|
@@ -201,8 +202,31 @@ function create_routes_and_nodes(cwd, config, fallback) {
|
|
|
201
202
|
// process files first
|
|
202
203
|
for (const file of files) {
|
|
203
204
|
if (file.is_dir) continue;
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
|
|
206
|
+
const ext = valid_extensions.find((ext) => file.name.endsWith(ext));
|
|
207
|
+
if (!ext) continue;
|
|
208
|
+
|
|
209
|
+
if (!file.name.startsWith('+')) {
|
|
210
|
+
const name = file.name.slice(0, -ext.length);
|
|
211
|
+
// check if it is a valid route filename but missing the + prefix
|
|
212
|
+
const typo =
|
|
213
|
+
/^(?:(page(?:@(.*))?)|(layout(?:@(.*))?)|(error))$/.test(name) ||
|
|
214
|
+
/^(?:(server)|(page(?:(@[a-zA-Z0-9_-]*))?(\.server)?)|(layout(?:(@[a-zA-Z0-9_-]*))?(\.server)?))$/.test(
|
|
215
|
+
name
|
|
216
|
+
);
|
|
217
|
+
if (typo) {
|
|
218
|
+
console.log(
|
|
219
|
+
colors
|
|
220
|
+
.bold()
|
|
221
|
+
.yellow(
|
|
222
|
+
`Missing route file prefix. Did you mean +${file.name}?` +
|
|
223
|
+
` at ${path.join(dir, file.name)}`
|
|
224
|
+
)
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
206
230
|
|
|
207
231
|
if (file.name.endsWith('.d.ts')) {
|
|
208
232
|
let name = file.name.slice(0, -5);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import { relative_path, resolve_entry } from '../../utils/filesystem.js';
|
|
2
3
|
import { s } from '../../utils/misc.js';
|
|
3
4
|
import { dedent, write_if_changed } from './utils.js';
|
|
5
|
+
import colors from 'kleur';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Writes the client manifest to disk. The manifest is used to power the router. It contains the
|
|
@@ -108,6 +110,18 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
|
|
|
108
110
|
|
|
109
111
|
const hooks_file = resolve_entry(kit.files.hooks.client);
|
|
110
112
|
|
|
113
|
+
const typo = resolve_entry('src/+hooks.client');
|
|
114
|
+
if (typo) {
|
|
115
|
+
console.log(
|
|
116
|
+
colors
|
|
117
|
+
.bold()
|
|
118
|
+
.yellow(
|
|
119
|
+
`Unexpected + prefix. Did you mean ${typo.split('/').at(-1)?.slice(1)}?` +
|
|
120
|
+
` at ${path.resolve(typo)}`
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
111
125
|
write_if_changed(
|
|
112
126
|
`${output}/app.js`,
|
|
113
127
|
dedent`
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import { hash } from '../../runtime/hash.js';
|
|
4
3
|
import { posixify, resolve_entry } from '../../utils/filesystem.js';
|
|
@@ -6,6 +5,7 @@ import { s } from '../../utils/misc.js';
|
|
|
6
5
|
import { load_error_page, load_template } from '../config/index.js';
|
|
7
6
|
import { runtime_directory } from '../utils.js';
|
|
8
7
|
import { write_if_changed } from './utils.js';
|
|
8
|
+
import colors from 'kleur';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {{
|
|
@@ -76,8 +76,19 @@ export { set_assets, set_building, set_private_env, set_public_env };
|
|
|
76
76
|
* @param {string} output
|
|
77
77
|
*/
|
|
78
78
|
export function write_server(config, output) {
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
const hooks_file = resolve_entry(config.kit.files.hooks.server);
|
|
80
|
+
|
|
81
|
+
const typo = resolve_entry('src/+hooks.server');
|
|
82
|
+
if (typo) {
|
|
83
|
+
console.log(
|
|
84
|
+
colors
|
|
85
|
+
.bold()
|
|
86
|
+
.yellow(
|
|
87
|
+
`Unexpected + prefix. Did you mean ${typo.split('/').at(-1)?.slice(1)}?` +
|
|
88
|
+
` at ${path.resolve(typo)}`
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
}
|
|
81
92
|
|
|
82
93
|
/** @param {string} file */
|
|
83
94
|
function relative(file) {
|
|
@@ -88,7 +99,7 @@ export function write_server(config, output) {
|
|
|
88
99
|
`${output}/server/internal.js`,
|
|
89
100
|
server_template({
|
|
90
101
|
config,
|
|
91
|
-
hooks:
|
|
102
|
+
hooks: hooks_file ? relative(hooks_file) : null,
|
|
92
103
|
has_service_worker:
|
|
93
104
|
config.kit.serviceWorker.register && !!resolve_entry(config.kit.files.serviceWorker),
|
|
94
105
|
runtime_directory: relative(runtime_directory),
|
package/src/exports/index.js
CHANGED
|
@@ -38,14 +38,14 @@ export function error(status, body) {
|
|
|
38
38
|
* Create a `Redirect` object. If thrown during request handling, SvelteKit will return a redirect response.
|
|
39
39
|
* Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it.
|
|
40
40
|
* @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.
|
|
41
|
-
* @param {string} location The location to redirect to.
|
|
41
|
+
* @param {string | URL} location The location to redirect to.
|
|
42
42
|
*/
|
|
43
43
|
export function redirect(status, location) {
|
|
44
44
|
if ((!BROWSER || DEV) && (isNaN(status) || status < 300 || status > 308)) {
|
|
45
45
|
throw new Error('Invalid status code');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
return new Redirect(status, location);
|
|
48
|
+
return new Redirect(status, location.toString());
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
package/src/exports/public.d.ts
CHANGED
|
@@ -119,7 +119,7 @@ export interface Builder {
|
|
|
119
119
|
getClientDirectory(): string;
|
|
120
120
|
/** Get the fully resolved path to the directory containing server-side code. */
|
|
121
121
|
getServerDirectory(): string;
|
|
122
|
-
/** Get the application path including any configured `base` path, e.g.
|
|
122
|
+
/** Get the application path including any configured `base` path, e.g. `my-base-path/_app`. */
|
|
123
123
|
getAppPath(): string;
|
|
124
124
|
|
|
125
125
|
/**
|
|
@@ -851,7 +851,7 @@ export interface Navigation {
|
|
|
851
851
|
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
|
|
852
852
|
* - `popstate`: Navigation was triggered by back/forward navigation
|
|
853
853
|
*/
|
|
854
|
-
type:
|
|
854
|
+
type: Exclude<NavigationType, 'enter'>;
|
|
855
855
|
/**
|
|
856
856
|
* Whether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation)
|
|
857
857
|
*/
|
|
@@ -875,7 +875,7 @@ export interface BeforeNavigate extends Navigation {
|
|
|
875
875
|
/**
|
|
876
876
|
* The argument passed to [`afterNavigate`](https://kit.svelte.dev/docs/modules#$app-navigation-afternavigate) callbacks.
|
|
877
877
|
*/
|
|
878
|
-
export interface AfterNavigate extends Navigation {
|
|
878
|
+
export interface AfterNavigate extends Omit<Navigation, 'type'> {
|
|
879
879
|
/**
|
|
880
880
|
* The type of navigation:
|
|
881
881
|
* - `enter`: The app has hydrated
|
|
@@ -884,7 +884,7 @@ export interface AfterNavigate extends Navigation {
|
|
|
884
884
|
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
|
|
885
885
|
* - `popstate`: Navigation was triggered by back/forward navigation
|
|
886
886
|
*/
|
|
887
|
-
type:
|
|
887
|
+
type: Exclude<NavigationType, 'leave'>;
|
|
888
888
|
/**
|
|
889
889
|
* Since `afterNavigate` is called after a navigation completes, it will never be called with a navigation that unloads the page.
|
|
890
890
|
*/
|
|
@@ -31,7 +31,7 @@ import { compact } from '../../utils/array.js';
|
|
|
31
31
|
import { validate_page_exports } from '../../utils/exports.js';
|
|
32
32
|
import { unwrap_promises } from '../../utils/promises.js';
|
|
33
33
|
import { HttpError, Redirect } from '../control.js';
|
|
34
|
-
import { INVALIDATED_PARAM, validate_depends } from '../shared.js';
|
|
34
|
+
import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../shared.js';
|
|
35
35
|
import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY, SNAPSHOT_KEY } from './constants.js';
|
|
36
36
|
import { stores } from './singletons.js';
|
|
37
37
|
|
|
@@ -902,7 +902,7 @@ export function create_client(app, target) {
|
|
|
902
902
|
/**
|
|
903
903
|
* @param {{
|
|
904
904
|
* url: URL;
|
|
905
|
-
* type: import('@sveltejs/kit').
|
|
905
|
+
* type: import('@sveltejs/kit').Navigation["type"];
|
|
906
906
|
* intent?: import('./types').NavigationIntent;
|
|
907
907
|
* delta?: number;
|
|
908
908
|
* }} opts
|
|
@@ -955,7 +955,7 @@ export function create_client(app, target) {
|
|
|
955
955
|
* replaceState: boolean;
|
|
956
956
|
* state: any;
|
|
957
957
|
* } | null;
|
|
958
|
-
* type: import('@sveltejs/kit').
|
|
958
|
+
* type: import('@sveltejs/kit').Navigation["type"];
|
|
959
959
|
* delta?: number;
|
|
960
960
|
* nav_token?: {};
|
|
961
961
|
* accepted: () => void;
|
|
@@ -1819,6 +1819,9 @@ export function create_client(app, target) {
|
|
|
1819
1819
|
async function load_data(url, invalid) {
|
|
1820
1820
|
const data_url = new URL(url);
|
|
1821
1821
|
data_url.pathname = add_data_suffix(url.pathname);
|
|
1822
|
+
if (url.pathname.endsWith('/')) {
|
|
1823
|
+
data_url.searchParams.append(TRAILING_SLASH_PARAM, '1');
|
|
1824
|
+
}
|
|
1822
1825
|
if (DEV && url.searchParams.has(INVALIDATED_PARAM)) {
|
|
1823
1826
|
throw new Error(`Cannot used reserved query parameter "${INVALIDATED_PARAM}"`);
|
|
1824
1827
|
}
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import { get_option } from '../../utils/options.js';
|
|
30
30
|
import { error, json, text } from '../../exports/index.js';
|
|
31
31
|
import { action_json_redirect, is_action_json_request } from './page/actions.js';
|
|
32
|
-
import { INVALIDATED_PARAM } from '../shared.js';
|
|
32
|
+
import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM } from '../shared.js';
|
|
33
33
|
|
|
34
34
|
/* global __SVELTEKIT_ADAPTER_NAME__ */
|
|
35
35
|
|
|
@@ -100,7 +100,10 @@ export async function respond(request, options, manifest, state) {
|
|
|
100
100
|
let invalidated_data_nodes;
|
|
101
101
|
if (is_data_request) {
|
|
102
102
|
decoded = strip_data_suffix(decoded) || '/';
|
|
103
|
-
url.pathname =
|
|
103
|
+
url.pathname =
|
|
104
|
+
strip_data_suffix(url.pathname) +
|
|
105
|
+
(url.searchParams.get(TRAILING_SLASH_PARAM) === '1' ? '/' : '') || '/';
|
|
106
|
+
url.searchParams.delete(TRAILING_SLASH_PARAM);
|
|
104
107
|
invalidated_data_nodes = url.searchParams
|
|
105
108
|
.get(INVALIDATED_PARAM)
|
|
106
109
|
?.split('')
|
package/src/runtime/shared.js
CHANGED
package/src/utils/url.js
CHANGED
|
@@ -139,6 +139,8 @@ export function make_trackable(url, callback) {
|
|
|
139
139
|
* @param {URL} url
|
|
140
140
|
*/
|
|
141
141
|
export function disable_hash(url) {
|
|
142
|
+
allow_nodejs_console_log(url);
|
|
143
|
+
|
|
142
144
|
Object.defineProperty(url, 'hash', {
|
|
143
145
|
get() {
|
|
144
146
|
throw new Error(
|
|
@@ -153,6 +155,8 @@ export function disable_hash(url) {
|
|
|
153
155
|
* @param {URL} url
|
|
154
156
|
*/
|
|
155
157
|
export function disable_search(url) {
|
|
158
|
+
allow_nodejs_console_log(url);
|
|
159
|
+
|
|
156
160
|
for (const property of ['search', 'searchParams']) {
|
|
157
161
|
Object.defineProperty(url, property, {
|
|
158
162
|
get() {
|
|
@@ -162,6 +166,19 @@ export function disable_search(url) {
|
|
|
162
166
|
}
|
|
163
167
|
}
|
|
164
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Allow URL to be console logged, bypassing disabled properties.
|
|
171
|
+
* @param {URL} url
|
|
172
|
+
*/
|
|
173
|
+
function allow_nodejs_console_log(url) {
|
|
174
|
+
if (!BROWSER) {
|
|
175
|
+
// @ts-ignore
|
|
176
|
+
url[Symbol.for('nodejs.util.inspect.custom')] = (depth, opts, inspect) => {
|
|
177
|
+
return inspect(new URL(url), opts);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
165
182
|
const DATA_SUFFIX = '/__data.json';
|
|
166
183
|
|
|
167
184
|
/** @param {string} pathname */
|
package/src/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -99,7 +99,7 @@ declare module '@sveltejs/kit' {
|
|
|
99
99
|
getClientDirectory(): string;
|
|
100
100
|
/** Get the fully resolved path to the directory containing server-side code. */
|
|
101
101
|
getServerDirectory(): string;
|
|
102
|
-
/** Get the application path including any configured `base` path, e.g.
|
|
102
|
+
/** Get the application path including any configured `base` path, e.g. `my-base-path/_app`. */
|
|
103
103
|
getAppPath(): string;
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -831,7 +831,7 @@ declare module '@sveltejs/kit' {
|
|
|
831
831
|
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
|
|
832
832
|
* - `popstate`: Navigation was triggered by back/forward navigation
|
|
833
833
|
*/
|
|
834
|
-
type:
|
|
834
|
+
type: Exclude<NavigationType, 'enter'>;
|
|
835
835
|
/**
|
|
836
836
|
* Whether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation)
|
|
837
837
|
*/
|
|
@@ -855,7 +855,7 @@ declare module '@sveltejs/kit' {
|
|
|
855
855
|
/**
|
|
856
856
|
* The argument passed to [`afterNavigate`](https://kit.svelte.dev/docs/modules#$app-navigation-afternavigate) callbacks.
|
|
857
857
|
*/
|
|
858
|
-
export interface AfterNavigate extends Navigation {
|
|
858
|
+
export interface AfterNavigate extends Omit<Navigation, 'type'> {
|
|
859
859
|
/**
|
|
860
860
|
* The type of navigation:
|
|
861
861
|
* - `enter`: The app has hydrated
|
|
@@ -864,7 +864,7 @@ declare module '@sveltejs/kit' {
|
|
|
864
864
|
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
|
|
865
865
|
* - `popstate`: Navigation was triggered by back/forward navigation
|
|
866
866
|
*/
|
|
867
|
-
type:
|
|
867
|
+
type: Exclude<NavigationType, 'leave'>;
|
|
868
868
|
/**
|
|
869
869
|
* Since `afterNavigate` is called after a navigation completes, it will never be called with a navigation that unloads the page.
|
|
870
870
|
*/
|
|
@@ -1675,7 +1675,7 @@ declare module '@sveltejs/kit' {
|
|
|
1675
1675
|
* @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
|
|
1676
1676
|
* @param location The location to redirect to.
|
|
1677
1677
|
*/
|
|
1678
|
-
export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string): Redirect_1;
|
|
1678
|
+
export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string | URL): Redirect_1;
|
|
1679
1679
|
/**
|
|
1680
1680
|
* Create a JSON `Response` object from the supplied data.
|
|
1681
1681
|
* @param data The value that will be serialized as JSON.
|