@sveltejs/kit 1.30.2 → 2.0.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 +24 -24
- package/src/core/adapt/builder.js +8 -1
- package/src/core/config/index.js +9 -1
- package/src/core/config/options.js +1 -12
- package/src/core/postbuild/analyse.js +98 -80
- package/src/core/postbuild/prerender.js +11 -9
- package/src/core/sync/sync.js +2 -0
- package/src/core/sync/write_non_ambient.js +42 -0
- package/src/core/sync/write_server.js +3 -3
- package/src/core/sync/write_tsconfig.js +27 -78
- package/src/core/sync/write_types/index.js +1 -1
- package/src/exports/hooks/sequence.js +1 -1
- package/src/exports/index.js +88 -71
- package/src/exports/node/index.js +21 -24
- package/src/exports/node/polyfills.js +5 -34
- package/src/exports/public.d.ts +82 -61
- package/src/exports/vite/dev/index.js +11 -19
- package/src/exports/vite/graph_analysis/index.js +2 -4
- package/src/exports/vite/index.js +73 -14
- package/src/exports/vite/module_ids.js +7 -0
- package/src/exports/vite/preview/index.js +56 -130
- package/src/runtime/app/forms.js +2 -35
- package/src/runtime/app/navigation.js +33 -18
- package/src/runtime/app/paths.js +2 -29
- package/src/runtime/client/client.js +449 -199
- package/src/runtime/client/constants.js +5 -1
- package/src/runtime/client/session-storage.js +7 -5
- package/src/runtime/client/singletons.js +7 -1
- package/src/runtime/client/types.d.ts +6 -2
- package/src/runtime/client/utils.js +12 -10
- package/src/runtime/control.js +16 -8
- package/src/runtime/server/cookie.js +38 -61
- package/src/runtime/server/data/index.js +6 -4
- package/src/runtime/server/env_module.js +29 -0
- package/src/runtime/server/fetch.js +7 -6
- package/src/runtime/server/index.js +23 -20
- package/src/runtime/server/page/actions.js +24 -15
- package/src/runtime/server/page/index.js +6 -8
- package/src/runtime/server/page/load_data.js +58 -40
- package/src/runtime/server/page/render.js +12 -7
- package/src/runtime/server/page/respond_with_error.js +4 -4
- package/src/runtime/server/page/types.d.ts +1 -1
- package/src/runtime/server/respond.js +14 -12
- package/src/runtime/server/utils.js +11 -8
- package/src/runtime/shared-server.js +19 -2
- package/src/types/ambient.d.ts +7 -1
- package/src/types/internal.d.ts +4 -1
- package/src/types/synthetic/$env+dynamic+private.md +2 -0
- package/src/types/synthetic/$env+dynamic+public.md +2 -0
- package/src/utils/error.js +17 -1
- package/src/utils/routing.js +47 -1
- package/src/utils/url.js +45 -27
- package/src/version.js +1 -1
- package/types/index.d.ts +171 -118
- package/types/index.d.ts.map +9 -5
- package/src/utils/platform.js +0 -1
- package/src/utils/promises.js +0 -61
|
@@ -7,8 +7,6 @@ import { loadEnv, normalizePath } from 'vite';
|
|
|
7
7
|
import { getRequest, setResponse } from '../../../exports/node/index.js';
|
|
8
8
|
import { installPolyfills } from '../../../exports/node/polyfills.js';
|
|
9
9
|
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
10
|
-
import { should_polyfill } from '../../../utils/platform.js';
|
|
11
|
-
import { not_found } from '../utils.js';
|
|
12
10
|
|
|
13
11
|
/** @typedef {import('http').IncomingMessage} Req */
|
|
14
12
|
/** @typedef {import('http').ServerResponse} Res */
|
|
@@ -20,12 +18,9 @@ import { not_found } from '../utils.js';
|
|
|
20
18
|
* @param {import('types').ValidatedConfig} svelte_config
|
|
21
19
|
*/
|
|
22
20
|
export async function preview(vite, vite_config, svelte_config) {
|
|
23
|
-
|
|
24
|
-
installPolyfills();
|
|
25
|
-
}
|
|
21
|
+
installPolyfills();
|
|
26
22
|
|
|
27
23
|
const { paths } = svelte_config.kit;
|
|
28
|
-
const base = paths.base;
|
|
29
24
|
const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;
|
|
30
25
|
|
|
31
26
|
const protocol = vite_config.preview.https ? 'https' : 'http';
|
|
@@ -54,131 +49,84 @@ export async function preview(vite, vite_config, svelte_config) {
|
|
|
54
49
|
});
|
|
55
50
|
|
|
56
51
|
return () => {
|
|
57
|
-
//
|
|
52
|
+
// prerendered dependencies
|
|
58
53
|
vite.middlewares.use(
|
|
59
|
-
|
|
60
|
-
assets,
|
|
61
|
-
sirv(join(svelte_config.kit.outDir, 'output/client'), {
|
|
62
|
-
setHeaders: (res, pathname) => {
|
|
63
|
-
// only apply to immutable directory, not e.g. version.json
|
|
64
|
-
if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) {
|
|
65
|
-
res.setHeader('cache-control', 'public,max-age=31536000,immutable');
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
)
|
|
54
|
+
mutable(join(svelte_config.kit.outDir, 'output/prerendered/dependencies'))
|
|
70
55
|
);
|
|
71
56
|
|
|
57
|
+
// prerendered pages (we can't just use sirv because we need to
|
|
58
|
+
// preserve the correct trailingSlash behaviour)
|
|
72
59
|
vite.middlewares.use((req, res, next) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
res.writeHead(307, {
|
|
82
|
-
location
|
|
83
|
-
});
|
|
60
|
+
let if_none_match_value = req.headers['if-none-match'];
|
|
61
|
+
|
|
62
|
+
if (if_none_match_value?.startsWith('W/"')) {
|
|
63
|
+
if_none_match_value = if_none_match_value.substring(2);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (if_none_match_value === etag) {
|
|
67
|
+
res.statusCode = 304;
|
|
84
68
|
res.end();
|
|
85
69
|
return;
|
|
86
70
|
}
|
|
87
71
|
|
|
88
|
-
|
|
89
|
-
next();
|
|
90
|
-
} else {
|
|
91
|
-
res.statusCode = 404;
|
|
92
|
-
not_found(req, res, base);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
72
|
+
const { pathname, search } = new URL(/** @type {string} */ (req.url), 'http://dummy');
|
|
95
73
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
// prerendered pages (we can't just use sirv because we need to
|
|
102
|
-
// preserve the correct trailingSlash behaviour)
|
|
103
|
-
vite.middlewares.use(
|
|
104
|
-
scoped(base, (req, res, next) => {
|
|
105
|
-
let if_none_match_value = req.headers['if-none-match'];
|
|
74
|
+
let filename = normalizePath(
|
|
75
|
+
join(svelte_config.kit.outDir, 'output/prerendered/pages' + pathname)
|
|
76
|
+
);
|
|
77
|
+
let prerendered = is_file(filename);
|
|
106
78
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
79
|
+
if (!prerendered) {
|
|
80
|
+
const has_trailing_slash = pathname.endsWith('/');
|
|
81
|
+
const html_filename = `${filename}${has_trailing_slash ? 'index.html' : '.html'}`;
|
|
110
82
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
res.end();
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
83
|
+
/** @type {string | undefined} */
|
|
84
|
+
let redirect;
|
|
116
85
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (!prerendered) {
|
|
125
|
-
const has_trailing_slash = pathname.endsWith('/');
|
|
126
|
-
const html_filename = `${filename}${has_trailing_slash ? 'index.html' : '.html'}`;
|
|
127
|
-
|
|
128
|
-
/** @type {string | undefined} */
|
|
129
|
-
let redirect;
|
|
130
|
-
|
|
131
|
-
if (is_file(html_filename)) {
|
|
132
|
-
filename = html_filename;
|
|
133
|
-
prerendered = true;
|
|
134
|
-
} else if (has_trailing_slash) {
|
|
135
|
-
if (is_file(filename.slice(0, -1) + '.html')) {
|
|
136
|
-
redirect = pathname.slice(0, -1);
|
|
137
|
-
}
|
|
138
|
-
} else if (is_file(filename + '/index.html')) {
|
|
139
|
-
redirect = pathname + '/';
|
|
86
|
+
if (is_file(html_filename)) {
|
|
87
|
+
filename = html_filename;
|
|
88
|
+
prerendered = true;
|
|
89
|
+
} else if (has_trailing_slash) {
|
|
90
|
+
if (is_file(filename.slice(0, -1) + '.html')) {
|
|
91
|
+
redirect = pathname.slice(0, -1);
|
|
140
92
|
}
|
|
93
|
+
} else if (is_file(filename + '/index.html')) {
|
|
94
|
+
redirect = pathname + '/';
|
|
95
|
+
}
|
|
141
96
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
97
|
+
if (redirect) {
|
|
98
|
+
if (search) redirect += search;
|
|
99
|
+
res.writeHead(307, {
|
|
100
|
+
location: redirect
|
|
101
|
+
});
|
|
147
102
|
|
|
148
|
-
|
|
103
|
+
res.end();
|
|
149
104
|
|
|
150
|
-
|
|
151
|
-
}
|
|
105
|
+
return;
|
|
152
106
|
}
|
|
107
|
+
}
|
|
153
108
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
109
|
+
if (prerendered) {
|
|
110
|
+
res.writeHead(200, {
|
|
111
|
+
'content-type': lookup(pathname) || 'text/html',
|
|
112
|
+
etag
|
|
113
|
+
});
|
|
159
114
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
);
|
|
115
|
+
fs.createReadStream(filename).pipe(res);
|
|
116
|
+
} else {
|
|
117
|
+
next();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
166
120
|
|
|
167
121
|
// SSR
|
|
168
122
|
vite.middlewares.use(async (req, res) => {
|
|
169
123
|
const host = req.headers['host'];
|
|
124
|
+
req.url = req.originalUrl;
|
|
170
125
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
base: `${protocol}://${host}`,
|
|
176
|
-
request: req
|
|
177
|
-
});
|
|
178
|
-
} catch (/** @type {any} */ err) {
|
|
179
|
-
res.statusCode = err.status || 400;
|
|
180
|
-
return res.end('Invalid request body');
|
|
181
|
-
}
|
|
126
|
+
const request = await getRequest({
|
|
127
|
+
base: `${protocol}://${host}`,
|
|
128
|
+
request: req
|
|
129
|
+
});
|
|
182
130
|
|
|
183
131
|
setResponse(
|
|
184
132
|
res,
|
|
@@ -204,31 +152,9 @@ const mutable = (dir) =>
|
|
|
204
152
|
? sirv(dir, {
|
|
205
153
|
etag: true,
|
|
206
154
|
maxAge: 0
|
|
207
|
-
|
|
155
|
+
})
|
|
208
156
|
: (_req, _res, next) => next();
|
|
209
157
|
|
|
210
|
-
/**
|
|
211
|
-
* @param {string} scope
|
|
212
|
-
* @param {Handler} handler
|
|
213
|
-
* @returns {Handler}
|
|
214
|
-
*/
|
|
215
|
-
function scoped(scope, handler) {
|
|
216
|
-
if (scope === '') return handler;
|
|
217
|
-
|
|
218
|
-
return (req, res, next) => {
|
|
219
|
-
if (req.url?.startsWith(scope)) {
|
|
220
|
-
const original_url = req.url;
|
|
221
|
-
req.url = req.url.slice(scope.length);
|
|
222
|
-
handler(req, res, () => {
|
|
223
|
-
req.url = original_url;
|
|
224
|
-
next();
|
|
225
|
-
});
|
|
226
|
-
} else {
|
|
227
|
-
next();
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
158
|
/** @param {string} path */
|
|
233
159
|
function is_file(path) {
|
|
234
160
|
return fs.existsSync(path) && !fs.statSync(path).isDirectory();
|
package/src/runtime/app/forms.js
CHANGED
|
@@ -49,20 +49,6 @@ export function deserialize(result) {
|
|
|
49
49
|
return parsed;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
/**
|
|
53
|
-
* @param {string} old_name
|
|
54
|
-
* @param {string} new_name
|
|
55
|
-
* @param {string} call_location
|
|
56
|
-
* @returns void
|
|
57
|
-
*/
|
|
58
|
-
function warn_on_access(old_name, new_name, call_location) {
|
|
59
|
-
if (!DEV) return;
|
|
60
|
-
// TODO 2.0: Remove this code
|
|
61
|
-
console.warn(
|
|
62
|
-
`\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
52
|
/**
|
|
67
53
|
* Shallow clone an element, so that we can access e.g. `form.action` without worrying
|
|
68
54
|
* that someone has added an `<input name="action">` (https://github.com/sveltejs/kit/issues/7593)
|
|
@@ -157,11 +143,9 @@ export function enhance(form_element, submit = () => {}) {
|
|
|
157
143
|
if (DEV && clone(form_element).enctype !== 'multipart/form-data') {
|
|
158
144
|
for (const value of form_data.values()) {
|
|
159
145
|
if (value instanceof File) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
'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.'
|
|
146
|
+
throw new Error(
|
|
147
|
+
'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.'
|
|
163
148
|
);
|
|
164
|
-
break;
|
|
165
149
|
}
|
|
166
150
|
}
|
|
167
151
|
}
|
|
@@ -176,21 +160,12 @@ export function enhance(form_element, submit = () => {}) {
|
|
|
176
160
|
let cancelled = false;
|
|
177
161
|
const cancel = () => (cancelled = true);
|
|
178
162
|
|
|
179
|
-
// TODO 2.0: Remove `data` and `form`
|
|
180
163
|
const callback =
|
|
181
164
|
(await submit({
|
|
182
165
|
action,
|
|
183
166
|
cancel,
|
|
184
167
|
controller,
|
|
185
|
-
get data() {
|
|
186
|
-
warn_on_access('data', 'formData', 'use:enhance submit function');
|
|
187
|
-
return form_data;
|
|
188
|
-
},
|
|
189
168
|
formData: form_data,
|
|
190
|
-
get form() {
|
|
191
|
-
warn_on_access('form', 'formElement', 'use:enhance submit function');
|
|
192
|
-
return form_element;
|
|
193
|
-
},
|
|
194
169
|
formElement: form_element,
|
|
195
170
|
submitter: event.submitter
|
|
196
171
|
})) ?? fallback_callback;
|
|
@@ -220,15 +195,7 @@ export function enhance(form_element, submit = () => {}) {
|
|
|
220
195
|
|
|
221
196
|
callback({
|
|
222
197
|
action,
|
|
223
|
-
get data() {
|
|
224
|
-
warn_on_access('data', 'formData', 'callback returned from use:enhance submit function');
|
|
225
|
-
return form_data;
|
|
226
|
-
},
|
|
227
198
|
formData: form_data,
|
|
228
|
-
get form() {
|
|
229
|
-
warn_on_access('form', 'formElement', 'callback returned from use:enhance submit function');
|
|
230
|
-
return form_element;
|
|
231
|
-
},
|
|
232
199
|
formElement: form_element,
|
|
233
200
|
update: (opts) =>
|
|
234
201
|
fallback_callback({
|
|
@@ -11,20 +11,13 @@ export const disableScrollHandling = /* @__PURE__ */ client_method('disable_scro
|
|
|
11
11
|
* Returns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) to the specified `url`.
|
|
12
12
|
* For external URLs, use `window.location = url` instead of calling `goto(url)`.
|
|
13
13
|
*
|
|
14
|
-
* @type {(url: string | URL, opts?: {
|
|
15
|
-
* replaceState?: boolean;
|
|
16
|
-
* noScroll?: boolean;
|
|
17
|
-
* keepFocus?: boolean;
|
|
18
|
-
* invalidateAll?: boolean;
|
|
19
|
-
* state?: any
|
|
20
|
-
* }) => Promise<void>}
|
|
14
|
+
* @type {(url: string | URL, opts?: { replaceState?: boolean; noScroll?: boolean; keepFocus?: boolean; invalidateAll?: boolean; }) => Promise<void>}
|
|
21
15
|
* @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.
|
|
22
16
|
* @param {Object} [opts] Options related to the navigation
|
|
23
17
|
* @param {boolean} [opts.replaceState] If `true`, will replace the current `history` entry rather than creating a new one with `pushState`
|
|
24
18
|
* @param {boolean} [opts.noScroll] If `true`, the browser will maintain its scroll position rather than scrolling to the top of the page after navigation
|
|
25
19
|
* @param {boolean} [opts.keepFocus] If `true`, the currently focused element will retain focus after navigation. Otherwise, focus will be reset to the body
|
|
26
|
-
* @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.
|
|
27
|
-
* @param {any} [opts.state] The state of the new/updated history entry
|
|
20
|
+
* @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.
|
|
28
21
|
* @returns {Promise<void>}
|
|
29
22
|
*/
|
|
30
23
|
export const goto = /* @__PURE__ */ client_method('goto');
|
|
@@ -64,11 +57,11 @@ export const invalidateAll = /* @__PURE__ */ client_method('invalidate_all');
|
|
|
64
57
|
*
|
|
65
58
|
* This is the same behaviour that SvelteKit triggers when the user taps or mouses over an `<a>` element with `data-sveltekit-preload-data`.
|
|
66
59
|
* If the next navigation is to `href`, the values returned from load will be used, making navigation instantaneous.
|
|
67
|
-
* Returns a Promise that resolves
|
|
60
|
+
* Returns a Promise that resolves with the result of running the new route's `load` functions once the preload is complete.
|
|
68
61
|
*
|
|
69
|
-
* @type {(href: string) => Promise<
|
|
62
|
+
* @type {(href: string) => Promise<Record<string, any>>}
|
|
70
63
|
* @param {string} href Page to preload
|
|
71
|
-
* @returns {Promise<
|
|
64
|
+
* @returns {Promise<{ type: 'loaded'; status: number; data: Record<string, any> } | { type: 'redirect'; location: string }>}
|
|
72
65
|
*/
|
|
73
66
|
export const preloadData = /* @__PURE__ */ client_method('preload_data');
|
|
74
67
|
|
|
@@ -81,18 +74,20 @@ export const preloadData = /* @__PURE__ */ client_method('preload_data');
|
|
|
81
74
|
* Unlike `preloadData`, this won't call `load` functions.
|
|
82
75
|
* Returns a Promise that resolves when the modules have been imported.
|
|
83
76
|
*
|
|
84
|
-
* @type {(
|
|
85
|
-
* @param {
|
|
77
|
+
* @type {(url: string) => Promise<void>}
|
|
78
|
+
* @param {string} url
|
|
86
79
|
* @returns {Promise<void>}
|
|
87
80
|
*/
|
|
88
81
|
export const preloadCode = /* @__PURE__ */ client_method('preload_code');
|
|
89
82
|
|
|
90
83
|
/**
|
|
91
84
|
* 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.
|
|
92
|
-
* Calling `cancel()` will prevent the navigation from completing. If the navigation would have directly unloaded the current page, calling `cancel` will trigger the native
|
|
93
|
-
* browser unload confirmation dialog. In these cases, `navigation.willUnload` is `true`.
|
|
94
85
|
*
|
|
95
|
-
*
|
|
86
|
+
* 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.
|
|
87
|
+
*
|
|
88
|
+
* 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`.
|
|
89
|
+
*
|
|
90
|
+
* 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`.
|
|
96
91
|
*
|
|
97
92
|
* `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted.
|
|
98
93
|
* @type {(callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void) => void}
|
|
@@ -109,7 +104,7 @@ export const beforeNavigate = /* @__PURE__ */ client_method('before_navigate');
|
|
|
109
104
|
* If a function (or a `Promise` that resolves to a function) is returned from the callback, it will be called once the DOM has updated.
|
|
110
105
|
*
|
|
111
106
|
* `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted.
|
|
112
|
-
* @type {(callback: (navigation: import('@sveltejs/kit').OnNavigate) => import('
|
|
107
|
+
* @type {(callback: (navigation: import('@sveltejs/kit').OnNavigate) => import('types').MaybePromise<(() => void) | void>) => void}
|
|
113
108
|
* @param {(navigation: import('@sveltejs/kit').OnNavigate) => void} callback
|
|
114
109
|
* @returns {void}
|
|
115
110
|
*/
|
|
@@ -124,3 +119,23 @@ export const onNavigate = /* @__PURE__ */ client_method('on_navigate');
|
|
|
124
119
|
* @returns {void}
|
|
125
120
|
*/
|
|
126
121
|
export const afterNavigate = /* @__PURE__ */ client_method('after_navigate');
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 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).
|
|
125
|
+
*
|
|
126
|
+
* @type {(url: string | URL, state: App.PageState) => void}
|
|
127
|
+
* @param {string | URL} url
|
|
128
|
+
* @param {App.PageState} state
|
|
129
|
+
* @returns {void}
|
|
130
|
+
*/
|
|
131
|
+
export const pushState = /* @__PURE__ */ client_method('push_state');
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 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).
|
|
135
|
+
*
|
|
136
|
+
* @type {(url: string | URL, state: App.PageState) => void}
|
|
137
|
+
* @param {string | URL} url
|
|
138
|
+
* @param {App.PageState} state
|
|
139
|
+
* @returns {void}
|
|
140
|
+
*/
|
|
141
|
+
export const replaceState = /* @__PURE__ */ client_method('replace_state');
|
package/src/runtime/app/paths.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export { base, assets } from '__sveltekit/paths';
|
|
2
2
|
import { base } from '__sveltekit/paths';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
|
|
3
|
+
import { resolve_route } from '../../utils/routing.js';
|
|
6
4
|
|
|
7
5
|
/**
|
|
8
6
|
* Populate a route ID with params to resolve a pathname.
|
|
@@ -21,30 +19,5 @@ const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
|
|
|
21
19
|
* @returns {string}
|
|
22
20
|
*/
|
|
23
21
|
export function resolveRoute(id, params) {
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
base +
|
|
27
|
-
'/' +
|
|
28
|
-
segments
|
|
29
|
-
.map((segment) =>
|
|
30
|
-
segment.replace(basic_param_pattern, (_, optional, rest, name) => {
|
|
31
|
-
const param_value = params[name];
|
|
32
|
-
|
|
33
|
-
// This is nested so TS correctly narrows the type
|
|
34
|
-
if (!param_value) {
|
|
35
|
-
if (optional) return '';
|
|
36
|
-
if (rest && param_value !== undefined) return '';
|
|
37
|
-
throw new Error(`Missing parameter '${name}' in route ${id}`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (param_value.startsWith('/') || param_value.endsWith('/'))
|
|
41
|
-
throw new Error(
|
|
42
|
-
`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
|
|
43
|
-
);
|
|
44
|
-
return param_value;
|
|
45
|
-
})
|
|
46
|
-
)
|
|
47
|
-
.filter(Boolean)
|
|
48
|
-
.join('/')
|
|
49
|
-
);
|
|
22
|
+
return base + resolve_route(id, params);
|
|
50
23
|
}
|