@sveltejs/kit 3.0.0-next.2 → 3.0.0-next.21
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 +62 -36
- package/src/cli.js +15 -12
- package/src/constants.js +6 -1
- package/src/core/adapt/builder.js +66 -72
- package/src/core/adapt/index.js +17 -6
- package/src/core/config/index.js +134 -80
- package/src/core/config/options.js +295 -273
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +146 -16
- package/src/core/generate_manifest/index.js +18 -15
- package/src/core/postbuild/analyse.js +8 -20
- package/src/core/postbuild/crawl.js +22 -6
- package/src/core/postbuild/entities.js +8 -2
- package/src/core/postbuild/fallback.js +4 -2
- package/src/core/postbuild/prerender.js +222 -70
- package/src/core/postbuild/queue.js +2 -1
- package/src/core/sync/create_manifest_data/conflict.js +1 -1
- package/src/core/sync/create_manifest_data/index.js +82 -62
- package/src/core/sync/sync.js +40 -31
- package/src/core/sync/ts.js +1 -1
- package/src/core/sync/utils.js +22 -2
- package/src/core/sync/{write_non_ambient.js → write_app_types.js} +107 -58
- package/src/core/sync/write_client_manifest.js +14 -29
- package/src/core/sync/write_env.js +7 -5
- package/src/core/sync/write_server.js +37 -45
- package/src/core/sync/write_tsconfig/index.js +274 -0
- package/src/core/sync/write_tsconfig/test-app/package.json +7 -0
- package/src/core/sync/write_tsconfig/utils.js +77 -0
- package/src/core/sync/write_tsconfig/validate.js +128 -0
- package/src/core/sync/write_types/index.js +127 -123
- package/src/core/utils.js +30 -5
- package/src/exports/env/index.js +77 -0
- package/src/exports/env/public.d.ts +55 -0
- package/src/exports/hooks/index.js +3 -9
- package/src/exports/hooks/public.d.ts +195 -0
- package/src/exports/hooks/sequence.js +9 -6
- package/src/exports/index.js +52 -29
- package/src/exports/internal/client.js +5 -0
- package/src/exports/internal/env.js +8 -5
- package/src/exports/internal/index.js +1 -90
- package/src/exports/internal/{event.js → server/event.js} +2 -3
- package/src/exports/internal/server/index.js +37 -0
- package/src/exports/internal/server/telemetry.js +95 -0
- package/src/exports/internal/shared.js +90 -0
- package/src/exports/node/index.js +64 -22
- package/src/exports/params/index.js +70 -0
- package/src/exports/params/public.d.ts +63 -0
- package/src/exports/public.d.ts +50 -1733
- package/src/exports/remote/index.js +11 -0
- package/src/exports/remote/public.d.ts +519 -0
- package/src/exports/url.js +86 -0
- package/src/exports/vite/build/build_server.js +54 -65
- package/src/exports/vite/build/remote.js +24 -19
- package/src/exports/vite/build/utils.js +0 -8
- package/src/exports/vite/dev/index.js +218 -146
- package/src/exports/vite/index.js +1590 -858
- package/src/exports/vite/module_ids.js +2 -2
- package/src/exports/vite/preview/index.js +40 -32
- package/src/exports/vite/public.d.ts +588 -0
- package/src/exports/vite/utils.js +84 -46
- package/src/pathname.js +55 -0
- package/src/runner.js +15 -0
- package/src/runtime/app/env/internal.js +4 -4
- package/src/runtime/app/env/types.d.ts +1 -1
- package/src/runtime/app/environment/index.js +3 -3
- package/src/runtime/app/{forms.js → forms/index.js} +73 -42
- package/src/runtime/app/forms/public.d.ts +2 -0
- package/src/runtime/app/forms/types.d.ts +56 -0
- package/src/runtime/app/internal/transport.js +53 -0
- package/src/runtime/app/manifest/index.js +1 -0
- package/src/runtime/app/{navigation.js → navigation/index.js} +2 -1
- package/src/runtime/app/navigation/public.d.ts +237 -0
- package/src/runtime/app/paths/client.js +37 -37
- package/src/runtime/app/paths/index.js +1 -1
- package/src/runtime/app/paths/internal/client.js +34 -2
- package/src/runtime/app/paths/internal/server.js +6 -23
- package/src/runtime/app/paths/internal.d.ts +3 -0
- package/src/runtime/app/paths/public.d.ts +1 -29
- package/src/runtime/app/paths/server.js +36 -17
- package/src/runtime/app/paths/types.d.ts +11 -19
- package/src/runtime/app/server/index.js +2 -2
- package/src/runtime/app/server/public.d.ts +201 -0
- package/src/runtime/app/server/remote/command.js +13 -11
- package/src/runtime/app/server/remote/form.js +61 -39
- package/src/runtime/app/server/remote/prerender.js +45 -45
- package/src/runtime/app/server/remote/query.js +106 -108
- package/src/runtime/app/server/remote/requested.js +27 -19
- package/src/runtime/app/server/remote/shared.js +76 -76
- package/src/runtime/app/service-worker/index.js +24 -0
- package/src/runtime/app/state/client.js +4 -2
- package/src/runtime/app/state/index.js +7 -5
- package/src/runtime/app/state/public.d.ts +72 -0
- package/src/runtime/app/state/server.js +3 -0
- package/src/runtime/app/stores.js +15 -78
- package/src/runtime/client/bundle.js +1 -1
- package/src/runtime/client/client-entry.js +3 -0
- package/src/runtime/client/client.js +1336 -648
- package/src/runtime/client/constants.js +3 -6
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/fetcher.js +25 -25
- package/src/runtime/client/ndjson.js +1 -1
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/client/payload.js +17 -0
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/command.svelte.js +37 -61
- package/src/runtime/client/remote-functions/form.svelte.js +267 -178
- package/src/runtime/client/remote-functions/prerender.svelte.js +32 -11
- package/src/runtime/client/remote-functions/query/index.js +10 -17
- package/src/runtime/client/remote-functions/query/instance.svelte.js +64 -18
- package/src/runtime/client/remote-functions/query/proxy.js +5 -5
- package/src/runtime/client/remote-functions/query-batch.svelte.js +61 -70
- package/src/runtime/client/remote-functions/query-live/index.js +1 -1
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +63 -21
- package/src/runtime/client/remote-functions/query-live/iterator.js +15 -12
- package/src/runtime/client/remote-functions/query-live/proxy.js +2 -12
- package/src/runtime/client/remote-functions/shared.svelte.js +90 -65
- package/src/runtime/client/snapshots.js +147 -0
- package/src/runtime/client/state.svelte.js +94 -55
- package/src/runtime/client/stream.js +3 -2
- package/src/runtime/client/types.d.ts +13 -9
- package/src/runtime/client/utils.js +22 -110
- package/src/runtime/components/root.svelte +56 -0
- package/src/runtime/env/dynamic/private.js +7 -0
- package/src/runtime/env/dynamic/public.js +7 -0
- package/src/runtime/env/static/private.js +6 -0
- package/src/runtime/env/static/public.js +6 -0
- package/src/runtime/form-utils.js +172 -61
- package/src/runtime/pathname.js +20 -32
- package/src/runtime/props.svelte.js +72 -0
- package/src/runtime/server/constants.js +0 -3
- package/src/runtime/server/cookie.js +72 -55
- package/src/runtime/server/csrf.js +65 -0
- package/src/runtime/server/data/index.js +49 -53
- package/src/runtime/server/dev.js +22 -0
- package/src/runtime/server/endpoint.js +6 -7
- package/src/runtime/server/env_module.js +0 -5
- package/src/runtime/server/errors.js +160 -0
- package/src/runtime/server/fetch.js +32 -39
- package/src/runtime/server/index.js +90 -64
- package/src/runtime/server/internal.js +71 -0
- package/src/runtime/server/page/actions.js +85 -64
- package/src/runtime/server/page/crypto.js +2 -2
- package/src/runtime/server/page/csp.js +88 -104
- package/src/runtime/server/page/data_serializer.js +24 -25
- package/src/runtime/server/page/index.js +36 -53
- package/src/runtime/server/page/load_data.js +50 -57
- package/src/runtime/server/page/render.js +173 -239
- package/src/runtime/server/page/respond_with_error.js +17 -31
- package/src/runtime/server/page/serialize_data.js +2 -13
- package/src/runtime/server/page/server_routing.js +85 -26
- package/src/runtime/server/remote-functions.js +640 -0
- package/src/runtime/server/respond.js +190 -131
- package/src/runtime/server/sourcemaps.js +183 -0
- package/src/runtime/server/state.js +53 -0
- package/src/runtime/server/utils.js +13 -155
- package/src/runtime/shared.js +20 -40
- package/src/runtime/utils.js +3 -0
- package/src/types/ambient-private.d.ts +11 -1
- package/src/types/ambient.d.ts +87 -36
- package/src/types/global-private.d.ts +25 -25
- package/src/types/internal.d.ts +163 -157
- package/src/types/private.d.ts +41 -1
- package/src/utils/error.js +28 -4
- package/src/utils/escape.js +9 -25
- package/src/utils/features.js +1 -1
- package/src/utils/filesystem.js +1 -23
- package/src/utils/fork.js +7 -2
- package/src/utils/hash.js +21 -0
- package/src/utils/http.js +8 -7
- package/src/utils/import.js +9 -2
- package/src/utils/imports.js +83 -0
- package/src/utils/mime.js +9 -0
- package/src/utils/page_nodes.js +6 -7
- package/src/utils/params.js +67 -0
- package/src/utils/regex.js +9 -0
- package/src/utils/routing.js +145 -73
- package/src/utils/shared-iterator.js +5 -0
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +33 -2
- package/src/version.js +1 -1
- package/types/index.d.ts +2616 -2433
- package/types/index.d.ts.map +120 -106
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_root.js +0 -148
- package/src/core/sync/write_tsconfig.js +0 -250
- package/src/exports/internal/server.js +0 -22
- package/src/exports/node/polyfills.js +0 -30
- package/src/runtime/server/app.js +0 -9
- package/src/runtime/server/remote.js +0 -457
- package/src/runtime/shared-server.js +0 -7
- package/src/runtime/telemetry/otel.js +0 -21
- package/src/runtime/telemetry/record_span.js +0 -65
- package/src/types/synthetic/$lib.md +0 -5
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
- /package/src/{runtime/telemetry/noop.js → telemetry.js} +0 -0
|
@@ -1,31 +1,24 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
1
2
|
import path from 'node:path';
|
|
2
3
|
import { posixify } from '../../utils/os.js';
|
|
3
4
|
import { negotiate } from '../../utils/http.js';
|
|
4
5
|
import { escape_html } from '../../utils/escape.js';
|
|
6
|
+
import { escape_for_regexp } from '../../utils/regex.js';
|
|
5
7
|
import { stackless } from '../../utils/error.js';
|
|
6
8
|
import { dedent } from '../../core/sync/utils.js';
|
|
7
|
-
import {
|
|
8
|
-
app_server,
|
|
9
|
-
app_env_private,
|
|
10
|
-
service_worker,
|
|
11
|
-
sveltekit_env_private
|
|
12
|
-
} from './module_ids.js';
|
|
9
|
+
import { app_server, app_env_private, sveltekit_env_private } from './module_ids.js';
|
|
13
10
|
|
|
14
11
|
/**
|
|
15
|
-
* Transforms
|
|
12
|
+
* Transforms alias to a valid vite.resolve.alias array.
|
|
16
13
|
*
|
|
17
14
|
* Related to tsconfig path alias creation.
|
|
18
15
|
*
|
|
19
|
-
* @param {import('types').
|
|
16
|
+
* @param {import('types').ValidatedConfig} config
|
|
20
17
|
* @param {string} root
|
|
21
|
-
|
|
18
|
+
*/
|
|
22
19
|
export function get_config_aliases(config, root) {
|
|
23
20
|
/** @type {import('vite').Alias[]} */
|
|
24
|
-
const alias = [
|
|
25
|
-
// For now, we handle `$lib` specially here rather than make it a default value for
|
|
26
|
-
// `config.kit.alias` since it has special meaning for packaging, etc.
|
|
27
|
-
{ find: '$lib', replacement: config.files.lib }
|
|
28
|
-
];
|
|
21
|
+
const alias = [];
|
|
29
22
|
|
|
30
23
|
for (let [key, value] of Object.entries(config.alias)) {
|
|
31
24
|
value = posixify(value);
|
|
@@ -36,29 +29,22 @@ export function get_config_aliases(config, root) {
|
|
|
36
29
|
// Doing just `{ find: key.slice(0, -2) ,..}` would mean `import .. from "key"` would also be matched, which we don't want
|
|
37
30
|
alias.push({
|
|
38
31
|
find: new RegExp(`^${escape_for_regexp(key.slice(0, -2))}\\/(.+)$`),
|
|
39
|
-
replacement: `${path.resolve(root, value)}/$1`
|
|
32
|
+
replacement: `${posixify(path.resolve(root, value))}/$1`
|
|
40
33
|
});
|
|
41
34
|
} else if (key + '/*' in config.alias) {
|
|
42
35
|
// key and key/* both exist -> the replacement for key needs to happen _only_ on import .. from "key"
|
|
43
36
|
alias.push({
|
|
44
37
|
find: new RegExp(`^${escape_for_regexp(key)}$`),
|
|
45
|
-
replacement: path.resolve(root, value)
|
|
38
|
+
replacement: posixify(path.resolve(root, value))
|
|
46
39
|
});
|
|
47
40
|
} else {
|
|
48
|
-
alias.push({ find: key, replacement: path.resolve(root, value) });
|
|
41
|
+
alias.push({ find: key, replacement: posixify(path.resolve(root, value)) });
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
44
|
|
|
52
45
|
return alias;
|
|
53
46
|
}
|
|
54
47
|
|
|
55
|
-
/**
|
|
56
|
-
* @param {string} str
|
|
57
|
-
*/
|
|
58
|
-
function escape_for_regexp(str) {
|
|
59
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, (match) => '\\' + match);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
48
|
/**
|
|
63
49
|
* Silently respond with 404 for Chrome DevTools workspaces request.
|
|
64
50
|
* Chrome always requests this at the root, regardless of base path.
|
|
@@ -118,22 +104,17 @@ export function not_found(req, res, base) {
|
|
|
118
104
|
const query_pattern = /\?.*$/s;
|
|
119
105
|
|
|
120
106
|
/**
|
|
121
|
-
* Removes cwd
|
|
107
|
+
* Removes cwd path from the start of the id and replaces any `#`-prefixed
|
|
108
|
+
* import alias target paths with their alias names.
|
|
122
109
|
* @param {string} id
|
|
123
|
-
* @param {string}
|
|
110
|
+
* @param {Array<{ alias: string, path: string }>} aliases — sorted by path length descending
|
|
124
111
|
* @param {string} cwd
|
|
125
112
|
*/
|
|
126
|
-
export function normalize_id(id,
|
|
113
|
+
export function normalize_id(id, aliases, cwd) {
|
|
127
114
|
id = id.replace(query_pattern, '');
|
|
128
115
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (id.startsWith(cwd)) {
|
|
134
|
-
id = path.relative(cwd, id);
|
|
135
|
-
}
|
|
136
|
-
|
|
116
|
+
// check before the cwd is removed — in a user's app these modules live
|
|
117
|
+
// inside `node_modules`, i.e. within the cwd
|
|
137
118
|
if (id === app_server) {
|
|
138
119
|
return '$app/server';
|
|
139
120
|
}
|
|
@@ -142,29 +123,86 @@ export function normalize_id(id, lib, cwd) {
|
|
|
142
123
|
return '$app/env/private';
|
|
143
124
|
}
|
|
144
125
|
|
|
145
|
-
|
|
146
|
-
|
|
126
|
+
for (const { alias, path } of aliases) {
|
|
127
|
+
if (id === path || id.startsWith(path + '/')) {
|
|
128
|
+
id = id.replace(path, alias);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (id.startsWith(cwd)) {
|
|
134
|
+
id = path.relative(cwd, id);
|
|
147
135
|
}
|
|
148
136
|
|
|
149
137
|
return posixify(id);
|
|
150
138
|
}
|
|
151
139
|
|
|
140
|
+
export const remote_module_pattern = /[/.]remote\.[^/]+$/;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* A cache of which directories can export remote modules
|
|
144
|
+
* @type {Map<string, boolean>}
|
|
145
|
+
*/
|
|
146
|
+
const remote_module_cache = new Map();
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Whether `id` is a remote module. Files in node_modules only count if the
|
|
150
|
+
* package they belong to has a peer dependency on `@sveltejs/kit`
|
|
151
|
+
* @param {string} id
|
|
152
|
+
* @returns {boolean}
|
|
153
|
+
*/
|
|
154
|
+
export function is_remote_module(id) {
|
|
155
|
+
id = posixify(id);
|
|
156
|
+
if (!remote_module_pattern.test(id)) return false;
|
|
157
|
+
if (!id.includes('node_modules')) return true;
|
|
158
|
+
|
|
159
|
+
return can_export_remote_module(path.dirname(id));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @param {string} directory
|
|
164
|
+
* @returns {boolean}
|
|
165
|
+
*/
|
|
166
|
+
function can_export_remote_module(directory) {
|
|
167
|
+
let cached = remote_module_cache.get(directory);
|
|
168
|
+
if (cached !== undefined) return cached;
|
|
169
|
+
|
|
170
|
+
let pkg;
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
pkg = JSON.parse(fs.readFileSync(path.join(directory, 'package.json'), 'utf8'));
|
|
174
|
+
} catch {}
|
|
175
|
+
|
|
176
|
+
if (pkg?.peerDependencies?.['@sveltejs/kit']) {
|
|
177
|
+
cached = true;
|
|
178
|
+
} else {
|
|
179
|
+
const parent = path.dirname(directory);
|
|
180
|
+
|
|
181
|
+
cached =
|
|
182
|
+
path.basename(directory) === 'node_modules' || parent === directory
|
|
183
|
+
? false // base case
|
|
184
|
+
: can_export_remote_module(parent); // recurse
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
remote_module_cache.set(directory, cached);
|
|
188
|
+
return cached;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export const server_only_module_pattern = /[/.]server\.[^/]+$/;
|
|
192
|
+
export const server_only_directory_pattern = /\/server\//;
|
|
193
|
+
|
|
152
194
|
export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace('\0virtual:', '');
|
|
153
195
|
|
|
154
196
|
/**
|
|
155
|
-
* For `error_for_missing_config('
|
|
197
|
+
* For `error_for_missing_config('remote functions', 'experimental.remoteFunctions', 'true')`,
|
|
156
198
|
* returns:
|
|
157
199
|
*
|
|
158
200
|
* ```
|
|
159
|
-
* To enable
|
|
201
|
+
* To enable remote functions, add the following to the SvelteKit plugin in your `vite.config.js`:
|
|
160
202
|
*
|
|
161
203
|
*\`\`\`js
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* instrumentation:
|
|
165
|
-
* server: true
|
|
166
|
-
* }
|
|
167
|
-
* }
|
|
204
|
+
* experimental: {
|
|
205
|
+
* remoteFunctions: true
|
|
168
206
|
* }
|
|
169
207
|
*\`\`\`
|
|
170
208
|
*```
|
|
@@ -185,7 +223,7 @@ export function error_for_missing_config(feature_name, path, value) {
|
|
|
185
223
|
|
|
186
224
|
throw stackless(
|
|
187
225
|
dedent`\
|
|
188
|
-
To enable ${feature_name}, add the following to your \`
|
|
226
|
+
To enable ${feature_name}, add the following to your SvelteKit plugin in \`vite.config.js\`:
|
|
189
227
|
|
|
190
228
|
${result}
|
|
191
229
|
`
|
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
|
+
}
|
package/src/runner.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @import { ViteDevServer } from 'vite' */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {typeof import('vite')} vite the peer resolved vite module
|
|
5
|
+
* @param {ViteDevServer} server
|
|
6
|
+
*/
|
|
7
|
+
export function get_runner(vite, server) {
|
|
8
|
+
// `isRunnableDevEnvironment` does an `instanceof` check and will fail if
|
|
9
|
+
// we're using different instances of Vite
|
|
10
|
+
if (!vite.isRunnableDevEnvironment(server.environments.ssr)) {
|
|
11
|
+
throw new Error('The configured Vite SSR environment must be a RunnableDevEnvironment');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return server.environments.ssr.runner;
|
|
15
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { BROWSER } from 'esm-env';
|
|
2
|
+
import { payload } from '../../client/payload.js';
|
|
3
|
+
|
|
4
|
+
export const version = BROWSER ? payload.version : __SVELTEKIT_APP_VERSION__;
|
|
2
5
|
export let building = false;
|
|
3
6
|
export let prerendering = false;
|
|
4
7
|
|
|
@@ -9,6 +12,3 @@ export function set_building() {
|
|
|
9
12
|
export function set_prerendering() {
|
|
10
13
|
prerendering = true;
|
|
11
14
|
}
|
|
12
|
-
|
|
13
|
-
// force /@vite/client to be injected
|
|
14
|
-
import.meta.hot;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DEV } from 'esm-env';
|
|
2
2
|
export * from '../env/index.js';
|
|
3
3
|
|
|
4
|
-
if (
|
|
5
|
-
console.warn('`$app/environment` is
|
|
4
|
+
if (DEV) {
|
|
5
|
+
console.warn('`$app/environment` is deprecated, use `$app/env` instead');
|
|
6
6
|
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { noop } from '
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
/** @import { ActionResult, SubmitFunction } from './types.js' */
|
|
2
|
+
import { DEV } from 'esm-env';
|
|
3
|
+
import { noop } from '../../../utils/functions.js';
|
|
4
|
+
import { refreshAll } from '../navigation/index.js';
|
|
5
|
+
import {
|
|
6
|
+
applyAction,
|
|
7
|
+
apply_action_navigation,
|
|
8
|
+
handle_error,
|
|
9
|
+
is_current_location
|
|
10
|
+
} from '../../client/client.js';
|
|
11
|
+
import { notify_version } from '../../client/state.svelte.js';
|
|
12
|
+
import { parse } from '#app/internal/transport';
|
|
7
13
|
|
|
8
14
|
export { applyAction };
|
|
9
15
|
|
|
@@ -27,15 +33,13 @@ export { applyAction };
|
|
|
27
33
|
* @template {Record<string, unknown> | undefined} Success
|
|
28
34
|
* @template {Record<string, unknown> | undefined} Failure
|
|
29
35
|
* @param {string} result
|
|
30
|
-
* @returns {
|
|
36
|
+
* @returns {ActionResult<Success, Failure>}
|
|
31
37
|
*/
|
|
32
38
|
export function deserialize(result) {
|
|
33
39
|
const parsed = JSON.parse(result);
|
|
34
40
|
|
|
35
41
|
if (parsed.data) {
|
|
36
|
-
|
|
37
|
-
// will not be initialised yet if `kit.output.bundleStrategy` is 'single' or 'inline'
|
|
38
|
-
parsed.data = devalue.parse(parsed.data, BROWSER ? client_app.decoders : server_app.decoders);
|
|
42
|
+
parsed.data = parse(parsed.data);
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
return parsed;
|
|
@@ -61,21 +65,22 @@ function clone(element) {
|
|
|
61
65
|
* If a function is returned, that function is called with the response from the server.
|
|
62
66
|
* If nothing is returned, the fallback will be used.
|
|
63
67
|
*
|
|
64
|
-
* If this function or its return value isn't set, it
|
|
65
|
-
* -
|
|
66
|
-
* - updates `page.status`
|
|
67
|
-
* -
|
|
68
|
+
* If this function or its return value isn't set, it emulates the browser-native behaviour, just without the full-page reload. It
|
|
69
|
+
* - resets the `<form>` element and refreshes all data in case of a successful submission with no redirect response
|
|
70
|
+
* - updates the `form` prop, `page.form` and `page.status` if the action is on the same page as the form
|
|
71
|
+
* - navigates to the page the submission lands on — populating that page's `form` prop and `page.status` — on success and failure if that isn't the current page, just as a native form submission would, but with the `?/actionName` param stripped from the destination URL
|
|
68
72
|
* - redirects in case of a redirect response
|
|
69
|
-
* -
|
|
73
|
+
* - renders the nearest error page in case of an unexpected error — the one nearest the action's route, if the action is on a different page
|
|
70
74
|
*
|
|
71
75
|
* If you provide a custom function with a callback and want to use the default behavior, invoke `update` in your callback.
|
|
72
76
|
* It accepts an options object
|
|
73
77
|
* - `reset: false` if you don't want the `<form>` values to be reset after a successful submission
|
|
74
|
-
* - `
|
|
78
|
+
* - `refreshAll` to control whether all data is refreshed after submission; it defaults to `true` for successes and `false` for failures
|
|
79
|
+
* - `navigate: false` to apply non-redirect results to the current page rather than navigating to `result.location`; redirects are always followed
|
|
75
80
|
* @template {Record<string, unknown> | undefined} Success
|
|
76
81
|
* @template {Record<string, unknown> | undefined} Failure
|
|
77
82
|
* @param {HTMLFormElement} form_element The form element
|
|
78
|
-
* @param {
|
|
83
|
+
* @param {SubmitFunction<Success, Failure>} submit Submit callback
|
|
79
84
|
*/
|
|
80
85
|
export function enhance(form_element, submit = noop) {
|
|
81
86
|
if (DEV && clone(form_element).method !== 'post') {
|
|
@@ -84,37 +89,50 @@ export function enhance(form_element, submit = noop) {
|
|
|
84
89
|
|
|
85
90
|
/**
|
|
86
91
|
* @param {{
|
|
87
|
-
*
|
|
92
|
+
* result: ActionResult;
|
|
93
|
+
* reset?: boolean;
|
|
94
|
+
* refreshAll?: boolean;
|
|
88
95
|
* invalidateAll?: boolean;
|
|
89
|
-
*
|
|
90
|
-
* reset?: boolean
|
|
96
|
+
* navigate?: boolean;
|
|
91
97
|
* }} opts
|
|
92
98
|
*/
|
|
93
99
|
const fallback_callback = async ({
|
|
94
|
-
action,
|
|
95
100
|
result,
|
|
96
101
|
reset = true,
|
|
97
|
-
|
|
102
|
+
refreshAll: should_refresh_all,
|
|
103
|
+
invalidateAll: deprecated_invalidate_all,
|
|
104
|
+
navigate = true
|
|
98
105
|
}) => {
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
if (DEV && deprecated_invalidate_all !== undefined) {
|
|
107
|
+
console.warn(
|
|
108
|
+
'The `update({ invalidateAll })` option has been deprecated in favour of `update({ refreshAll })`'
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
should_refresh_all ??= deprecated_invalidate_all ?? result.type === 'success';
|
|
113
|
+
|
|
114
|
+
if (result.type === 'success' && reset) {
|
|
115
|
+
// We call reset from the prototype to avoid DOM clobbering
|
|
116
|
+
HTMLFormElement.prototype.reset.call(form_element);
|
|
107
117
|
}
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
const destination =
|
|
120
|
+
navigate && result.type !== 'redirect' && !is_current_location(result.location)
|
|
121
|
+
? result.location
|
|
122
|
+
: undefined;
|
|
123
|
+
|
|
124
|
+
if (destination === undefined) {
|
|
125
|
+
if (should_refresh_all && result.type !== 'redirect') {
|
|
126
|
+
await refreshAll();
|
|
127
|
+
}
|
|
128
|
+
|
|
116
129
|
await applyAction(result);
|
|
130
|
+
return;
|
|
117
131
|
}
|
|
132
|
+
|
|
133
|
+
// emulate the browser: navigate to where the submission lands, rendering that
|
|
134
|
+
// page with this result
|
|
135
|
+
await apply_action_navigation(destination, result, should_refresh_all);
|
|
118
136
|
};
|
|
119
137
|
|
|
120
138
|
/** @param {SubmitEvent} event */
|
|
@@ -165,7 +183,7 @@ export function enhance(form_element, submit = noop) {
|
|
|
165
183
|
})) ?? fallback_callback;
|
|
166
184
|
if (cancelled) return;
|
|
167
185
|
|
|
168
|
-
/** @type {
|
|
186
|
+
/** @type {ActionResult} */
|
|
169
187
|
let result;
|
|
170
188
|
|
|
171
189
|
try {
|
|
@@ -197,11 +215,23 @@ export function enhance(form_element, submit = noop) {
|
|
|
197
215
|
signal: controller.signal
|
|
198
216
|
});
|
|
199
217
|
|
|
218
|
+
// detect new deployments from the response header
|
|
219
|
+
notify_version(response.headers.get('x-sveltekit-version'));
|
|
220
|
+
|
|
200
221
|
result = deserialize(await response.text());
|
|
201
|
-
if (result.type === 'error'
|
|
222
|
+
if (result.type === 'error' || result.type === 'failure') {
|
|
223
|
+
result.status = response.status;
|
|
224
|
+
}
|
|
202
225
|
} catch (error) {
|
|
203
226
|
if (/** @type {any} */ (error)?.name === 'AbortError') return;
|
|
204
|
-
result = {
|
|
227
|
+
result = {
|
|
228
|
+
type: 'error',
|
|
229
|
+
error: await handle_error(error, {
|
|
230
|
+
params: {},
|
|
231
|
+
route: { id: null },
|
|
232
|
+
url: new URL(location.href)
|
|
233
|
+
})
|
|
234
|
+
};
|
|
205
235
|
}
|
|
206
236
|
|
|
207
237
|
await callback({
|
|
@@ -210,10 +240,11 @@ export function enhance(form_element, submit = noop) {
|
|
|
210
240
|
formElement: form_element,
|
|
211
241
|
update: (opts) =>
|
|
212
242
|
fallback_callback({
|
|
213
|
-
action,
|
|
214
243
|
result,
|
|
215
244
|
reset: opts?.reset,
|
|
216
|
-
|
|
245
|
+
refreshAll: opts?.refreshAll,
|
|
246
|
+
invalidateAll: opts?.invalidateAll,
|
|
247
|
+
navigate: opts?.navigate
|
|
217
248
|
}),
|
|
218
249
|
// @ts-expect-error generic constraints stuff we don't care about
|
|
219
250
|
result
|
|
@@ -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,53 @@
|
|
|
1
|
+
/** @import { Transport } from '@sveltejs/kit/hooks' */
|
|
2
|
+
import * as devalue from 'devalue';
|
|
3
|
+
import { DEV } from 'esm-env';
|
|
4
|
+
|
|
5
|
+
/** @type {(thing: any) => string} */
|
|
6
|
+
export let uneval = () => {
|
|
7
|
+
throw new Error(DEV ? 'called uneval before init_transport' : '');
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/** @type {(data: any) => string} */
|
|
11
|
+
export let stringify = () => {
|
|
12
|
+
throw new Error(DEV ? 'called stringify before init_transport' : '');
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** @type {(data: string) => any} */
|
|
16
|
+
export let parse = () => {
|
|
17
|
+
throw new Error(DEV ? 'called parse before init_transport' : '');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** @type {Record<string, (data: any) => any>} */
|
|
21
|
+
export let encoders = {};
|
|
22
|
+
|
|
23
|
+
/** @type {Record<string, (data: any) => any>} */
|
|
24
|
+
export let decoders = {};
|
|
25
|
+
|
|
26
|
+
export let has_custom_transporters = false;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param {Transport} transport
|
|
31
|
+
*/
|
|
32
|
+
export function init_transport(transport) {
|
|
33
|
+
const transporters = Object.entries(transport);
|
|
34
|
+
|
|
35
|
+
has_custom_transporters = transporters.length > 0;
|
|
36
|
+
|
|
37
|
+
/** @param {unknown} thing */
|
|
38
|
+
const replacer = (thing) => {
|
|
39
|
+
for (const key of Object.keys(transport)) {
|
|
40
|
+
const encoded = transport[key].encode(thing);
|
|
41
|
+
if (encoded) {
|
|
42
|
+
return `app.decode('${key}', ${devalue.uneval(encoded, replacer)})`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
encoders = Object.fromEntries(transporters.map(([k, v]) => [k, v.encode]));
|
|
48
|
+
decoders = Object.fromEntries(transporters.map(([k, v]) => [k, v.decode]));
|
|
49
|
+
|
|
50
|
+
uneval = (data) => devalue.uneval(data, replacer);
|
|
51
|
+
stringify = (data) => devalue.stringify(data, encoders);
|
|
52
|
+
parse = (data) => devalue.parse(data, decoders);
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '__sveltekit/manifest-data';
|