@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.44.0",
3
+ "version": "2.46.0",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -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 key.
1965
- * The key is stringified and used for deduplication to potentially reuse existing instances.
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(key: string | number | boolean): Omit<RemoteForm<Input, Output>, '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
- if (imported_by_remotes.has(id)) {
689
- return `chunk-${uid++}`;
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>) => MaybePromise<Output>} fn
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 {(data?: Input) => MaybePromise<Output>} [maybe_fn]
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 {(data?: Input) => Output} */
64
+ /** @type {any} */
65
65
  const fn = maybe_fn ?? validate_or_fn;
66
66
 
67
67
  /** @type {StandardSchemaV1 | null} */
68
- const schema = !maybe_fn || validate_or_fn === 'unchecked' ? null : validate_or_fn;
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 = flatten_issues(validated.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
- output.result = await run_remote_function(event, state, true, data, (d) => d, fn);
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 {RequestEvent} */
107
- const cleansed = {
108
- ...event,
109
- setHeaders: () => {
110
- throw new Error('setHeaders is not allowed in remote functions');
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
- delete: (name, opts) => {
126
- if (!allow_cookies) {
127
- throw new Error('Cannot delete cookies in `query` or `prerender` functions');
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({ event: cleansed, state }, () => validate(arg));
141
- return with_request_store({ event: cleansed, state }, () => fn(validated));
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 = convert_formdata(form_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
- convert_formdata(form_data)
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, prerender_args] = id.split('/');
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
- ? prerender_args
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} */
@@ -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
@@ -1,4 +1,4 @@
1
1
  // generated during release, do not modify
2
2
 
3
3
  /** @type {string} */
4
- export const VERSION = '2.44.0';
4
+ export const VERSION = '2.46.0';
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 key.
1941
- * The key is stringified and used for deduplication to potentially reuse existing instances.
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(key: string | number | boolean): Omit<RemoteForm<Input, Output>, '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>) => MaybePromise<Output>): RemoteForm<StandardSchemaV1.InferInput<Schema>, Output>;
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
  *
@@ -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": ";;;;;;;;;;;kBAkCiBA,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAiCZC,cAAcA;;;;;;aAMdC,cAAcA;;;;;;;;MAQrBC,aAAaA;;;;;OAKJC,YAAYA;;kBAETC,aAAaA;;;;;;MAMzBC,qBAAqBA;;;;;;;;;;;kBAWTC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8IPC,MAAMA;;;;;;;;;;;kBAWNC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4DPC,QAAQA;;;;;;;;kBAQRC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAqkBdC,MAAMA;;;;;;;;;;;aAWNC,iBAAiBA;;;;;;;;;;;;aAYjBC,qBAAqBA;;;;;;;;;aASrBC,iBAAiBA;;;;;;;;;;aAUjBC,WAAWA;;;;;;;;;;aAUXC,UAAUA;;;;;;aAMVC,UAAUA;;;;;;aAMVC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;aA0BPC,SAASA;;;;;kBAKJC,WAAWA;;;;;;;;;;;;aAYhBC,IAAIA;;;;;;;;;;;;kBAYCC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAyHTC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0BfC,gBAAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAgCrBC,cAAcA;;kBAETC,cAAcA;;;;;;;;;;;;;;;;;;;;kBAoBdC,eAAeA;;;;;;;;;;;;;;;;;;;;;;kBAsBfC,kBAAkBA;;;;;;;;;;;;;;;;;;;kBAmBlBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;kBAwBpBC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;kBAsBlBC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;aAwBnBC,UAAUA;;;;;;;;;aASVC,cAAcA;;;;;;;;;;aAUdC,UAAUA;;;;;;;;;;;;;;;;;;aAkBVC,aAAaA;;;;;;;;;;;;;;;;;;;kBAmBRC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA8CTC,YAAYA;;kBAEPC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA+GjBC,cAAcA;;;;;kBAKTC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;kBAuBdC,eAAeA;;;;;;;;;;;;;;;cAenBC,MAAMA;;;;;;kBAMFC,iBAAiBA;;;;;;;kBAOjBC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;aAyBhBC,UAAUA;;;;;;;kBAOLC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAkFpBC,MAAMA;;;;;;;;;;aAUNC,OAAOA;;;;;;;;;;;;;;;;aAgBPC,YAAYA;;;;;;;;;;;;kBCrtDXC,SAASA;;;;;;;;;;kBAqBTC,QAAQA;;;;;;;aD6tDTC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6BTC,QAAQA;;;;;;MAMpBC,uBAAuBA;;;MAGvBC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6BLC,mBAAmBA;;;;;MAK1BC,iBAAiBA;;;;;;;;;;;;;;;;;;;;;MAqBjBC,sBAAsBA;;;;;;;;;aASfC,oBAAoBA;;MAE3BC,MAAMA;;;;;;;;;;;aAWCC,eAAeA;;;;;;;;;;;;;;MActBC,wBAAwBA;;;;;;;;MAQxBC,gBAAgBA;;;;;;;;;;;;MAYhBC,mBAAmBA;;MAEnBC,UAAUA;;kBAEEC,eAAeA;;;;kBAIfC,eAAeA;;;;;;MAM3BC,SAASA;;;;;;;;;;MAUTC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAoCLC,OAAOA;;;;;;aAMPC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA8EVC,aAAaA;;;;;;;;aAQbC,cAAcA;;;;;;;;;;;;;;;;;;aAkBdC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqCNC,mBAAmBA;;;;;;;;aAQxBC,uBAAuBA;;;;;aAKvBC,mBAAmBA;WE7lEdC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAkDZC,GAAGA;;;;;;;;;;;;;;;;;;;;;WAqBHC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmElBC,UAAUA;;WAELC,MAAMA;;;;;;;;;MASXC,YAAYA;;WAEPC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmCXC,yBAAyBA;;;;;;;;;;WAUzBC,yBAAyBA;;;;WAIzBC,sCAAsCA;;;;WAItCC,4BAA4BA;;;;MAIjCC,8BAA8BA;MAC9BC,8BAA8BA;MAC9BC,iCAAiCA;;;;;MAKjCC,2CAA2CA;;;;;;aAM3CC,eAAeA;;WAIVC,cAAcA;;;;;WAKdC,YAAYA;;;;;;MAMjBC,aAAaA;WC9LRC,KAAKA;;;;;;WAeLC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAuHTC,YAAYA;;;;;;;;;;;;;WAkBZC,QAAQA;;;;;;;;;;;;;;MAgCbC,iBAAiBA;;;;;;;;;WAWZC,UAAUA;;;;;;;;;;;;;WAaVC,SAASA;;;;;;;;;;;;;;;;;;;;;;;WAsHTC,YAAYA;;;;;;;;;;;;;;;;MAgBjBC,kBAAkBA;;WAEbC,aAAaA;;;;;;;;;;WAUbC,UAAUA;;;;;;;;;;;WAWVC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;MAuBZC,aAAaA;;WA8BRC,eAAeA;;;;;;MAMpBC,uBAAuBA;;MAGvBC,WAAWA;;;;;;;;WAQNC,QAAQA;;;;;;;;;WASRC,cAAcA;;;;;;;;;MA+CnBC,eAAeA;;;;;MAKfC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC7cdC,WAAWA;;;;;;;;;;;;;;;;;;;iBAsBXC,QAAQA;;;;;iBAiBRC,UAAUA;;;;;;iBASVC,IAAIA;;;;;;iBA4BJC,IAAIA;;;;;;;;;;;;;;;;iBAkDJC,eAAeA;;;;;;;;;;;;;;iBAmBfC,YAAYA;;;;;;;cCrOfC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC4EJC,QAAQA;;;;;;iBC4BFC,UAAUA;;;;;;iBAkCVC,WAAWA;;;;;iBAgFjBC,oBAAoBA;;;;;;;;;;;iBC3MpBC,gBAAgBA;;;;;;;;;iBCsHVC,SAASA;;;;;;;;;cCrIlBC,OAAOA;;;;;cAKPC,GAAGA;;;;;cAKHC,QAAQA;;;;;cAKRC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;iBCYJC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;iBAgDXC,OAAOA;;;;;;;iBCuqEDC,WAAWA;;;;;;;;;;;iBAhVjBC,aAAaA;;;;;;;;;;;;iBAiBbC,cAAcA;;;;;;;;;;iBAedC,UAAUA;;;;;iBASVC,qBAAqBA;;;;;;;;;;iBA8BrBC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCJC,UAAUA;;;;iBA0BVC,aAAaA;;;;;iBAebC,UAAUA;;;;;;;;;;;;;;iBAuBJC,WAAWA;;;;;;;;;;;;;;;;;;iBAoCXC,WAAWA;;;;;iBAsCjBC,SAASA;;;;;iBA+CTC,YAAYA;MVhjEhBlE,YAAYA;;;;;;;;;;;;;;YW/IbmE,IAAIA;;;;;;;;;YASJC,MAAMA;;;;;iBAKDC,YAAYA;;;MCxBhBC,WAAWA;;;;;;;;;;;;;;;;;;;;;iBCqBPC,KAAKA;;;;;;;;;;;;;;;;;;;;;iBA2BLC,OAAOA;;;;;;;;;;;;;;;;;;;;iBC/BPC,IAAIA;;;;;;;;iBCSJC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MdicnBC,8BAA8BA;MDlU9B3E,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cgB1GX4E,IAAIA;;;;;cAQJC,UAAUA;;;;;;;;;;;cAMVC,OAAOA;;;;;;;;;iBCrDPC,SAASA;;;;;;;;;;;;;;;cAyBTH,IAAIA;;;;;;;;;;cAiBJC,UAAUA;;;;;;;;cAeVC,OAAOA",
212
215
  "ignoreList": []
213
216
  }