@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
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { disable_search, make_trackable } from '../../../utils/url.js';
|
|
2
|
-
import { unwrap_promises } from '../../../utils/promises.js';
|
|
3
1
|
import { DEV } from 'esm-env';
|
|
2
|
+
import { disable_search, make_trackable } from '../../../utils/url.js';
|
|
4
3
|
import { validate_depends } from '../../shared.js';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -10,39 +9,49 @@ import { validate_depends } from '../../shared.js';
|
|
|
10
9
|
* state: import('types').SSRState;
|
|
11
10
|
* node: import('types').SSRNode | undefined;
|
|
12
11
|
* parent: () => Promise<Record<string, any>>;
|
|
13
|
-
* track_server_fetches: boolean;
|
|
14
12
|
* }} opts
|
|
15
13
|
* @returns {Promise<import('types').ServerDataNode | null>}
|
|
16
14
|
*/
|
|
17
|
-
export async function load_server_data({
|
|
18
|
-
event,
|
|
19
|
-
state,
|
|
20
|
-
node,
|
|
21
|
-
parent,
|
|
22
|
-
// TODO 2.0: Remove this
|
|
23
|
-
track_server_fetches
|
|
24
|
-
}) {
|
|
15
|
+
export async function load_server_data({ event, state, node, parent }) {
|
|
25
16
|
if (!node?.server) return null;
|
|
26
17
|
|
|
27
18
|
let done = false;
|
|
19
|
+
let is_tracking = true;
|
|
28
20
|
|
|
29
21
|
const uses = {
|
|
30
22
|
dependencies: new Set(),
|
|
31
23
|
params: new Set(),
|
|
32
24
|
parent: false,
|
|
33
25
|
route: false,
|
|
34
|
-
url: false
|
|
26
|
+
url: false,
|
|
27
|
+
search_params: new Set()
|
|
35
28
|
};
|
|
36
29
|
|
|
37
|
-
const url = make_trackable(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
const url = make_trackable(
|
|
31
|
+
event.url,
|
|
32
|
+
() => {
|
|
33
|
+
if (DEV && done && !uses.url) {
|
|
34
|
+
console.warn(
|
|
35
|
+
`${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`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
if (is_tracking) {
|
|
40
|
+
uses.url = true;
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
(param) => {
|
|
44
|
+
if (DEV && done && !uses.search_params.has(param)) {
|
|
45
|
+
console.warn(
|
|
46
|
+
`${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`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (is_tracking) {
|
|
51
|
+
uses.search_params.add(param);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
);
|
|
46
55
|
|
|
47
56
|
if (state.prerendering) {
|
|
48
57
|
disable_search(url);
|
|
@@ -59,11 +68,7 @@ export async function load_server_data({
|
|
|
59
68
|
);
|
|
60
69
|
}
|
|
61
70
|
|
|
62
|
-
//
|
|
63
|
-
if (track_server_fetches) {
|
|
64
|
-
uses.dependencies.add(url.href);
|
|
65
|
-
}
|
|
66
|
-
|
|
71
|
+
// Note: server fetches are not added to uses.depends due to security concerns
|
|
67
72
|
return event.fetch(info, init);
|
|
68
73
|
},
|
|
69
74
|
/** @param {string[]} deps */
|
|
@@ -94,7 +99,9 @@ export async function load_server_data({
|
|
|
94
99
|
);
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
if (is_tracking) {
|
|
103
|
+
uses.params.add(key);
|
|
104
|
+
}
|
|
98
105
|
return target[/** @type {string} */ (key)];
|
|
99
106
|
}
|
|
100
107
|
}),
|
|
@@ -105,7 +112,9 @@ export async function load_server_data({
|
|
|
105
112
|
);
|
|
106
113
|
}
|
|
107
114
|
|
|
108
|
-
|
|
115
|
+
if (is_tracking) {
|
|
116
|
+
uses.parent = true;
|
|
117
|
+
}
|
|
109
118
|
return parent();
|
|
110
119
|
},
|
|
111
120
|
route: new Proxy(event.route, {
|
|
@@ -118,23 +127,32 @@ export async function load_server_data({
|
|
|
118
127
|
);
|
|
119
128
|
}
|
|
120
129
|
|
|
121
|
-
|
|
130
|
+
if (is_tracking) {
|
|
131
|
+
uses.route = true;
|
|
132
|
+
}
|
|
122
133
|
return target[/** @type {'id'} */ (key)];
|
|
123
134
|
}
|
|
124
135
|
}),
|
|
125
|
-
url
|
|
136
|
+
url,
|
|
137
|
+
untrack(fn) {
|
|
138
|
+
is_tracking = false;
|
|
139
|
+
try {
|
|
140
|
+
return fn();
|
|
141
|
+
} finally {
|
|
142
|
+
is_tracking = true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
126
145
|
});
|
|
127
146
|
|
|
128
|
-
const data = result ? await unwrap_promises(result, node.server_id) : null;
|
|
129
147
|
if (__SVELTEKIT_DEV__) {
|
|
130
|
-
validate_load_response(
|
|
148
|
+
validate_load_response(result, node.server_id);
|
|
131
149
|
}
|
|
132
150
|
|
|
133
151
|
done = true;
|
|
134
152
|
|
|
135
153
|
return {
|
|
136
154
|
type: 'data',
|
|
137
|
-
data,
|
|
155
|
+
data: result ?? null,
|
|
138
156
|
uses,
|
|
139
157
|
slash: node.server.trailingSlash
|
|
140
158
|
};
|
|
@@ -178,15 +196,15 @@ export async function load_data({
|
|
|
178
196
|
fetch: create_universal_fetch(event, state, fetched, csr, resolve_opts),
|
|
179
197
|
setHeaders: event.setHeaders,
|
|
180
198
|
depends: () => {},
|
|
181
|
-
parent
|
|
199
|
+
parent,
|
|
200
|
+
untrack: (fn) => fn()
|
|
182
201
|
});
|
|
183
202
|
|
|
184
|
-
const data = result ? await unwrap_promises(result, node.universal_id) : null;
|
|
185
203
|
if (__SVELTEKIT_DEV__) {
|
|
186
|
-
validate_load_response(
|
|
204
|
+
validate_load_response(result, node.universal_id);
|
|
187
205
|
}
|
|
188
206
|
|
|
189
|
-
return
|
|
207
|
+
return result ?? null;
|
|
190
208
|
}
|
|
191
209
|
|
|
192
210
|
/**
|
|
@@ -398,10 +416,10 @@ function validate_load_response(data, id) {
|
|
|
398
416
|
typeof data !== 'object'
|
|
399
417
|
? `a ${typeof data}`
|
|
400
418
|
: data instanceof Response
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
419
|
+
? 'a Response object'
|
|
420
|
+
: Array.isArray(data)
|
|
421
|
+
? 'an array'
|
|
422
|
+
: 'a non-plain object'
|
|
405
423
|
}, but must return a plain object at the top level (i.e. \`return {...}\`)`
|
|
406
424
|
);
|
|
407
425
|
}
|
|
@@ -8,7 +8,7 @@ import { s } from '../../../utils/misc.js';
|
|
|
8
8
|
import { Csp } from './csp.js';
|
|
9
9
|
import { uneval_action_response } from './actions.js';
|
|
10
10
|
import { clarify_devalue_error, stringify_uses, handle_error_and_jsonify } from '../utils.js';
|
|
11
|
-
import { public_env } from '../../shared-server.js';
|
|
11
|
+
import { public_env, safe_public_env } from '../../shared-server.js';
|
|
12
12
|
import { text } from '../../../exports/index.js';
|
|
13
13
|
import { create_async_iterator } from '../../../utils/streaming.js';
|
|
14
14
|
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
@@ -95,7 +95,7 @@ export async function render_response({
|
|
|
95
95
|
let base_expression = s(paths.base);
|
|
96
96
|
|
|
97
97
|
// if appropriate, use relative paths for greater portability
|
|
98
|
-
if (paths.relative
|
|
98
|
+
if (paths.relative && !state.prerendering?.fallback) {
|
|
99
99
|
const segments = event.url.pathname.slice(paths.base.length).split('/').slice(2);
|
|
100
100
|
|
|
101
101
|
base = segments.map(() => '..').join('/') || '.';
|
|
@@ -141,7 +141,8 @@ export async function render_response({
|
|
|
141
141
|
status,
|
|
142
142
|
url: event.url,
|
|
143
143
|
data,
|
|
144
|
-
form: form_value
|
|
144
|
+
form: form_value,
|
|
145
|
+
state: {}
|
|
145
146
|
};
|
|
146
147
|
|
|
147
148
|
// use relative paths during rendering, so that the resulting HTML is as
|
|
@@ -276,6 +277,10 @@ export async function render_response({
|
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
if (page_config.csr) {
|
|
280
|
+
if (client.uses_env_dynamic_public && state.prerendering) {
|
|
281
|
+
modulepreloads.add(`${options.app_dir}/env.js`);
|
|
282
|
+
}
|
|
283
|
+
|
|
279
284
|
const included_modulepreloads = Array.from(modulepreloads, (dep) => prefixed(dep)).filter(
|
|
280
285
|
(path) => resolve_opts.preload({ type: 'js', path })
|
|
281
286
|
);
|
|
@@ -295,7 +300,7 @@ export async function render_response({
|
|
|
295
300
|
const properties = [
|
|
296
301
|
paths.assets && `assets: ${s(paths.assets)}`,
|
|
297
302
|
`base: ${base_expression}`,
|
|
298
|
-
`env: ${s(public_env)}`
|
|
303
|
+
`env: ${!client.uses_env_dynamic_public || state.prerendering ? null : s(public_env)}`
|
|
299
304
|
].filter(Boolean);
|
|
300
305
|
|
|
301
306
|
if (chunks) {
|
|
@@ -431,7 +436,7 @@ export async function render_response({
|
|
|
431
436
|
body,
|
|
432
437
|
assets,
|
|
433
438
|
nonce: /** @type {string} */ (csp.nonce),
|
|
434
|
-
env:
|
|
439
|
+
env: safe_public_env
|
|
435
440
|
});
|
|
436
441
|
|
|
437
442
|
// TODO flush chunks as early as we can
|
|
@@ -467,7 +472,7 @@ export async function render_response({
|
|
|
467
472
|
? text(transformed, {
|
|
468
473
|
status,
|
|
469
474
|
headers
|
|
470
|
-
|
|
475
|
+
})
|
|
471
476
|
: new Response(
|
|
472
477
|
new ReadableStream({
|
|
473
478
|
async start(controller) {
|
|
@@ -485,7 +490,7 @@ export async function render_response({
|
|
|
485
490
|
'content-type': 'text/html'
|
|
486
491
|
}
|
|
487
492
|
}
|
|
488
|
-
|
|
493
|
+
);
|
|
489
494
|
}
|
|
490
495
|
|
|
491
496
|
/**
|
|
@@ -2,7 +2,8 @@ import { render_response } from './render.js';
|
|
|
2
2
|
import { load_data, load_server_data } from './load_data.js';
|
|
3
3
|
import { handle_error_and_jsonify, static_error_page, redirect_response } from '../utils.js';
|
|
4
4
|
import { get_option } from '../../../utils/options.js';
|
|
5
|
-
import {
|
|
5
|
+
import { Redirect } from '../../control.js';
|
|
6
|
+
import { get_status } from '../../../utils/error.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @typedef {import('./types.js').Loaded} Loaded
|
|
@@ -49,8 +50,7 @@ export async function respond_with_error({
|
|
|
49
50
|
event,
|
|
50
51
|
state,
|
|
51
52
|
node: default_layout,
|
|
52
|
-
parent: async () => ({})
|
|
53
|
-
track_server_fetches: options.track_server_fetches
|
|
53
|
+
parent: async () => ({})
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
const server_data = await server_data_promise;
|
|
@@ -104,7 +104,7 @@ export async function respond_with_error({
|
|
|
104
104
|
|
|
105
105
|
return static_error_page(
|
|
106
106
|
options,
|
|
107
|
-
e
|
|
107
|
+
get_status(e),
|
|
108
108
|
(await handle_error_and_jsonify(event, options, e)).message
|
|
109
109
|
);
|
|
110
110
|
}
|
|
@@ -18,7 +18,7 @@ import { exec } from '../../utils/routing.js';
|
|
|
18
18
|
import { redirect_json_response, render_data } from './data/index.js';
|
|
19
19
|
import { add_cookies_to_headers, get_cookies } from './cookie.js';
|
|
20
20
|
import { create_fetch } from './fetch.js';
|
|
21
|
-
import { Redirect,
|
|
21
|
+
import { HttpError, Redirect, SvelteKitError } from '../control.js';
|
|
22
22
|
import {
|
|
23
23
|
validate_layout_exports,
|
|
24
24
|
validate_layout_server_exports,
|
|
@@ -27,9 +27,10 @@ import {
|
|
|
27
27
|
validate_server_exports
|
|
28
28
|
} from '../../utils/exports.js';
|
|
29
29
|
import { get_option } from '../../utils/options.js';
|
|
30
|
-
import {
|
|
30
|
+
import { json, text } from '../../exports/index.js';
|
|
31
31
|
import { action_json_redirect, is_action_json_request } from './page/actions.js';
|
|
32
32
|
import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM } from '../shared.js';
|
|
33
|
+
import { get_public_env } from './env_module.js';
|
|
33
34
|
|
|
34
35
|
/* global __SVELTEKIT_ADAPTER_NAME__ */
|
|
35
36
|
|
|
@@ -67,7 +68,10 @@ export async function respond(request, options, manifest, state) {
|
|
|
67
68
|
request.headers.get('origin') !== url.origin;
|
|
68
69
|
|
|
69
70
|
if (forbidden) {
|
|
70
|
-
const csrf_error =
|
|
71
|
+
const csrf_error = new HttpError(
|
|
72
|
+
403,
|
|
73
|
+
`Cross-site ${request.method} form submissions are forbidden`
|
|
74
|
+
);
|
|
71
75
|
if (request.headers.get('accept') === 'application/json') {
|
|
72
76
|
return json(csrf_error.body, { status: csrf_error.status });
|
|
73
77
|
}
|
|
@@ -95,6 +99,10 @@ export async function respond(request, options, manifest, state) {
|
|
|
95
99
|
decoded = decoded.slice(base.length) || '/';
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
if (decoded === `/${options.app_dir}/env.js`) {
|
|
103
|
+
return get_public_env(request);
|
|
104
|
+
}
|
|
105
|
+
|
|
98
106
|
const is_data_request = has_data_suffix(decoded);
|
|
99
107
|
/** @type {boolean[] | undefined} */
|
|
100
108
|
let invalidated_data_nodes;
|
|
@@ -341,8 +349,8 @@ export async function respond(request, options, manifest, state) {
|
|
|
341
349
|
const response = is_data_request
|
|
342
350
|
? redirect_json_response(e)
|
|
343
351
|
: route?.page && is_action_json_request(event)
|
|
344
|
-
|
|
345
|
-
|
|
352
|
+
? action_json_redirect(e)
|
|
353
|
+
: redirect_response(e.status, e.location);
|
|
346
354
|
add_cookies_to_headers(response.headers, Object.values(cookies_to_add));
|
|
347
355
|
return response;
|
|
348
356
|
}
|
|
@@ -356,12 +364,6 @@ export async function respond(request, options, manifest, state) {
|
|
|
356
364
|
async function resolve(event, opts) {
|
|
357
365
|
try {
|
|
358
366
|
if (opts) {
|
|
359
|
-
if ('ssr' in opts) {
|
|
360
|
-
throw new Error(
|
|
361
|
-
'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'
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
367
|
resolve_opts = {
|
|
366
368
|
transformPageChunk: opts.transformPageChunk || default_transform,
|
|
367
369
|
filterSerializedResponseHeaders: opts.filterSerializedResponseHeaders || default_filter,
|
|
@@ -480,7 +482,7 @@ export async function respond(request, options, manifest, state) {
|
|
|
480
482
|
manifest,
|
|
481
483
|
state,
|
|
482
484
|
status: 404,
|
|
483
|
-
error: new
|
|
485
|
+
error: new SvelteKitError(404, 'Not Found', `Not found: ${event.url.pathname}`),
|
|
484
486
|
resolve_opts
|
|
485
487
|
});
|
|
486
488
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DEV } from 'esm-env';
|
|
2
2
|
import { json, text } from '../../exports/index.js';
|
|
3
|
-
import { coalesce_to_error } from '../../utils/error.js';
|
|
3
|
+
import { coalesce_to_error, get_message, get_status } from '../../utils/error.js';
|
|
4
4
|
import { negotiate } from '../../utils/http.js';
|
|
5
|
-
import { HttpError
|
|
5
|
+
import { HttpError } from '../control.js';
|
|
6
6
|
import { fix_stack_trace } from '../shared-server.js';
|
|
7
7
|
import { ENDPOINT_METHODS } from '../../constants.js';
|
|
8
8
|
|
|
@@ -70,7 +70,7 @@ export function static_error_page(options, status, message) {
|
|
|
70
70
|
*/
|
|
71
71
|
export async function handle_fatal_error(event, options, error) {
|
|
72
72
|
error = error instanceof HttpError ? error : coalesce_to_error(error);
|
|
73
|
-
const status = error
|
|
73
|
+
const status = get_status(error);
|
|
74
74
|
const body = await handle_error_and_jsonify(event, options, error);
|
|
75
75
|
|
|
76
76
|
// ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it
|
|
@@ -103,11 +103,10 @@ export async function handle_error_and_jsonify(event, options, error) {
|
|
|
103
103
|
fix_stack_trace(error);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
106
|
+
const status = get_status(error);
|
|
107
|
+
const message = get_message(error);
|
|
108
|
+
|
|
109
|
+
return (await options.hooks.handleError({ error, event, status, message })) ?? { message };
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
/**
|
|
@@ -149,6 +148,10 @@ export function stringify_uses(node) {
|
|
|
149
148
|
uses.push(`"dependencies":${JSON.stringify(Array.from(node.uses.dependencies))}`);
|
|
150
149
|
}
|
|
151
150
|
|
|
151
|
+
if (node.uses && node.uses.search_params.size > 0) {
|
|
152
|
+
uses.push(`"search_params":${JSON.stringify(Array.from(node.uses.search_params))}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
152
155
|
if (node.uses && node.uses.params.size > 0) {
|
|
153
156
|
uses.push(`"params":${JSON.stringify(Array.from(node.uses.params))}`);
|
|
154
157
|
}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* `$env/dynamic/private`
|
|
3
|
+
* @type {Record<string, string>}
|
|
4
|
+
*/
|
|
2
5
|
export let private_env = {};
|
|
3
6
|
|
|
4
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* `$env/dynamic/public`. When prerendering, this will be a proxy that forbids reads
|
|
9
|
+
* @type {Record<string, string>}
|
|
10
|
+
*/
|
|
5
11
|
export let public_env = {};
|
|
6
12
|
|
|
13
|
+
/**
|
|
14
|
+
* The same as `public_env`, but without the proxy. Use for `%sveltekit.env.PUBLIC_FOO%`
|
|
15
|
+
* @type {Record<string, string>}
|
|
16
|
+
*/
|
|
17
|
+
export let safe_public_env = {};
|
|
18
|
+
|
|
7
19
|
/** @param {any} error */
|
|
8
20
|
export let fix_stack_trace = (error) => error?.stack;
|
|
9
21
|
|
|
@@ -17,6 +29,11 @@ export function set_public_env(environment) {
|
|
|
17
29
|
public_env = environment;
|
|
18
30
|
}
|
|
19
31
|
|
|
32
|
+
/** @type {(environment: Record<string, string>) => void} */
|
|
33
|
+
export function set_safe_public_env(environment) {
|
|
34
|
+
safe_public_env = environment;
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
/** @param {(error: Error) => string} value */
|
|
21
38
|
export function set_fix_stack_trace(value) {
|
|
22
39
|
fix_stack_trace = value;
|
package/src/types/ambient.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* // interface Error {}
|
|
8
8
|
* // interface Locals {}
|
|
9
9
|
* // interface PageData {}
|
|
10
|
+
* // interface PageState {}
|
|
10
11
|
* // interface Platform {}
|
|
11
12
|
* }
|
|
12
13
|
* }
|
|
@@ -39,6 +40,11 @@ declare namespace App {
|
|
|
39
40
|
*/
|
|
40
41
|
export interface PageData {}
|
|
41
42
|
|
|
43
|
+
/**
|
|
44
|
+
* 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`.
|
|
45
|
+
*/
|
|
46
|
+
export interface PageState {}
|
|
47
|
+
|
|
42
48
|
/**
|
|
43
49
|
* If your adapter provides [platform-specific context](https://kit.svelte.dev/docs/adapters#platform-specific-context) via `event.platform`, you can specify it here.
|
|
44
50
|
*/
|
|
@@ -101,7 +107,7 @@ declare module '__sveltekit/paths' {
|
|
|
101
107
|
* > If a value for `config.kit.paths.assets` is specified, it will be replaced with `'/_svelte_kit_assets'` during `vite dev` or `vite preview`, since the assets don't yet live at their eventual URL.
|
|
102
108
|
*/
|
|
103
109
|
export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets';
|
|
104
|
-
export let relative: boolean
|
|
110
|
+
export let relative: boolean;
|
|
105
111
|
export function reset(): void;
|
|
106
112
|
export function override(paths: { base: string; assets: string }): void;
|
|
107
113
|
export function set_assets(path: string): void;
|
package/src/types/internal.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export interface ServerInternalModule {
|
|
|
31
31
|
set_assets(path: string): void;
|
|
32
32
|
set_private_env(environment: Record<string, string>): void;
|
|
33
33
|
set_public_env(environment: Record<string, string>): void;
|
|
34
|
+
set_safe_public_env(environment: Record<string, string>): void;
|
|
34
35
|
set_version(version: string): void;
|
|
35
36
|
set_fix_stack_trace(fix_stack_trace: (error: unknown) => string): void;
|
|
36
37
|
}
|
|
@@ -59,6 +60,7 @@ export interface BuildData {
|
|
|
59
60
|
imports: string[];
|
|
60
61
|
stylesheets: string[];
|
|
61
62
|
fonts: string[];
|
|
63
|
+
uses_env_dynamic_public: boolean;
|
|
62
64
|
} | null;
|
|
63
65
|
server_manifest: import('vite').Manifest;
|
|
64
66
|
}
|
|
@@ -330,10 +332,10 @@ export interface SSRNode {
|
|
|
330
332
|
export type SSRNodeLoader = () => Promise<SSRNode>;
|
|
331
333
|
|
|
332
334
|
export interface SSROptions {
|
|
335
|
+
app_dir: string;
|
|
333
336
|
app_template_contains_nonce: boolean;
|
|
334
337
|
csp: ValidatedConfig['kit']['csp'];
|
|
335
338
|
csrf_check_origin: boolean;
|
|
336
|
-
track_server_fetches: boolean;
|
|
337
339
|
embedded: boolean;
|
|
338
340
|
env_public_prefix: string;
|
|
339
341
|
env_private_prefix: string;
|
|
@@ -408,6 +410,7 @@ export interface Uses {
|
|
|
408
410
|
parent: boolean;
|
|
409
411
|
route: boolean;
|
|
410
412
|
url: boolean;
|
|
413
|
+
search_params: Set<string>;
|
|
411
414
|
}
|
|
412
415
|
|
|
413
416
|
export type ValidatedConfig = RecursiveRequired<Config>;
|
|
@@ -2,6 +2,8 @@ This module provides access to runtime environment variables, as defined by the
|
|
|
2
2
|
|
|
3
3
|
This module cannot be imported into client-side code.
|
|
4
4
|
|
|
5
|
+
Dynamic environment variables cannot be used during prerendering.
|
|
6
|
+
|
|
5
7
|
```ts
|
|
6
8
|
import { env } from '$env/dynamic/private';
|
|
7
9
|
console.log(env.DEPLOYMENT_SPECIFIC_VARIABLE);
|
|
@@ -2,6 +2,8 @@ Similar to [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dyn
|
|
|
2
2
|
|
|
3
3
|
Note that public dynamic environment variables must all be sent from the server to the client, causing larger network requests — when possible, use `$env/static/public` instead.
|
|
4
4
|
|
|
5
|
+
Dynamic environment variables cannot be used during prerendering.
|
|
6
|
+
|
|
5
7
|
```ts
|
|
6
8
|
import { env } from '$env/dynamic/public';
|
|
7
9
|
console.log(env.PUBLIC_DEPLOYMENT_SPECIFIC_VARIABLE);
|
package/src/utils/error.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { HttpError, SvelteKitError } from '../runtime/control.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @param {unknown} err
|
|
3
5
|
* @return {Error}
|
|
@@ -16,7 +18,21 @@ export function coalesce_to_error(err) {
|
|
|
16
18
|
* @param {unknown} error
|
|
17
19
|
*/
|
|
18
20
|
export function normalize_error(error) {
|
|
19
|
-
return /** @type {import('../runtime/control.js').Redirect |
|
|
21
|
+
return /** @type {import('../runtime/control.js').Redirect | HttpError | SvelteKitError | Error} */ (
|
|
20
22
|
error
|
|
21
23
|
);
|
|
22
24
|
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {unknown} error
|
|
28
|
+
*/
|
|
29
|
+
export function get_status(error) {
|
|
30
|
+
return error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {unknown} error
|
|
35
|
+
*/
|
|
36
|
+
export function get_message(error) {
|
|
37
|
+
return error instanceof SvelteKitError ? error.text : 'Internal Error';
|
|
38
|
+
}
|
package/src/utils/routing.js
CHANGED
|
@@ -91,7 +91,7 @@ export function parse_route_id(id) {
|
|
|
91
91
|
return '/' + result;
|
|
92
92
|
})
|
|
93
93
|
.join('')}/?$`
|
|
94
|
-
|
|
94
|
+
);
|
|
95
95
|
|
|
96
96
|
return { pattern, params };
|
|
97
97
|
}
|
|
@@ -214,3 +214,49 @@ function escape(str) {
|
|
|
214
214
|
.replace(/[.*+?^${}()|\\]/g, '\\$&')
|
|
215
215
|
);
|
|
216
216
|
}
|
|
217
|
+
|
|
218
|
+
const basic_param_pattern = /\[(\[)?(\.\.\.)?(\w+?)(?:=(\w+))?\]\]?/g;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Populate a route ID with params to resolve a pathname.
|
|
222
|
+
* @example
|
|
223
|
+
* ```js
|
|
224
|
+
* resolveRoute(
|
|
225
|
+
* `/blog/[slug]/[...somethingElse]`,
|
|
226
|
+
* {
|
|
227
|
+
* slug: 'hello-world',
|
|
228
|
+
* somethingElse: 'something/else'
|
|
229
|
+
* }
|
|
230
|
+
* ); // `/blog/hello-world/something/else`
|
|
231
|
+
* ```
|
|
232
|
+
* @param {string} id
|
|
233
|
+
* @param {Record<string, string | undefined>} params
|
|
234
|
+
* @returns {string}
|
|
235
|
+
*/
|
|
236
|
+
export function resolve_route(id, params) {
|
|
237
|
+
const segments = get_route_segments(id);
|
|
238
|
+
return (
|
|
239
|
+
'/' +
|
|
240
|
+
segments
|
|
241
|
+
.map((segment) =>
|
|
242
|
+
segment.replace(basic_param_pattern, (_, optional, rest, name) => {
|
|
243
|
+
const param_value = params[name];
|
|
244
|
+
|
|
245
|
+
// This is nested so TS correctly narrows the type
|
|
246
|
+
if (!param_value) {
|
|
247
|
+
if (optional) return '';
|
|
248
|
+
if (rest && param_value !== undefined) return '';
|
|
249
|
+
throw new Error(`Missing parameter '${name}' in route ${id}`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (param_value.startsWith('/') || param_value.endsWith('/'))
|
|
253
|
+
throw new Error(
|
|
254
|
+
`Parameter '${name}' in route ${id} cannot start or end with a slash -- this would cause an invalid route like foo//bar`
|
|
255
|
+
);
|
|
256
|
+
return param_value;
|
|
257
|
+
})
|
|
258
|
+
)
|
|
259
|
+
.filter(Boolean)
|
|
260
|
+
.join('/')
|
|
261
|
+
);
|
|
262
|
+
}
|