@sveltejs/kit 3.0.0-next.18 → 3.0.0-next.19
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 +12 -5
- package/src/cli.js +1 -1
- package/src/constants.js +3 -0
- package/src/core/config/index.js +1 -1
- package/src/core/env.js +1 -1
- package/src/core/postbuild/analyse.js +1 -1
- package/src/core/postbuild/prerender.js +1 -1
- package/src/core/sync/create_manifest_data/index.js +9 -0
- package/src/core/sync/sync.js +22 -9
- package/src/core/sync/ts.js +1 -1
- package/src/core/sync/write_app_types.js +1 -1
- package/src/core/sync/write_client_manifest.js +1 -1
- package/src/core/sync/write_server.js +1 -3
- package/src/core/sync/write_tsconfig/index.js +1 -1
- package/src/core/sync/write_types/index.js +6 -3
- package/src/exports/index.js +9 -9
- package/src/exports/internal/server/event.js +1 -1
- package/src/exports/internal/server/telemetry.js +1 -1
- package/src/exports/internal/shared.js +9 -0
- package/src/exports/{params.js → params/index.js} +6 -4
- package/src/exports/params/public.d.ts +63 -0
- package/src/exports/public.d.ts +77 -447
- package/src/exports/vite/build/build_server.js +2 -2
- package/src/exports/vite/dev/index.js +2 -3
- package/src/exports/vite/index.js +14 -3
- package/src/pathname.js +55 -0
- package/src/runtime/app/{forms.js → forms/index.js} +9 -8
- package/src/runtime/app/forms/public.d.ts +2 -0
- package/src/runtime/app/forms/types.d.ts +56 -0
- package/src/runtime/app/{navigation.js → navigation/index.js} +2 -2
- package/src/runtime/app/navigation/public.d.ts +237 -0
- package/src/runtime/app/paths/client.js +14 -8
- package/src/runtime/app/paths/index.js +1 -1
- package/src/runtime/app/paths/internal/client.js +4 -0
- package/src/runtime/app/paths/internal/server.js +4 -0
- package/src/runtime/app/paths/internal.d.ts +3 -0
- package/src/runtime/app/paths/public.d.ts +1 -1
- package/src/runtime/app/paths/server.js +6 -4
- package/src/runtime/app/server/index.js +1 -1
- package/src/runtime/app/server/remote/form.js +3 -4
- package/src/runtime/app/server/remote/prerender.js +3 -3
- package/src/runtime/app/server/remote/shared.js +3 -10
- package/src/runtime/app/state/index.js +4 -2
- package/src/runtime/app/state/public.d.ts +72 -0
- package/src/runtime/app/stores.js +2 -2
- package/src/runtime/client/client.js +65 -54
- package/src/runtime/client/entry.js +2 -2
- package/src/runtime/client/remote-functions/command.svelte.js +36 -34
- package/src/runtime/client/remote-functions/form.svelte.js +76 -78
- package/src/runtime/client/remote-functions/prerender.svelte.js +3 -3
- package/src/runtime/client/remote-functions/query/index.js +1 -1
- package/src/runtime/client/remote-functions/query/instance.svelte.js +4 -3
- package/src/runtime/client/remote-functions/query-batch.svelte.js +3 -3
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +5 -5
- package/src/runtime/client/remote-functions/query-live/iterator.js +5 -7
- package/src/runtime/client/remote-functions/shared.svelte.js +9 -14
- package/src/runtime/client/state.svelte.js +5 -3
- package/src/runtime/client/types.d.ts +2 -1
- package/src/runtime/pathname.js +6 -61
- package/src/runtime/props.svelte.js +1 -1
- package/src/runtime/server/constants.js +0 -3
- package/src/runtime/server/errors.js +53 -28
- package/src/runtime/server/fetch.js +1 -1
- package/src/runtime/server/index.js +9 -14
- package/src/runtime/server/page/actions.js +2 -1
- package/src/runtime/server/page/index.js +7 -3
- package/src/runtime/server/page/load_data.js +1 -1
- package/src/runtime/server/page/render.js +17 -11
- package/src/runtime/server/page/server_routing.js +3 -2
- package/src/runtime/server/remote-functions.js +3 -2
- package/src/runtime/server/respond.js +4 -8
- package/src/runtime/server/state.js +3 -6
- package/src/types/ambient.d.ts +1 -1
- package/src/types/internal.d.ts +8 -10
- package/src/types/private.d.ts +12 -3
- package/src/utils/error.js +30 -14
- package/src/utils/page_nodes.js +3 -2
- package/src/utils/params.js +3 -2
- package/src/utils/routing.js +5 -4
- package/src/version.js +1 -1
- package/types/index.d.ts +992 -932
- package/types/index.d.ts.map +43 -31
- /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
package/src/pathname.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const DATA_SUFFIX = '/__data.json';
|
|
2
|
+
const HTML_DATA_SUFFIX = '.html__data.json';
|
|
3
|
+
|
|
4
|
+
/** @param {string} pathname */
|
|
5
|
+
export function has_data_suffix(pathname) {
|
|
6
|
+
return pathname.endsWith(DATA_SUFFIX) || pathname.endsWith(HTML_DATA_SUFFIX);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** @param {string} pathname */
|
|
10
|
+
export function add_data_suffix(pathname) {
|
|
11
|
+
if (pathname.endsWith('.html')) return pathname.replace(/\.html$/, HTML_DATA_SUFFIX);
|
|
12
|
+
return pathname.replace(/\/$/, '') + DATA_SUFFIX;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** @param {string} pathname */
|
|
16
|
+
export function strip_data_suffix(pathname) {
|
|
17
|
+
if (pathname.endsWith(HTML_DATA_SUFFIX)) {
|
|
18
|
+
return pathname.slice(0, -HTML_DATA_SUFFIX.length) + '.html';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return pathname.slice(0, -DATA_SUFFIX.length);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ROUTE_SUFFIX = '/__route.js';
|
|
25
|
+
const HTML_ROUTE_SUFFIX = '.html__route.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} pathname
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
export function has_resolution_suffix(pathname) {
|
|
32
|
+
return pathname.endsWith(ROUTE_SUFFIX) || pathname.endsWith(HTML_ROUTE_SUFFIX);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Convert a regular URL to a route to send to SvelteKit's server-side route resolution endpoint
|
|
37
|
+
* @param {string} pathname
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
export function add_resolution_suffix(pathname) {
|
|
41
|
+
if (pathname.endsWith('.html')) return pathname.replace(/\.html$/, HTML_ROUTE_SUFFIX);
|
|
42
|
+
return pathname.replace(/\/$/, '') + ROUTE_SUFFIX;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {string} pathname
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
49
|
+
export function strip_resolution_suffix(pathname) {
|
|
50
|
+
if (pathname.endsWith(HTML_ROUTE_SUFFIX)) {
|
|
51
|
+
return pathname.slice(0, -HTML_ROUTE_SUFFIX.length) + '.html';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return pathname.slice(0, -ROUTE_SUFFIX.length);
|
|
55
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
/** @import { ActionResult, SubmitFunction } from './types.js' */
|
|
1
2
|
import { DEV } from 'esm-env';
|
|
2
|
-
import { noop } from '
|
|
3
|
-
import { refreshAll } from '
|
|
3
|
+
import { noop } from '../../../utils/functions.js';
|
|
4
|
+
import { refreshAll } from '../navigation/index.js';
|
|
4
5
|
import {
|
|
5
6
|
applyAction,
|
|
6
7
|
apply_action_navigation,
|
|
7
8
|
handle_error,
|
|
8
9
|
is_current_location
|
|
9
|
-
} from '
|
|
10
|
-
import { notify_version } from '
|
|
10
|
+
} from '../../client/client.js';
|
|
11
|
+
import { notify_version } from '../../client/state.svelte.js';
|
|
11
12
|
import { parse } from '#app/internal/transport';
|
|
12
13
|
|
|
13
14
|
export { applyAction };
|
|
@@ -32,7 +33,7 @@ export { applyAction };
|
|
|
32
33
|
* @template {Record<string, unknown> | undefined} Success
|
|
33
34
|
* @template {Record<string, unknown> | undefined} Failure
|
|
34
35
|
* @param {string} result
|
|
35
|
-
* @returns {
|
|
36
|
+
* @returns {ActionResult<Success, Failure>}
|
|
36
37
|
*/
|
|
37
38
|
export function deserialize(result) {
|
|
38
39
|
const parsed = JSON.parse(result);
|
|
@@ -79,7 +80,7 @@ function clone(element) {
|
|
|
79
80
|
* @template {Record<string, unknown> | undefined} Success
|
|
80
81
|
* @template {Record<string, unknown> | undefined} Failure
|
|
81
82
|
* @param {HTMLFormElement} form_element The form element
|
|
82
|
-
* @param {
|
|
83
|
+
* @param {SubmitFunction<Success, Failure>} submit Submit callback
|
|
83
84
|
*/
|
|
84
85
|
export function enhance(form_element, submit = noop) {
|
|
85
86
|
if (DEV && clone(form_element).method !== 'post') {
|
|
@@ -88,7 +89,7 @@ export function enhance(form_element, submit = noop) {
|
|
|
88
89
|
|
|
89
90
|
/**
|
|
90
91
|
* @param {{
|
|
91
|
-
* result:
|
|
92
|
+
* result: ActionResult;
|
|
92
93
|
* reset?: boolean;
|
|
93
94
|
* refreshAll?: boolean;
|
|
94
95
|
* invalidateAll?: boolean;
|
|
@@ -182,7 +183,7 @@ export function enhance(form_element, submit = noop) {
|
|
|
182
183
|
})) ?? fallback_callback;
|
|
183
184
|
if (cancelled) return;
|
|
184
185
|
|
|
185
|
-
/** @type {
|
|
186
|
+
/** @type {ActionResult} */
|
|
186
187
|
let result;
|
|
187
188
|
|
|
188
189
|
try {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// kept separate from public.d.ts so generated $types can resolve these without pulling in the runtime graph
|
|
2
|
+
import type { MaybePromise } from '../../../types/private.js';
|
|
3
|
+
/**
|
|
4
|
+
* When calling a form action via fetch, the response will be one of these shapes.
|
|
5
|
+
* ```svelte
|
|
6
|
+
* <form method="post" use:enhance={() => {
|
|
7
|
+
* return ({ result }) => {
|
|
8
|
+
* // result is of type ActionResult
|
|
9
|
+
* };
|
|
10
|
+
* }}
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Success and failure results carry the root-relative `pathname + search` of the action URL, with
|
|
14
|
+
* the `?/actionName` parameter removed. Redirect results carry the redirect target. Server-generated
|
|
15
|
+
* error results also carry the action location, while client-generated errors such as network
|
|
16
|
+
* failures do not. `update` uses this location to emulate native form navigation.
|
|
17
|
+
*/
|
|
18
|
+
export type ActionResult<
|
|
19
|
+
Success extends Record<string, unknown> | undefined = Record<string, any>,
|
|
20
|
+
Failure extends Record<string, unknown> | undefined = Record<string, any>
|
|
21
|
+
> =
|
|
22
|
+
| { type: 'success'; status: number; data?: Success; location: string }
|
|
23
|
+
| { type: 'failure'; status: number; data?: Failure; location: string }
|
|
24
|
+
| { type: 'redirect'; status: number; location: string }
|
|
25
|
+
| { type: 'error'; status?: number; error: App.Error; location?: string };
|
|
26
|
+
|
|
27
|
+
export type SubmitFunction<
|
|
28
|
+
Success extends Record<string, unknown> | undefined = Record<string, any>,
|
|
29
|
+
Failure extends Record<string, unknown> | undefined = Record<string, any>
|
|
30
|
+
> = (input: {
|
|
31
|
+
action: URL;
|
|
32
|
+
formData: FormData;
|
|
33
|
+
formElement: HTMLFormElement;
|
|
34
|
+
controller: AbortController;
|
|
35
|
+
submitter: HTMLElement | null;
|
|
36
|
+
cancel: () => void;
|
|
37
|
+
}) => MaybePromise<
|
|
38
|
+
| void
|
|
39
|
+
| ((opts: {
|
|
40
|
+
formData: FormData;
|
|
41
|
+
formElement: HTMLFormElement;
|
|
42
|
+
action: URL;
|
|
43
|
+
result: ActionResult<Success, Failure>;
|
|
44
|
+
/**
|
|
45
|
+
* Call this to get the default behavior of a form submission response.
|
|
46
|
+
* @param options Set `reset: false` if you don't want the `<form>` values to be reset after a successful submission. `refreshAll` defaults to `true` for successful results and `false` for failures. When the submission navigates, setting it to `false` still runs the destination's `load` functions but may reuse shared layout data. Set `navigate: false` to apply non-redirect results to the current page instead of navigating to `result.location`. Redirects are always followed.
|
|
47
|
+
*/
|
|
48
|
+
update: (options?: {
|
|
49
|
+
reset?: boolean;
|
|
50
|
+
refreshAll?: boolean;
|
|
51
|
+
navigate?: boolean;
|
|
52
|
+
/** @deprecated Use `refreshAll` instead. */
|
|
53
|
+
invalidateAll?: boolean;
|
|
54
|
+
}) => Promise<void>;
|
|
55
|
+
}) => MaybePromise<void>)
|
|
56
|
+
>;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types';
|
|
2
|
+
|
|
3
|
+
export * from './index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Information about the target of a specific navigation.
|
|
7
|
+
*/
|
|
8
|
+
export interface NavigationTarget<
|
|
9
|
+
Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>,
|
|
10
|
+
RouteId extends AppRouteId | null = AppRouteId | null
|
|
11
|
+
> {
|
|
12
|
+
/**
|
|
13
|
+
* Parameters of the target page - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object.
|
|
14
|
+
* Is `null` if the target is not part of the SvelteKit app (could not be resolved to a route).
|
|
15
|
+
*/
|
|
16
|
+
params: Params | null;
|
|
17
|
+
/**
|
|
18
|
+
* Info about the target route
|
|
19
|
+
*/
|
|
20
|
+
route: {
|
|
21
|
+
/**
|
|
22
|
+
* The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched.
|
|
23
|
+
*/
|
|
24
|
+
id: RouteId | null;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The URL that is navigated to
|
|
28
|
+
*/
|
|
29
|
+
url: URL;
|
|
30
|
+
/**
|
|
31
|
+
* The scroll position associated with this navigation.
|
|
32
|
+
*
|
|
33
|
+
* For the `from` target, this is the scroll position at the moment of navigation.
|
|
34
|
+
*
|
|
35
|
+
* For the `to` target, this represents the scroll position that will be or was restored:
|
|
36
|
+
* - In `beforeNavigate` and `onNavigate`, this is only available for `popstate` navigations (back/forward button)
|
|
37
|
+
* and will be `null` for other navigation types, since the final scroll position isn't known
|
|
38
|
+
* ahead of time.
|
|
39
|
+
* - In `afterNavigate`, this is always the scroll position that was applied after the navigation
|
|
40
|
+
* completed.
|
|
41
|
+
*/
|
|
42
|
+
scroll: { x: number; y: number } | null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface GotoOptions {
|
|
46
|
+
/**
|
|
47
|
+
* If `true`, replaces the current history entry rather than creating a new one.
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
replace?: boolean;
|
|
51
|
+
/** @deprecated Use `replace` instead. */
|
|
52
|
+
replaceState?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* If `true`, updates the URL and `page.state` without navigating.
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
|
+
shallow?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* If `true`, resets the scroll position (to the top of the page, or to the element
|
|
60
|
+
* matching the URL's `#hash` if there is one) and resets focus (to the `<body>`, or the
|
|
61
|
+
* `autofocus` element if there is one) once the navigation completes.
|
|
62
|
+
*
|
|
63
|
+
* If `false`, the current scroll position and focused element are left alone.
|
|
64
|
+
* @default true, or false when `shallow` is true
|
|
65
|
+
*/
|
|
66
|
+
reset?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* If `true`, reruns all `load` functions and queries of the page.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
refreshAll?: boolean;
|
|
72
|
+
/** Causes any `load` functions to rerun if they depend on one of the URLs. */
|
|
73
|
+
invalidate?: Array<string | URL | ((url: URL) => boolean)>;
|
|
74
|
+
/** @deprecated Use `refreshAll` instead. */
|
|
75
|
+
invalidateAll?: boolean;
|
|
76
|
+
/** An optional object that will be available as `page.state`. */
|
|
77
|
+
state?: App.PageState;
|
|
78
|
+
/**
|
|
79
|
+
* If `true`, `page.state` will be restored after a full page reload.
|
|
80
|
+
* @default false
|
|
81
|
+
*/
|
|
82
|
+
persistState?: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* - `enter`: The app has hydrated/started
|
|
87
|
+
* - `form`: The user submitted a `<form method="GET">`
|
|
88
|
+
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
|
|
89
|
+
* - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring
|
|
90
|
+
* - `link`: Navigation was triggered by a link click
|
|
91
|
+
* - `popstate`: Navigation was triggered by back/forward navigation
|
|
92
|
+
*/
|
|
93
|
+
export type NavigationType = 'enter' | 'form' | 'leave' | 'link' | 'goto' | 'popstate';
|
|
94
|
+
|
|
95
|
+
export interface NavigationBase {
|
|
96
|
+
/**
|
|
97
|
+
* The type of navigation:
|
|
98
|
+
* - `enter`: The app has hydrated/started
|
|
99
|
+
* - `form`: The user submitted a `<form method="GET">`
|
|
100
|
+
* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect
|
|
101
|
+
* - `leave`: The app is being left either because the tab is being closed or a navigation to a different document is occurring
|
|
102
|
+
* - `link`: Navigation was triggered by a link click
|
|
103
|
+
* - `popstate`: Navigation was triggered by back/forward navigation
|
|
104
|
+
*/
|
|
105
|
+
type: NavigationType;
|
|
106
|
+
/** Whether this is a shallow navigation. */
|
|
107
|
+
shallow: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Where navigation was triggered from
|
|
110
|
+
*/
|
|
111
|
+
from: NavigationTarget | null;
|
|
112
|
+
/**
|
|
113
|
+
* Where navigation is going to/has gone to
|
|
114
|
+
*/
|
|
115
|
+
to: NavigationTarget | null;
|
|
116
|
+
/**
|
|
117
|
+
* Whether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation).
|
|
118
|
+
*/
|
|
119
|
+
willUnload: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* A promise that resolves once the navigation is complete, and rejects if the navigation
|
|
122
|
+
* fails or is aborted. In the case of a `willUnload` navigation, the promise will never resolve
|
|
123
|
+
*/
|
|
124
|
+
complete: Promise<void>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The navigation that occurs when the app starts/hydrates
|
|
129
|
+
*/
|
|
130
|
+
export interface NavigationEnter extends NavigationBase {
|
|
131
|
+
type: 'enter';
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* In case of a history back/forward navigation, the number of steps to go back/forward
|
|
135
|
+
*/
|
|
136
|
+
delta?: undefined;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Dispatched `Event` object when navigation occurred by `popstate` or `link`.
|
|
140
|
+
*/
|
|
141
|
+
event?: undefined;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export type NavigationExternal = NavigationGoto | NavigationLeave;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* A navigation triggered by a `goto(...)` call or a redirect
|
|
148
|
+
*/
|
|
149
|
+
export interface NavigationGoto extends NavigationBase {
|
|
150
|
+
type: 'goto';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* A navigation triggered by the tab being closed, or the user navigating to a different document
|
|
155
|
+
*/
|
|
156
|
+
export interface NavigationLeave extends NavigationBase {
|
|
157
|
+
type: 'leave';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* A navigation triggered by a `<form method="GET">`
|
|
162
|
+
*/
|
|
163
|
+
export interface NavigationFormSubmit extends NavigationBase {
|
|
164
|
+
type: 'form';
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The `SubmitEvent` that caused the navigation
|
|
168
|
+
*/
|
|
169
|
+
event: SubmitEvent;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* A navigation triggered by back/forward navigation
|
|
174
|
+
*/
|
|
175
|
+
export interface NavigationPopState extends NavigationBase {
|
|
176
|
+
type: 'popstate';
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* In case of a history back/forward navigation, the number of steps to go back/forward
|
|
180
|
+
*/
|
|
181
|
+
delta: number;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The `PopStateEvent` that caused the navigation
|
|
185
|
+
*/
|
|
186
|
+
event: PopStateEvent;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* A navigation triggered by a link click
|
|
191
|
+
*/
|
|
192
|
+
export interface NavigationLink extends NavigationBase {
|
|
193
|
+
type: 'link';
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The `PointerEvent` that caused the navigation
|
|
197
|
+
*/
|
|
198
|
+
event: PointerEvent;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type Navigation =
|
|
202
|
+
| NavigationExternal
|
|
203
|
+
| NavigationFormSubmit
|
|
204
|
+
| NavigationPopState
|
|
205
|
+
| NavigationLink;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* The argument passed to [`beforeNavigate`](https://svelte.dev/docs/kit/$app-navigation#beforeNavigate) callbacks.
|
|
209
|
+
*/
|
|
210
|
+
export type BeforeNavigate = Navigation & {
|
|
211
|
+
/**
|
|
212
|
+
* Call this to prevent the navigation from starting.
|
|
213
|
+
*/
|
|
214
|
+
cancel: () => void;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* The argument passed to [`onNavigate`](https://svelte.dev/docs/kit/$app-navigation#onNavigate) callbacks.
|
|
219
|
+
*/
|
|
220
|
+
export type OnNavigate = Navigation & {
|
|
221
|
+
type: Exclude<NavigationType, 'enter' | 'leave'>;
|
|
222
|
+
/**
|
|
223
|
+
* Since `onNavigate` callbacks are called immediately before a client-side navigation, they will never be called with a navigation that unloads the page.
|
|
224
|
+
*/
|
|
225
|
+
willUnload: false;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The argument passed to [`afterNavigate`](https://svelte.dev/docs/kit/$app-navigation#afterNavigate) callbacks.
|
|
230
|
+
*/
|
|
231
|
+
export type AfterNavigate = (Navigation | NavigationEnter) & {
|
|
232
|
+
type: Exclude<NavigationType, 'leave'>;
|
|
233
|
+
/**
|
|
234
|
+
* Since `afterNavigate` callbacks are called after a navigation completes, they will never be called with a navigation that unloads the page.
|
|
235
|
+
*/
|
|
236
|
+
willUnload: false;
|
|
237
|
+
};
|
|
@@ -4,6 +4,8 @@ import { base, assets, hash_routing, match_implementation } from './internal/cli
|
|
|
4
4
|
import { resolve_route } from '../../../utils/routing.js';
|
|
5
5
|
import { DEV } from 'esm-env';
|
|
6
6
|
|
|
7
|
+
export { base, assets, app_dir } from './internal/client.js';
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* Resolve the URL of an asset in your `static` directory, by prefixing it with [`config.paths.assets`](https://svelte.dev/docs/kit/configuration#paths) if configured, or otherwise by prefixing it with the base path.
|
|
9
11
|
*
|
|
@@ -23,16 +25,18 @@ import { DEV } from 'esm-env';
|
|
|
23
25
|
* @returns {string}
|
|
24
26
|
*/
|
|
25
27
|
export function asset(file) {
|
|
28
|
+
let path = /** @type {string} */ (file);
|
|
29
|
+
|
|
26
30
|
// TODO 4.0 remove this
|
|
27
|
-
if (
|
|
31
|
+
if (path[0] === '/') {
|
|
28
32
|
if (DEV) {
|
|
29
|
-
console.warn(`\`asset('${
|
|
33
|
+
console.warn(`\`asset('${path}')\` should now be \`asset('${path.slice(1)}')\``);
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
path = path.slice(1);
|
|
33
37
|
}
|
|
34
38
|
|
|
35
|
-
return (assets || base) + '/' +
|
|
39
|
+
return (assets || base) + '/' + path;
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
const pathname_prefix = hash_routing ? '#' : '';
|
|
@@ -61,18 +65,20 @@ const pathname_prefix = hash_routing ? '#' : '';
|
|
|
61
65
|
* @returns {ResolvedPathname}
|
|
62
66
|
*/
|
|
63
67
|
export function resolve(...args) {
|
|
64
|
-
|
|
65
|
-
const [id, params] = args;
|
|
68
|
+
const [id, params] = /** @type {[string, Record<string, string>?]} */ (args);
|
|
66
69
|
|
|
70
|
+
if (id[0] === '/') {
|
|
67
71
|
// route ID
|
|
68
72
|
if (id.includes('[') && !params) {
|
|
69
73
|
throw new Error(`Missing params for dynamic route ID ${id}`);
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
/** @type {ResolvedPathname} */ (base + pathname_prefix + resolve_route(id, params ?? {}))
|
|
78
|
+
);
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
return base + pathname_prefix + '/' +
|
|
81
|
+
return /** @type {ResolvedPathname} */ (base + pathname_prefix + '/' + id);
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { asset, resolve, match } from '#app/paths';
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// TODO get rid of this module — merge the contents into `../client.js`, and expose it to the
|
|
2
|
+
// rest of the codebase as `#app/paths/client`, with an export condition that errors if
|
|
3
|
+
// it is imported on the server
|
|
4
|
+
|
|
1
5
|
/** @import { RouteId } from '$app/types' */
|
|
2
6
|
import { payload } from '../../../client/payload.js';
|
|
3
7
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// TODO get rid of this module — merge the contents into `../server.js`, and expose it to the
|
|
2
|
+
// rest of the codebase as `#app/paths/server`, with an export condition that errors if
|
|
3
|
+
// it is imported on the client
|
|
4
|
+
|
|
1
5
|
export const base = __SVELTEKIT_PATHS_BASE__;
|
|
2
6
|
export let assets = __SVELTEKIT_PATHS_ASSETS__ || base;
|
|
3
7
|
export const app_dir = __SVELTEKIT_APP_DIR__;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { asset, resolve, match } from './client.js';
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { base, assets, relative } from './internal/server.js';
|
|
2
2
|
import { resolve_route, find_route } from '../../../utils/routing.js';
|
|
3
3
|
import { decode_pathname } from '../../../utils/url.js';
|
|
4
|
-
import { add_data_suffix } from '
|
|
4
|
+
import { add_data_suffix } from '../../../pathname.js';
|
|
5
5
|
import { try_get_request_store } from '@sveltejs/kit/internal/server';
|
|
6
6
|
import { manifest } from '../../server/internal.js';
|
|
7
7
|
import { get_hooks } from '__SERVER__/internal.js';
|
|
8
8
|
import { DEV } from 'esm-env';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
export { base, assets, app_dir } from './internal/server.js';
|
|
11
|
+
|
|
12
|
+
/** @type {typeof import('./client.js').asset} */
|
|
11
13
|
export function asset(file) {
|
|
12
14
|
// TODO 4.0 remove this
|
|
13
15
|
if (file[0] === '/') {
|
|
@@ -21,7 +23,7 @@ export function asset(file) {
|
|
|
21
23
|
return assets !== base ? `${assets}/${file}` : resolve(file);
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
/** @type {import('./client.js').resolve} */
|
|
26
|
+
/** @type {typeof import('./client.js').resolve} */
|
|
25
27
|
export function resolve(id, params) {
|
|
26
28
|
let resolved;
|
|
27
29
|
|
|
@@ -56,7 +58,7 @@ export function resolve(id, params) {
|
|
|
56
58
|
return base + resolved;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
/** @type {import('./client.js').match} */
|
|
61
|
+
/** @type {typeof import('./client.js').match} */
|
|
60
62
|
export async function match(url) {
|
|
61
63
|
const store = try_get_request_store();
|
|
62
64
|
|
|
@@ -72,8 +72,7 @@ export function form(validate_or_fn, maybe_fn) {
|
|
|
72
72
|
* @param {string | number | boolean} [key]
|
|
73
73
|
*/
|
|
74
74
|
function create_instance(key) {
|
|
75
|
-
/** @type {RemoteForm<Input, Output>} */
|
|
76
|
-
const instance = {};
|
|
75
|
+
const instance = /** @type {RemoteForm<Input, Output>} */ ({});
|
|
77
76
|
|
|
78
77
|
instance.method = 'POST';
|
|
79
78
|
|
|
@@ -89,8 +88,8 @@ export function form(validate_or_fn, maybe_fn) {
|
|
|
89
88
|
name: '',
|
|
90
89
|
id: '',
|
|
91
90
|
fn: async (data, meta, form_data) => {
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
const output =
|
|
92
|
+
/** @type {{ submission: true, input?: Record<string, any>, issues?: InternalRemoteFormIssue[], result: Output }} */ ({});
|
|
94
93
|
|
|
95
94
|
// make it possible to differentiate between user submission and programmatic `field.set(...)` updates
|
|
96
95
|
output.submission = true;
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
/** @import { RemoteFunctionResponse, RemotePrerenderInputsGenerator, RemotePrerenderInternals, MaybePromise } from 'types' */
|
|
3
3
|
/** @import { StandardSchemaV1 } from '@standard-schema/spec' */
|
|
4
4
|
import { json } from '@sveltejs/kit';
|
|
5
|
-
import {
|
|
5
|
+
import { HandledHttpError } from '@sveltejs/kit/internal';
|
|
6
6
|
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
7
7
|
import { stringify_remote_arg } from '../../../shared.js';
|
|
8
8
|
import { parse, stringify } from '#app/internal/transport';
|
|
9
9
|
import { noop } from '../../../../utils/functions.js';
|
|
10
|
-
import { app_dir, base } from '
|
|
10
|
+
import { app_dir, base } from '#app/paths';
|
|
11
11
|
import { create_validator, get_response, run_remote_function } from './shared.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -114,7 +114,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
114
114
|
|
|
115
115
|
if (prerendered) {
|
|
116
116
|
if (prerendered.type === 'error') {
|
|
117
|
-
throw new
|
|
117
|
+
throw new HandledHttpError(prerendered.error);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
return parse(prerendered.data)._;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/** @import { RequestEvent } from '@sveltejs/kit' */
|
|
2
2
|
/** @import { MaybePromise, RequestState, RemoteInternals, RequestStore, RemoteLiveQueryUserFunctionReturnType } from 'types' */
|
|
3
3
|
import { error } from '@sveltejs/kit';
|
|
4
|
-
import {
|
|
4
|
+
import { ValidationError } from '@sveltejs/kit/internal';
|
|
5
|
+
import { with_request_store } from '@sveltejs/kit/internal/server';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @param {any} validate_or_fn
|
|
@@ -26,19 +27,12 @@ export function create_validator(validate_or_fn, maybe_fn) {
|
|
|
26
27
|
// use https://standardschema.dev validator if provided
|
|
27
28
|
if ('~standard' in validate_or_fn) {
|
|
28
29
|
return async (arg) => {
|
|
29
|
-
// Get event before async validation to ensure it's available in server environments without AsyncLocalStorage, too
|
|
30
|
-
const { event, state } = get_request_store();
|
|
31
|
-
|
|
32
30
|
// access property and call method in one go to preserve potential this context
|
|
33
31
|
const result = await validate_or_fn['~standard'].validate(arg);
|
|
34
32
|
|
|
35
33
|
// if the `issues` field exists, the validation failed
|
|
36
34
|
if (result.issues) {
|
|
37
|
-
|
|
38
|
-
issues: result.issues,
|
|
39
|
-
event: state.original_event ?? event
|
|
40
|
-
});
|
|
41
|
-
error(body.status ?? 400, body);
|
|
35
|
+
throw new ValidationError(result.issues);
|
|
42
36
|
}
|
|
43
37
|
|
|
44
38
|
return result.value;
|
|
@@ -137,7 +131,6 @@ function derive_remote_function_event(event, state, allow_cookies) {
|
|
|
137
131
|
event: derived,
|
|
138
132
|
state: {
|
|
139
133
|
...state,
|
|
140
|
-
original_event: state.original_event ?? event,
|
|
141
134
|
is_in_remote_function: true
|
|
142
135
|
}
|
|
143
136
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** @import { Navigation } from '$app/navigation' */
|
|
2
|
+
/** @import { Page } from '$app/state' */
|
|
1
3
|
import {
|
|
2
4
|
page as client_page,
|
|
3
5
|
navigating as client_navigating,
|
|
@@ -45,14 +47,14 @@ import { BROWSER } from 'esm-env';
|
|
|
45
47
|
*
|
|
46
48
|
* On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time.
|
|
47
49
|
*
|
|
48
|
-
* @type {
|
|
50
|
+
* @type {Page}
|
|
49
51
|
*/
|
|
50
52
|
export const page = BROWSER ? client_page : server_page;
|
|
51
53
|
|
|
52
54
|
/**
|
|
53
55
|
* A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties.
|
|
54
56
|
* Values are `null` when no navigation is occurring, or during server rendering.
|
|
55
|
-
* @type {
|
|
57
|
+
* @type {Navigation | { from: null, to: null, type: null, willUnload: null, delta: null, complete: null }}
|
|
56
58
|
*/
|
|
57
59
|
// @ts-expect-error
|
|
58
60
|
export const navigating = BROWSER ? client_navigating : server_navigating;
|