@sveltejs/kit 2.44.0 → 2.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/exports/public.d.ts +55 -4
- package/src/exports/vite/index.js +28 -2
- package/src/runtime/app/server/remote/form.js +154 -31
- package/src/runtime/app/server/remote/shared.js +36 -30
- package/src/runtime/client/remote-functions/form.svelte.js +21 -4
- package/src/runtime/form-utils.svelte.js +4 -0
- package/src/runtime/server/page/render.js +2 -2
- package/src/runtime/server/remote.js +13 -2
- package/src/runtime/server/respond.js +2 -1
- package/src/types/internal.d.ts +1 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +58 -7
- package/types/index.d.ts.map +4 -1
package/package.json
CHANGED
package/src/exports/public.d.ts
CHANGED
|
@@ -1925,7 +1925,7 @@ type RemoteFormFields<T> =
|
|
|
1925
1925
|
: RemoteFormFieldContainer<T> & { [K in keyof T]-?: RemoteFormFields<T[K]> };
|
|
1926
1926
|
|
|
1927
1927
|
// By breaking this out into its own type, we avoid the TS recursion depth limit
|
|
1928
|
-
type RecursiveFormFields = RemoteFormField<any> & { [key: string]: RecursiveFormFields };
|
|
1928
|
+
type RecursiveFormFields = RemoteFormField<any> & { [key: string | number]: RecursiveFormFields };
|
|
1929
1929
|
|
|
1930
1930
|
type MaybeArray<T> = T | T[];
|
|
1931
1931
|
|
|
@@ -1937,6 +1937,57 @@ export interface RemoteFormIssue {
|
|
|
1937
1937
|
message: string;
|
|
1938
1938
|
}
|
|
1939
1939
|
|
|
1940
|
+
// If the schema specifies `id` as a string or number, ensure that `for(...)`
|
|
1941
|
+
// only accepts that type. Otherwise, accept `string | number`
|
|
1942
|
+
type ExtractId<Input> = Input extends { id: infer Id }
|
|
1943
|
+
? Id extends string | number
|
|
1944
|
+
? Id
|
|
1945
|
+
: string | number
|
|
1946
|
+
: string | number;
|
|
1947
|
+
|
|
1948
|
+
/**
|
|
1949
|
+
* Recursively maps an input type to a structure where each field can create a validation issue.
|
|
1950
|
+
* This mirrors the runtime behavior of the `invalid` proxy passed to form handlers.
|
|
1951
|
+
*/
|
|
1952
|
+
type InvalidField<T> =
|
|
1953
|
+
WillRecurseIndefinitely<T> extends true
|
|
1954
|
+
? Record<string | number, any>
|
|
1955
|
+
: NonNullable<T> extends string | number | boolean | File
|
|
1956
|
+
? (message: string) => StandardSchemaV1.Issue
|
|
1957
|
+
: NonNullable<T> extends Array<infer U>
|
|
1958
|
+
? {
|
|
1959
|
+
[K in number]: InvalidField<U>;
|
|
1960
|
+
} & ((message: string) => StandardSchemaV1.Issue)
|
|
1961
|
+
: NonNullable<T> extends RemoteFormInput
|
|
1962
|
+
? {
|
|
1963
|
+
[K in keyof T]-?: InvalidField<T[K]>;
|
|
1964
|
+
} & ((message: string) => StandardSchemaV1.Issue)
|
|
1965
|
+
: Record<string, never>;
|
|
1966
|
+
|
|
1967
|
+
/**
|
|
1968
|
+
* A function and proxy object used to imperatively create validation errors in form handlers.
|
|
1969
|
+
*
|
|
1970
|
+
* Call `invalid(issue1, issue2, ...issueN)` to throw a validation error.
|
|
1971
|
+
* If an issue is a `string`, it applies to the form as a whole (and will show up in `fields.allIssues()`)
|
|
1972
|
+
* Access properties to create field-specific issues: `invalid.fieldName('message')`.
|
|
1973
|
+
* The type structure mirrors the input data structure for type-safe field access.
|
|
1974
|
+
*
|
|
1975
|
+
* @example
|
|
1976
|
+
* ```ts
|
|
1977
|
+
* invalid('Username or password is invalid');
|
|
1978
|
+
* ```
|
|
1979
|
+
*
|
|
1980
|
+
* @example
|
|
1981
|
+
* ```ts
|
|
1982
|
+
* invalid(
|
|
1983
|
+
* invalid.username('Username is taken'),
|
|
1984
|
+
* invalid.items[0].qty('Insufficient stock')
|
|
1985
|
+
* );
|
|
1986
|
+
* ```
|
|
1987
|
+
*/
|
|
1988
|
+
export type Invalid<Input = any> = ((...issues: Array<string | StandardSchemaV1.Issue>) => never) &
|
|
1989
|
+
InvalidField<Input>;
|
|
1990
|
+
|
|
1940
1991
|
/**
|
|
1941
1992
|
* The return value of a remote `form` function. See [Remote functions](https://svelte.dev/docs/kit/remote-functions#form) for full documentation.
|
|
1942
1993
|
*/
|
|
@@ -1961,8 +2012,8 @@ export type RemoteForm<Input extends RemoteFormInput | void, Output> = {
|
|
|
1961
2012
|
[attachment: symbol]: (node: HTMLFormElement) => void;
|
|
1962
2013
|
};
|
|
1963
2014
|
/**
|
|
1964
|
-
* Create an instance of the form for the given
|
|
1965
|
-
* The
|
|
2015
|
+
* Create an instance of the form for the given `id`.
|
|
2016
|
+
* The `id` is stringified and used for deduplication to potentially reuse existing instances.
|
|
1966
2017
|
* Useful when you have multiple forms that use the same remote form action, for example in a loop.
|
|
1967
2018
|
* ```svelte
|
|
1968
2019
|
* {#each todos as todo}
|
|
@@ -1974,7 +2025,7 @@ export type RemoteForm<Input extends RemoteFormInput | void, Output> = {
|
|
|
1974
2025
|
* {/each}
|
|
1975
2026
|
* ```
|
|
1976
2027
|
*/
|
|
1977
|
-
for(
|
|
2028
|
+
for(id: ExtractId<Input>): Omit<RemoteForm<Input, Output>, 'for'>;
|
|
1978
2029
|
/** Preflight checks */
|
|
1979
2030
|
preflight(schema: StandardSchemaV1<Input, any>): RemoteForm<Input, Output>;
|
|
1980
2031
|
/** Validate the form contents programmatically */
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
import { import_peer } from '../../utils/import.js';
|
|
42
42
|
import { compact } from '../../utils/array.js';
|
|
43
43
|
import { should_ignore } from './static_analysis/utils.js';
|
|
44
|
+
import { rollupVersion } from 'vite';
|
|
44
45
|
|
|
45
46
|
const cwd = process.cwd();
|
|
46
47
|
|
|
@@ -675,6 +676,15 @@ async function kit({ svelte_config }) {
|
|
|
675
676
|
// Set up manualChunks to isolate *.remote.ts files
|
|
676
677
|
const { manualChunks } = config.build.rollupOptions.output;
|
|
677
678
|
|
|
679
|
+
const [major, minor] = rollupVersion.split('.').map(Number);
|
|
680
|
+
const is_outdated_rollup = major === 4 && minor < 52;
|
|
681
|
+
if (is_outdated_rollup) {
|
|
682
|
+
console.warn(
|
|
683
|
+
'Rollup >=4.52.0 is recommended when using SvelteKit remote functions as it fixes some bugs related to code-splitting. Current version: ' +
|
|
684
|
+
rollupVersion
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
|
|
678
688
|
config.build.rollupOptions.output = {
|
|
679
689
|
...config.build.rollupOptions.output,
|
|
680
690
|
manualChunks(id, meta) {
|
|
@@ -685,8 +695,19 @@ async function kit({ svelte_config }) {
|
|
|
685
695
|
return `remote-${hash(relative)}`;
|
|
686
696
|
}
|
|
687
697
|
|
|
688
|
-
|
|
689
|
-
|
|
698
|
+
// With onlyExplicitManualChunks Rollup will keep any manual chunk's dependencies out of that chunk.
|
|
699
|
+
// This option only exists on more recent Rollup versions; use this as a fallback for older versions.
|
|
700
|
+
if (is_outdated_rollup) {
|
|
701
|
+
// Prevent core runtime and env from ending up in a remote chunk, which could break because of initialization order
|
|
702
|
+
if (id === `${runtime_directory}/app/server/index.js`) {
|
|
703
|
+
return 'app-server';
|
|
704
|
+
}
|
|
705
|
+
if (id === `${runtime_directory}/shared-server.js`) {
|
|
706
|
+
return 'app-shared-server';
|
|
707
|
+
}
|
|
708
|
+
if (imported_by_remotes.has(id)) {
|
|
709
|
+
return `chunk-${uid++}`;
|
|
710
|
+
}
|
|
690
711
|
}
|
|
691
712
|
|
|
692
713
|
// If there was an existing manualChunks function, call it
|
|
@@ -707,6 +728,11 @@ async function kit({ svelte_config }) {
|
|
|
707
728
|
}
|
|
708
729
|
}
|
|
709
730
|
};
|
|
731
|
+
|
|
732
|
+
if (!is_outdated_rollup) {
|
|
733
|
+
// @ts-expect-error only exists in more recent Rollup versions https://rollupjs.org/configuration-options/#output-onlyexplicitmanualchunks
|
|
734
|
+
config.build.rollupOptions.onlyExplicitManualChunks = true;
|
|
735
|
+
}
|
|
710
736
|
},
|
|
711
737
|
|
|
712
738
|
configureServer(_dev_server) {
|
|
@@ -20,7 +20,7 @@ import { get_cache, run_remote_function } from './shared.js';
|
|
|
20
20
|
*
|
|
21
21
|
* @template Output
|
|
22
22
|
* @overload
|
|
23
|
-
* @param {() => MaybePromise<Output>} fn
|
|
23
|
+
* @param {(invalid: import('@sveltejs/kit').Invalid<void>) => MaybePromise<Output>} fn
|
|
24
24
|
* @returns {RemoteForm<void, Output>}
|
|
25
25
|
* @since 2.27
|
|
26
26
|
*/
|
|
@@ -33,7 +33,7 @@ import { get_cache, run_remote_function } from './shared.js';
|
|
|
33
33
|
* @template Output
|
|
34
34
|
* @overload
|
|
35
35
|
* @param {'unchecked'} validate
|
|
36
|
-
* @param {(data: Input) => MaybePromise<Output>} fn
|
|
36
|
+
* @param {(data: Input, invalid: import('@sveltejs/kit').Invalid<Input>) => MaybePromise<Output>} fn
|
|
37
37
|
* @returns {RemoteForm<Input, Output>}
|
|
38
38
|
* @since 2.27
|
|
39
39
|
*/
|
|
@@ -46,7 +46,7 @@ import { get_cache, run_remote_function } from './shared.js';
|
|
|
46
46
|
* @template Output
|
|
47
47
|
* @overload
|
|
48
48
|
* @param {Schema} validate
|
|
49
|
-
* @param {(data: StandardSchemaV1.InferOutput<Schema
|
|
49
|
+
* @param {(data: StandardSchemaV1.InferOutput<Schema>, invalid: import('@sveltejs/kit').Invalid<StandardSchemaV1.InferOutput<Schema>>) => MaybePromise<Output>} fn
|
|
50
50
|
* @returns {RemoteForm<StandardSchemaV1.InferInput<Schema>, Output>}
|
|
51
51
|
* @since 2.27
|
|
52
52
|
*/
|
|
@@ -54,18 +54,19 @@ import { get_cache, run_remote_function } from './shared.js';
|
|
|
54
54
|
* @template {RemoteFormInput} Input
|
|
55
55
|
* @template Output
|
|
56
56
|
* @param {any} validate_or_fn
|
|
57
|
-
* @param {(
|
|
57
|
+
* @param {(data_or_invalid: any, invalid?: any) => MaybePromise<Output>} [maybe_fn]
|
|
58
58
|
* @returns {RemoteForm<Input, Output>}
|
|
59
59
|
* @since 2.27
|
|
60
60
|
*/
|
|
61
61
|
/*@__NO_SIDE_EFFECTS__*/
|
|
62
62
|
// @ts-ignore we don't want to prefix `fn` with an underscore, as that will be user-visible
|
|
63
63
|
export function form(validate_or_fn, maybe_fn) {
|
|
64
|
-
/** @type {
|
|
64
|
+
/** @type {any} */
|
|
65
65
|
const fn = maybe_fn ?? validate_or_fn;
|
|
66
66
|
|
|
67
67
|
/** @type {StandardSchemaV1 | null} */
|
|
68
|
-
const schema =
|
|
68
|
+
const schema =
|
|
69
|
+
!maybe_fn || validate_or_fn === 'unchecked' ? null : /** @type {any} */ (validate_or_fn);
|
|
69
70
|
|
|
70
71
|
/**
|
|
71
72
|
* @param {string | number | boolean} [key]
|
|
@@ -105,10 +106,16 @@ export function form(validate_or_fn, maybe_fn) {
|
|
|
105
106
|
/** @param {FormData} form_data */
|
|
106
107
|
fn: async (form_data) => {
|
|
107
108
|
const validate_only = form_data.get('sveltekit:validate_only') === 'true';
|
|
108
|
-
form_data.delete('sveltekit:validate_only');
|
|
109
109
|
|
|
110
110
|
let data = maybe_fn ? convert_formdata(form_data) : undefined;
|
|
111
111
|
|
|
112
|
+
if (data && data.id === undefined) {
|
|
113
|
+
const id = form_data.get('sveltekit:id');
|
|
114
|
+
if (typeof id === 'string') {
|
|
115
|
+
data.id = JSON.parse(id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
112
119
|
// TODO 3.0 remove this warning
|
|
113
120
|
if (DEV && !data) {
|
|
114
121
|
const error = () => {
|
|
@@ -146,29 +153,7 @@ export function form(validate_or_fn, maybe_fn) {
|
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
if (validated?.issues !== undefined) {
|
|
149
|
-
output.issues
|
|
150
|
-
|
|
151
|
-
// if it was a progressively-enhanced submission, we don't need
|
|
152
|
-
// to return the input — it's already there
|
|
153
|
-
if (!event.isRemoteRequest) {
|
|
154
|
-
output.input = {};
|
|
155
|
-
|
|
156
|
-
for (let key of form_data.keys()) {
|
|
157
|
-
// redact sensitive fields
|
|
158
|
-
if (/^[.\]]?_/.test(key)) continue;
|
|
159
|
-
|
|
160
|
-
const is_array = key.endsWith('[]');
|
|
161
|
-
const values = form_data.getAll(key).filter((value) => typeof value === 'string');
|
|
162
|
-
|
|
163
|
-
if (is_array) key = key.slice(0, -2);
|
|
164
|
-
|
|
165
|
-
output.input = set_nested_value(
|
|
166
|
-
/** @type {Record<string, any>} */ (output.input),
|
|
167
|
-
key,
|
|
168
|
-
is_array ? values : values[0]
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
156
|
+
handle_issues(output, validated.issues, event.isRemoteRequest, form_data);
|
|
172
157
|
} else {
|
|
173
158
|
if (validated !== undefined) {
|
|
174
159
|
data = validated.value;
|
|
@@ -176,7 +161,24 @@ export function form(validate_or_fn, maybe_fn) {
|
|
|
176
161
|
|
|
177
162
|
state.refreshes ??= {};
|
|
178
163
|
|
|
179
|
-
|
|
164
|
+
const invalid = create_invalid();
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
output.result = await run_remote_function(
|
|
168
|
+
event,
|
|
169
|
+
state,
|
|
170
|
+
true,
|
|
171
|
+
data,
|
|
172
|
+
(d) => d,
|
|
173
|
+
(data) => (!maybe_fn ? fn(invalid) : fn(data, invalid))
|
|
174
|
+
);
|
|
175
|
+
} catch (e) {
|
|
176
|
+
if (e instanceof ValidationError) {
|
|
177
|
+
handle_issues(output, e.issues, event.isRemoteRequest, form_data);
|
|
178
|
+
} else {
|
|
179
|
+
throw e;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
// We don't need to care about args or deduplicating calls, because uneval results are only relevant in full page reloads
|
|
@@ -284,3 +286,124 @@ export function form(validate_or_fn, maybe_fn) {
|
|
|
284
286
|
|
|
285
287
|
return create_instance();
|
|
286
288
|
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* @param {{ issues?: Record<string, any>, input?: Record<string, any>, result: any }} output
|
|
292
|
+
* @param {readonly StandardSchemaV1.Issue[]} issues
|
|
293
|
+
* @param {boolean} is_remote_request
|
|
294
|
+
* @param {FormData} form_data
|
|
295
|
+
*/
|
|
296
|
+
function handle_issues(output, issues, is_remote_request, form_data) {
|
|
297
|
+
output.issues = flatten_issues(issues);
|
|
298
|
+
|
|
299
|
+
// if it was a progressively-enhanced submission, we don't need
|
|
300
|
+
// to return the input — it's already there
|
|
301
|
+
if (!is_remote_request) {
|
|
302
|
+
output.input = {};
|
|
303
|
+
|
|
304
|
+
for (let key of form_data.keys()) {
|
|
305
|
+
// redact sensitive fields
|
|
306
|
+
if (/^[.\]]?_/.test(key)) continue;
|
|
307
|
+
|
|
308
|
+
const is_array = key.endsWith('[]');
|
|
309
|
+
const values = form_data.getAll(key).filter((value) => typeof value === 'string');
|
|
310
|
+
|
|
311
|
+
if (is_array) key = key.slice(0, -2);
|
|
312
|
+
|
|
313
|
+
output.input = set_nested_value(
|
|
314
|
+
/** @type {Record<string, any>} */ (output.input),
|
|
315
|
+
key,
|
|
316
|
+
is_array ? values : values[0]
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Creates an invalid function that can be used to imperatively mark form fields as invalid
|
|
324
|
+
* @returns {import('@sveltejs/kit').Invalid}
|
|
325
|
+
*/
|
|
326
|
+
function create_invalid() {
|
|
327
|
+
/**
|
|
328
|
+
* @param {...(string | StandardSchemaV1.Issue)} issues
|
|
329
|
+
* @returns {never}
|
|
330
|
+
*/
|
|
331
|
+
function invalid(...issues) {
|
|
332
|
+
throw new ValidationError(
|
|
333
|
+
issues.map((issue) => {
|
|
334
|
+
if (typeof issue === 'string') {
|
|
335
|
+
return {
|
|
336
|
+
path: [],
|
|
337
|
+
message: issue
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return issue;
|
|
342
|
+
})
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return /** @type {import('@sveltejs/kit').Invalid} */ (
|
|
347
|
+
new Proxy(invalid, {
|
|
348
|
+
get(target, prop) {
|
|
349
|
+
if (typeof prop === 'symbol') return /** @type {any} */ (target)[prop];
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @param {string} message
|
|
353
|
+
* @param {(string | number)[]} path
|
|
354
|
+
* @returns {StandardSchemaV1.Issue}
|
|
355
|
+
*/
|
|
356
|
+
const create_issue = (message, path = []) => ({
|
|
357
|
+
message,
|
|
358
|
+
path
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
return create_issue_proxy(prop, create_issue, []);
|
|
362
|
+
}
|
|
363
|
+
})
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Error thrown when form validation fails imperatively
|
|
369
|
+
*/
|
|
370
|
+
class ValidationError extends Error {
|
|
371
|
+
/**
|
|
372
|
+
* @param {StandardSchemaV1.Issue[]} issues
|
|
373
|
+
*/
|
|
374
|
+
constructor(issues) {
|
|
375
|
+
super('Validation failed');
|
|
376
|
+
this.name = 'ValidationError';
|
|
377
|
+
this.issues = issues;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Creates a proxy that builds up a path and returns a function to create an issue
|
|
383
|
+
* @param {string | number} key
|
|
384
|
+
* @param {(message: string, path: (string | number)[]) => StandardSchemaV1.Issue} create_issue
|
|
385
|
+
* @param {(string | number)[]} path
|
|
386
|
+
*/
|
|
387
|
+
function create_issue_proxy(key, create_issue, path) {
|
|
388
|
+
const new_path = [...path, key];
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* @param {string} message
|
|
392
|
+
* @returns {StandardSchemaV1.Issue}
|
|
393
|
+
*/
|
|
394
|
+
const issue_func = (message) => create_issue(message, new_path);
|
|
395
|
+
|
|
396
|
+
return new Proxy(issue_func, {
|
|
397
|
+
get(target, prop) {
|
|
398
|
+
if (typeof prop === 'symbol') return /** @type {any} */ (target)[prop];
|
|
399
|
+
|
|
400
|
+
// Handle array access like invalid.items[0]
|
|
401
|
+
if (/^\d+$/.test(prop)) {
|
|
402
|
+
return create_issue_proxy(parseInt(prop, 10), create_issue, new_path);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Handle property access like invalid.field.nested
|
|
406
|
+
return create_issue_proxy(prop, create_issue, new_path);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { RequestEvent } from '@sveltejs/kit' */
|
|
2
|
-
/** @import { ServerHooks, MaybePromise, RequestState, RemoteInfo } from 'types' */
|
|
2
|
+
/** @import { ServerHooks, MaybePromise, RequestState, RemoteInfo, RequestStore } from 'types' */
|
|
3
3
|
import { parse } from 'devalue';
|
|
4
4
|
import { error } from '@sveltejs/kit';
|
|
5
5
|
import { with_request_store, get_request_store } from '@sveltejs/kit/internal/server';
|
|
@@ -103,42 +103,48 @@ export function parse_remote_response(data, transport) {
|
|
|
103
103
|
* @param {(arg?: any) => T} fn
|
|
104
104
|
*/
|
|
105
105
|
export async function run_remote_function(event, state, allow_cookies, arg, validate, fn) {
|
|
106
|
-
/** @type {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
cookies: {
|
|
113
|
-
...event.cookies,
|
|
114
|
-
set: (name, value, opts) => {
|
|
115
|
-
if (!allow_cookies) {
|
|
116
|
-
throw new Error('Cannot set cookies in `query` or `prerender` functions');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (opts.path && !opts.path.startsWith('/')) {
|
|
120
|
-
throw new Error('Cookies set in remote functions must have an absolute path');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return event.cookies.set(name, value, opts);
|
|
106
|
+
/** @type {RequestStore} */
|
|
107
|
+
const store = {
|
|
108
|
+
event: {
|
|
109
|
+
...event,
|
|
110
|
+
setHeaders: () => {
|
|
111
|
+
throw new Error('setHeaders is not allowed in remote functions');
|
|
124
112
|
},
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
113
|
+
cookies: {
|
|
114
|
+
...event.cookies,
|
|
115
|
+
set: (name, value, opts) => {
|
|
116
|
+
if (!allow_cookies) {
|
|
117
|
+
throw new Error('Cannot set cookies in `query` or `prerender` functions');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (opts.path && !opts.path.startsWith('/')) {
|
|
121
|
+
throw new Error('Cookies set in remote functions must have an absolute path');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return event.cookies.set(name, value, opts);
|
|
125
|
+
},
|
|
126
|
+
delete: (name, opts) => {
|
|
127
|
+
if (!allow_cookies) {
|
|
128
|
+
throw new Error('Cannot delete cookies in `query` or `prerender` functions');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (opts.path && !opts.path.startsWith('/')) {
|
|
132
|
+
throw new Error('Cookies deleted in remote functions must have an absolute path');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return event.cookies.delete(name, opts);
|
|
128
136
|
}
|
|
129
|
-
|
|
130
|
-
if (opts.path && !opts.path.startsWith('/')) {
|
|
131
|
-
throw new Error('Cookies deleted in remote functions must have an absolute path');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return event.cookies.delete(name, opts);
|
|
135
137
|
}
|
|
138
|
+
},
|
|
139
|
+
state: {
|
|
140
|
+
...state,
|
|
141
|
+
is_in_remote_function: true
|
|
136
142
|
}
|
|
137
143
|
};
|
|
138
144
|
|
|
139
145
|
// In two parts, each with_event, so that runtimes without async local storage can still get the event at the start of the function
|
|
140
|
-
const validated = await with_request_store(
|
|
141
|
-
return with_request_store(
|
|
146
|
+
const validated = await with_request_store(store, () => validate(arg));
|
|
147
|
+
return with_request_store(store, () => fn(validated));
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
/**
|
|
@@ -82,13 +82,25 @@ export function form(id) {
|
|
|
82
82
|
|
|
83
83
|
let submitted = false;
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @param {FormData} form_data
|
|
87
|
+
* @returns {Record<string, any>}
|
|
88
|
+
*/
|
|
89
|
+
function convert(form_data) {
|
|
90
|
+
const data = convert_formdata(form_data);
|
|
91
|
+
if (key !== undefined && !form_data.has('id')) {
|
|
92
|
+
data.id = key;
|
|
93
|
+
}
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
|
|
85
97
|
/**
|
|
86
98
|
* @param {HTMLFormElement} form
|
|
87
99
|
* @param {FormData} form_data
|
|
88
100
|
* @param {Parameters<RemoteForm<any, any>['enhance']>[0]} callback
|
|
89
101
|
*/
|
|
90
102
|
async function handle_submit(form, form_data, callback) {
|
|
91
|
-
const data =
|
|
103
|
+
const data = convert(form_data);
|
|
92
104
|
|
|
93
105
|
submitted = true;
|
|
94
106
|
|
|
@@ -500,14 +512,19 @@ export function form(id) {
|
|
|
500
512
|
|
|
501
513
|
const id = ++validate_id;
|
|
502
514
|
|
|
515
|
+
// wait a tick in case the user is calling validate() right after set() which takes time to propagate
|
|
516
|
+
await tick();
|
|
517
|
+
|
|
503
518
|
const form_data = new FormData(element, submitter);
|
|
504
519
|
|
|
505
520
|
/** @type {readonly StandardSchemaV1.Issue[]} */
|
|
506
521
|
let array = [];
|
|
507
522
|
|
|
508
|
-
const validated = await preflight_schema?.['~standard'].validate(
|
|
509
|
-
|
|
510
|
-
)
|
|
523
|
+
const validated = await preflight_schema?.['~standard'].validate(convert(form_data));
|
|
524
|
+
|
|
525
|
+
if (validate_id !== id) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
511
528
|
|
|
512
529
|
if (validated?.issues) {
|
|
513
530
|
array = validated.issues;
|
|
@@ -31,6 +31,10 @@ export function convert_formdata(data) {
|
|
|
31
31
|
let result = Object.create(null); // guard against prototype pollution
|
|
32
32
|
|
|
33
33
|
for (let key of data.keys()) {
|
|
34
|
+
if (key.startsWith('sveltekit:')) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
const is_array = key.endsWith('[]');
|
|
35
39
|
/** @type {any[]} */
|
|
36
40
|
let values = data.getAll(key);
|
|
@@ -13,7 +13,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
|
13
13
|
import { SCHEME } from '../../../utils/url.js';
|
|
14
14
|
import { create_server_routing_response, generate_route_object } from './server_routing.js';
|
|
15
15
|
import { add_resolution_suffix } from '../../pathname.js';
|
|
16
|
-
import { with_request_store } from '@sveltejs/kit/internal/server';
|
|
16
|
+
import { try_get_request_store, with_request_store } from '@sveltejs/kit/internal/server';
|
|
17
17
|
import { text_encoder } from '../../utils.js';
|
|
18
18
|
import { get_global_name } from '../utils.js';
|
|
19
19
|
import { create_remote_cache_key } from '../../shared.js';
|
|
@@ -190,7 +190,7 @@ export async function render_response({
|
|
|
190
190
|
throw new Error(
|
|
191
191
|
`Cannot call \`fetch\` eagerly during server-side rendering with relative URL (${info}) — put your \`fetch\` calls inside \`onMount\` or a \`load\` function instead`
|
|
192
192
|
);
|
|
193
|
-
} else if (!warned) {
|
|
193
|
+
} else if (!warned && !try_get_request_store()?.state.is_in_remote_function) {
|
|
194
194
|
console.warn(
|
|
195
195
|
'Avoid calling `fetch` eagerly during server-side rendering — put your `fetch` calls inside `onMount` or a `load` function instead'
|
|
196
196
|
);
|
|
@@ -37,7 +37,7 @@ export async function handle_remote_call(event, state, options, manifest, id) {
|
|
|
37
37
|
* @param {string} id
|
|
38
38
|
*/
|
|
39
39
|
async function handle_remote_call_internal(event, state, options, manifest, id) {
|
|
40
|
-
const [hash, name,
|
|
40
|
+
const [hash, name, additional_args] = id.split('/');
|
|
41
41
|
const remotes = manifest._.remotes;
|
|
42
42
|
|
|
43
43
|
if (!remotes[hash]) error(404);
|
|
@@ -122,6 +122,11 @@ async function handle_remote_call_internal(event, state, options, manifest, id)
|
|
|
122
122
|
);
|
|
123
123
|
form_data.delete('sveltekit:remote_refreshes');
|
|
124
124
|
|
|
125
|
+
// If this is a keyed form instance (created via form.for(key)), add the key to the form data (unless already set)
|
|
126
|
+
if (additional_args) {
|
|
127
|
+
form_data.set('sveltekit:id', decodeURIComponent(additional_args));
|
|
128
|
+
}
|
|
129
|
+
|
|
125
130
|
const fn = info.fn;
|
|
126
131
|
const data = await with_request_store({ event, state }, () => fn(form_data));
|
|
127
132
|
|
|
@@ -151,7 +156,7 @@ async function handle_remote_call_internal(event, state, options, manifest, id)
|
|
|
151
156
|
|
|
152
157
|
const payload =
|
|
153
158
|
info.type === 'prerender'
|
|
154
|
-
?
|
|
159
|
+
? additional_args
|
|
155
160
|
: /** @type {string} */ (
|
|
156
161
|
// new URL(...) necessary because we're hiding the URL from the user in the event object
|
|
157
162
|
new URL(event.request.url).searchParams.get('payload')
|
|
@@ -289,6 +294,12 @@ async function handle_remote_form_post_internal(event, state, manifest, id) {
|
|
|
289
294
|
const form_data = await event.request.formData();
|
|
290
295
|
const fn = /** @type {RemoteInfo & { type: 'form' }} */ (/** @type {any} */ (form).__).fn;
|
|
291
296
|
|
|
297
|
+
// If this is a keyed form instance (created via form.for(key)), add the key to the form data (unless already set)
|
|
298
|
+
if (action_id && !form_data.has('id')) {
|
|
299
|
+
// The action_id is URL-encoded JSON, decode and parse it
|
|
300
|
+
form_data.set('sveltekit:id', decodeURIComponent(action_id));
|
|
301
|
+
}
|
|
302
|
+
|
|
292
303
|
await with_request_store({ event, state }, () => fn(form_data));
|
|
293
304
|
|
|
294
305
|
// We don't want the data to appear on `let { form } = $props()`, which is why we're not returning it.
|
|
@@ -148,7 +148,8 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
148
148
|
handleValidationError: options.hooks.handleValidationError,
|
|
149
149
|
tracing: {
|
|
150
150
|
record_span
|
|
151
|
-
}
|
|
151
|
+
},
|
|
152
|
+
is_in_remote_function: false
|
|
152
153
|
};
|
|
153
154
|
|
|
154
155
|
/** @type {import('@sveltejs/kit').RequestEvent} */
|
package/src/types/internal.d.ts
CHANGED
|
@@ -604,6 +604,7 @@ export interface RequestState {
|
|
|
604
604
|
tracing: {
|
|
605
605
|
record_span: RecordSpan;
|
|
606
606
|
};
|
|
607
|
+
is_in_remote_function: boolean;
|
|
607
608
|
form_instances?: Map<any, any>;
|
|
608
609
|
remote_data?: Map<RemoteInfo, Record<string, MaybePromise<any>>>;
|
|
609
610
|
refreshes?: Record<string, Promise<any>>;
|
package/src/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1901,7 +1901,7 @@ declare module '@sveltejs/kit' {
|
|
|
1901
1901
|
: RemoteFormFieldContainer<T> & { [K in keyof T]-?: RemoteFormFields<T[K]> };
|
|
1902
1902
|
|
|
1903
1903
|
// By breaking this out into its own type, we avoid the TS recursion depth limit
|
|
1904
|
-
type RecursiveFormFields = RemoteFormField<any> & { [key: string]: RecursiveFormFields };
|
|
1904
|
+
type RecursiveFormFields = RemoteFormField<any> & { [key: string | number]: RecursiveFormFields };
|
|
1905
1905
|
|
|
1906
1906
|
type MaybeArray<T> = T | T[];
|
|
1907
1907
|
|
|
@@ -1913,6 +1913,57 @@ declare module '@sveltejs/kit' {
|
|
|
1913
1913
|
message: string;
|
|
1914
1914
|
}
|
|
1915
1915
|
|
|
1916
|
+
// If the schema specifies `id` as a string or number, ensure that `for(...)`
|
|
1917
|
+
// only accepts that type. Otherwise, accept `string | number`
|
|
1918
|
+
type ExtractId<Input> = Input extends { id: infer Id }
|
|
1919
|
+
? Id extends string | number
|
|
1920
|
+
? Id
|
|
1921
|
+
: string | number
|
|
1922
|
+
: string | number;
|
|
1923
|
+
|
|
1924
|
+
/**
|
|
1925
|
+
* Recursively maps an input type to a structure where each field can create a validation issue.
|
|
1926
|
+
* This mirrors the runtime behavior of the `invalid` proxy passed to form handlers.
|
|
1927
|
+
*/
|
|
1928
|
+
type InvalidField<T> =
|
|
1929
|
+
WillRecurseIndefinitely<T> extends true
|
|
1930
|
+
? Record<string | number, any>
|
|
1931
|
+
: NonNullable<T> extends string | number | boolean | File
|
|
1932
|
+
? (message: string) => StandardSchemaV1.Issue
|
|
1933
|
+
: NonNullable<T> extends Array<infer U>
|
|
1934
|
+
? {
|
|
1935
|
+
[K in number]: InvalidField<U>;
|
|
1936
|
+
} & ((message: string) => StandardSchemaV1.Issue)
|
|
1937
|
+
: NonNullable<T> extends RemoteFormInput
|
|
1938
|
+
? {
|
|
1939
|
+
[K in keyof T]-?: InvalidField<T[K]>;
|
|
1940
|
+
} & ((message: string) => StandardSchemaV1.Issue)
|
|
1941
|
+
: Record<string, never>;
|
|
1942
|
+
|
|
1943
|
+
/**
|
|
1944
|
+
* A function and proxy object used to imperatively create validation errors in form handlers.
|
|
1945
|
+
*
|
|
1946
|
+
* Call `invalid(issue1, issue2, ...issueN)` to throw a validation error.
|
|
1947
|
+
* If an issue is a `string`, it applies to the form as a whole (and will show up in `fields.allIssues()`)
|
|
1948
|
+
* Access properties to create field-specific issues: `invalid.fieldName('message')`.
|
|
1949
|
+
* The type structure mirrors the input data structure for type-safe field access.
|
|
1950
|
+
*
|
|
1951
|
+
* @example
|
|
1952
|
+
* ```ts
|
|
1953
|
+
* invalid('Username or password is invalid');
|
|
1954
|
+
* ```
|
|
1955
|
+
*
|
|
1956
|
+
* @example
|
|
1957
|
+
* ```ts
|
|
1958
|
+
* invalid(
|
|
1959
|
+
* invalid.username('Username is taken'),
|
|
1960
|
+
* invalid.items[0].qty('Insufficient stock')
|
|
1961
|
+
* );
|
|
1962
|
+
* ```
|
|
1963
|
+
*/
|
|
1964
|
+
export type Invalid<Input = any> = ((...issues: Array<string | StandardSchemaV1.Issue>) => never) &
|
|
1965
|
+
InvalidField<Input>;
|
|
1966
|
+
|
|
1916
1967
|
/**
|
|
1917
1968
|
* The return value of a remote `form` function. See [Remote functions](https://svelte.dev/docs/kit/remote-functions#form) for full documentation.
|
|
1918
1969
|
*/
|
|
@@ -1937,8 +1988,8 @@ declare module '@sveltejs/kit' {
|
|
|
1937
1988
|
[attachment: symbol]: (node: HTMLFormElement) => void;
|
|
1938
1989
|
};
|
|
1939
1990
|
/**
|
|
1940
|
-
* Create an instance of the form for the given
|
|
1941
|
-
* The
|
|
1991
|
+
* Create an instance of the form for the given `id`.
|
|
1992
|
+
* The `id` is stringified and used for deduplication to potentially reuse existing instances.
|
|
1942
1993
|
* Useful when you have multiple forms that use the same remote form action, for example in a loop.
|
|
1943
1994
|
* ```svelte
|
|
1944
1995
|
* {#each todos as todo}
|
|
@@ -1950,7 +2001,7 @@ declare module '@sveltejs/kit' {
|
|
|
1950
2001
|
* {/each}
|
|
1951
2002
|
* ```
|
|
1952
2003
|
*/
|
|
1953
|
-
for(
|
|
2004
|
+
for(id: ExtractId<Input>): Omit<RemoteForm<Input, Output>, 'for'>;
|
|
1954
2005
|
/** Preflight checks */
|
|
1955
2006
|
preflight(schema: StandardSchemaV1<Input, any>): RemoteForm<Input, Output>;
|
|
1956
2007
|
/** Validate the form contents programmatically */
|
|
@@ -3100,7 +3151,7 @@ declare module '$app/server' {
|
|
|
3100
3151
|
*
|
|
3101
3152
|
* @since 2.27
|
|
3102
3153
|
*/
|
|
3103
|
-
export function form<Output>(fn: () => MaybePromise<Output>): RemoteForm<void, Output>;
|
|
3154
|
+
export function form<Output>(fn: (invalid: import("@sveltejs/kit").Invalid<void>) => MaybePromise<Output>): RemoteForm<void, Output>;
|
|
3104
3155
|
/**
|
|
3105
3156
|
* Creates a form object that can be spread onto a `<form>` element.
|
|
3106
3157
|
*
|
|
@@ -3108,7 +3159,7 @@ declare module '$app/server' {
|
|
|
3108
3159
|
*
|
|
3109
3160
|
* @since 2.27
|
|
3110
3161
|
*/
|
|
3111
|
-
export function form<Input extends RemoteFormInput, Output>(validate: "unchecked", fn: (data: Input) => MaybePromise<Output>): RemoteForm<Input, Output>;
|
|
3162
|
+
export function form<Input extends RemoteFormInput, Output>(validate: "unchecked", fn: (data: Input, invalid: import("@sveltejs/kit").Invalid<Input>) => MaybePromise<Output>): RemoteForm<Input, Output>;
|
|
3112
3163
|
/**
|
|
3113
3164
|
* Creates a form object that can be spread onto a `<form>` element.
|
|
3114
3165
|
*
|
|
@@ -3116,7 +3167,7 @@ declare module '$app/server' {
|
|
|
3116
3167
|
*
|
|
3117
3168
|
* @since 2.27
|
|
3118
3169
|
*/
|
|
3119
|
-
export function form<Schema extends StandardSchemaV1<RemoteFormInput, Record<string, any>>, Output>(validate: Schema, fn: (data: StandardSchemaV1.InferOutput<Schema
|
|
3170
|
+
export function form<Schema extends StandardSchemaV1<RemoteFormInput, Record<string, any>>, Output>(validate: Schema, fn: (data: StandardSchemaV1.InferOutput<Schema>, invalid: import("@sveltejs/kit").Invalid<StandardSchemaV1.InferOutput<Schema>>) => MaybePromise<Output>): RemoteForm<StandardSchemaV1.InferInput<Schema>, Output>;
|
|
3120
3171
|
/**
|
|
3121
3172
|
* Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call.
|
|
3122
3173
|
*
|
package/types/index.d.ts.map
CHANGED
|
@@ -71,6 +71,9 @@
|
|
|
71
71
|
"MaybeArray",
|
|
72
72
|
"RemoteFormInput",
|
|
73
73
|
"RemoteFormIssue",
|
|
74
|
+
"ExtractId",
|
|
75
|
+
"InvalidField",
|
|
76
|
+
"Invalid",
|
|
74
77
|
"RemoteForm",
|
|
75
78
|
"RemoteCommand",
|
|
76
79
|
"RemoteResource",
|
|
@@ -208,6 +211,6 @@
|
|
|
208
211
|
null,
|
|
209
212
|
null
|
|
210
213
|
],
|
|
211
|
-
"mappings": "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
|
|
214
|
+
"mappings": "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",
|
|
212
215
|
"ignoreList": []
|
|
213
216
|
}
|