@sveltejs/kit 2.47.2 → 2.47.3

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.47.2",
3
+ "version": "2.47.3",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -105,7 +105,8 @@ async function analyse({
105
105
  }
106
106
 
107
107
  metadata.nodes[node.index] = {
108
- has_server_load: has_server_load(node)
108
+ has_server_load: has_server_load(node),
109
+ has_universal_load: node.universal?.load !== undefined
109
110
  };
110
111
  }
111
112
 
@@ -1914,10 +1914,28 @@ type RemoteFormFieldContainer<Value> = RemoteFormFieldMethods<Value> & {
1914
1914
  allIssues(): RemoteFormIssue[] | undefined;
1915
1915
  };
1916
1916
 
1917
+ type UnknownField<Value> = RemoteFormFieldMethods<Value> & {
1918
+ /** Validation issues belonging to this or any of the fields that belong to it, if any */
1919
+ allIssues(): RemoteFormIssue[] | undefined;
1920
+ /**
1921
+ * Returns an object that can be spread onto an input element with the correct type attribute,
1922
+ * aria-invalid attribute if the field is invalid, and appropriate value/checked property getters/setters.
1923
+ * @example
1924
+ * ```svelte
1925
+ * <input {...myForm.fields.myString.as('text')} />
1926
+ * <input {...myForm.fields.myNumber.as('number')} />
1927
+ * <input {...myForm.fields.myBoolean.as('checkbox')} />
1928
+ * ```
1929
+ */
1930
+ as<T extends RemoteFormFieldType<Value>>(...args: AsArgs<T, Value>): InputElementProps<T>;
1931
+ } & {
1932
+ [key: string | number]: UnknownField<any>;
1933
+ };
1934
+
1917
1935
  /**
1918
1936
  * Recursive type to build form fields structure with proxy access
1919
1937
  */
1920
- type RemoteFormFields<T> =
1938
+ export type RemoteFormFields<T> =
1921
1939
  WillRecurseIndefinitely<T> extends true
1922
1940
  ? RecursiveFormFields
1923
1941
  : NonNullable<T> extends string | number | boolean | File
@@ -1925,11 +1943,17 @@ type RemoteFormFields<T> =
1925
1943
  : T extends string[] | File[]
1926
1944
  ? RemoteFormField<T> & { [K in number]: RemoteFormField<T[number]> }
1927
1945
  : T extends Array<infer U>
1928
- ? RemoteFormFieldContainer<T> & { [K in number]: RemoteFormFields<U> }
1929
- : RemoteFormFieldContainer<T> & { [K in keyof T]-?: RemoteFormFields<T[K]> };
1946
+ ? RemoteFormFieldContainer<T> & {
1947
+ [K in number]: RemoteFormFields<U>;
1948
+ }
1949
+ : RemoteFormFieldContainer<T> & {
1950
+ [K in keyof T]-?: RemoteFormFields<T[K]>;
1951
+ };
1930
1952
 
1931
1953
  // By breaking this out into its own type, we avoid the TS recursion depth limit
1932
- type RecursiveFormFields = RemoteFormField<any> & { [key: string | number]: RecursiveFormFields };
1954
+ type RecursiveFormFields = RemoteFormFieldContainer<any> & {
1955
+ [key: string | number]: UnknownField<any>;
1956
+ };
1933
1957
 
1934
1958
  type MaybeArray<T> = T | T[];
1935
1959
 
@@ -172,8 +172,8 @@ let secondary_build_started = false;
172
172
  /** @type {import('types').ManifestData} */
173
173
  let manifest_data;
174
174
 
175
- /** @type {import('types').ServerMetadata['remotes'] | undefined} only set at build time */
176
- let remote_exports = undefined;
175
+ /** @type {import('types').ServerMetadata | undefined} only set at build time once analysis is finished */
176
+ let build_metadata = undefined;
177
177
 
178
178
  /**
179
179
  * Returns the SvelteKit Vite plugin. Vite executes Rollup hooks as well as some of its own.
@@ -369,12 +369,28 @@ async function kit({ svelte_config }) {
369
369
 
370
370
  if (!secondary_build_started) {
371
371
  manifest_data = sync.all(svelte_config, config_env.mode).manifest_data;
372
+ // During the initial server build we don't know yet
373
+ new_config.define.__SVELTEKIT_HAS_SERVER_LOAD__ = 'true';
374
+ new_config.define.__SVELTEKIT_HAS_UNIVERSAL_LOAD__ = 'true';
375
+ } else {
376
+ const nodes = Object.values(
377
+ /** @type {import('types').ServerMetadata} */ (build_metadata).nodes
378
+ );
379
+
380
+ // Through the finished analysis we can now check if any node has server or universal load functions
381
+ const has_server_load = nodes.some((node) => node.has_server_load);
382
+ const has_universal_load = nodes.some((node) => node.has_universal_load);
383
+
384
+ new_config.define.__SVELTEKIT_HAS_SERVER_LOAD__ = s(has_server_load);
385
+ new_config.define.__SVELTEKIT_HAS_UNIVERSAL_LOAD__ = s(has_universal_load);
372
386
  }
373
387
  } else {
374
388
  new_config.define = {
375
389
  ...define,
376
390
  __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: '0',
377
- __SVELTEKIT_PAYLOAD__: 'globalThis.__sveltekit_dev'
391
+ __SVELTEKIT_PAYLOAD__: 'globalThis.__sveltekit_dev',
392
+ __SVELTEKIT_HAS_SERVER_LOAD__: 'true',
393
+ __SVELTEKIT_HAS_UNIVERSAL_LOAD__: 'true'
378
394
  };
379
395
 
380
396
  // @ts-ignore this prevents a reference error if `client.js` is imported on the server
@@ -733,8 +749,8 @@ async function kit({ svelte_config }) {
733
749
 
734
750
  // in prod, we already built and analysed the server code before
735
751
  // building the client code, so `remote_exports` is populated
736
- else if (remote_exports) {
737
- const exports = remote_exports.get(remote.hash);
752
+ else if (build_metadata?.remotes) {
753
+ const exports = build_metadata?.remotes.get(remote.hash);
738
754
  if (!exports) throw new Error('Expected to find metadata for remote file ' + id);
739
755
 
740
756
  for (const [name, value] of exports) {
@@ -1038,7 +1054,7 @@ async function kit({ svelte_config }) {
1038
1054
  remotes
1039
1055
  });
1040
1056
 
1041
- remote_exports = metadata.remotes;
1057
+ build_metadata = metadata;
1042
1058
 
1043
1059
  log.info('Building app');
1044
1060
 
@@ -4,7 +4,7 @@ import { read } from '../../../utils/filesystem.js';
4
4
 
5
5
  const inheritable_page_options = new Set(['ssr', 'prerender', 'csr', 'trailingSlash', 'config']);
6
6
 
7
- const valid_page_options = new Set([...inheritable_page_options, 'entries']);
7
+ const valid_page_options = new Set([...inheritable_page_options, 'entries', 'load']);
8
8
 
9
9
  const skip_parsing_regex = new RegExp(
10
10
  `${Array.from(valid_page_options).join('|')}|(?:export[\\s\\n]+\\*[\\s\\n]+from)`
@@ -14,7 +14,8 @@ const parser = Parser.extend(tsPlugin());
14
14
 
15
15
  /**
16
16
  * Collects page options from a +page.js/+layout.js file, ignoring reassignments
17
- * and using the declared value. Returns `null` if any export is too difficult to analyse.
17
+ * and using the declared value (except for load functions, for which the value is `true`).
18
+ * Returns `null` if any export is too difficult to analyse.
18
19
  * @param {string} filename The name of the file to report when an error occurs
19
20
  * @param {string} input
20
21
  * @returns {Record<string, any> | null}
@@ -116,6 +117,13 @@ export function statically_analyse_page_options(filename, input) {
116
117
  continue;
117
118
  }
118
119
 
120
+ // Special case: We only want to know that 'load' is exported (in a way that doesn't cause truthy checks in other places to trigger)
121
+ if (variable_declarator.id.name === 'load') {
122
+ page_options.set('load', null);
123
+ export_specifiers.delete('load');
124
+ continue;
125
+ }
126
+
119
127
  // references a declaration we can't easily evaluate statically
120
128
  return null;
121
129
  }
@@ -138,7 +146,12 @@ export function statically_analyse_page_options(filename, input) {
138
146
  // class and function declarations
139
147
  if (statement.declaration.type !== 'VariableDeclaration') {
140
148
  if (valid_page_options.has(statement.declaration.id.name)) {
141
- return null;
149
+ // Special case: We only want to know that 'load' is exported (in a way that doesn't cause truthy checks in other places to trigger)
150
+ if (statement.declaration.id.name === 'load') {
151
+ page_options.set('load', null);
152
+ } else {
153
+ return null;
154
+ }
142
155
  }
143
156
  continue;
144
157
  }
@@ -157,6 +170,12 @@ export function statically_analyse_page_options(filename, input) {
157
170
  continue;
158
171
  }
159
172
 
173
+ // Special case: We only want to know that 'load' is exported (in a way that doesn't cause truthy checks in other places to trigger)
174
+ if (declaration.id.name === 'load') {
175
+ page_options.set('load', null);
176
+ continue;
177
+ }
178
+
160
179
  // references a declaration we can't easily evaluate statically
161
180
  return null;
162
181
  }
@@ -187,7 +206,7 @@ export function get_name(node) {
187
206
  */
188
207
  export function create_node_analyser({ resolve, static_exports = new Map() }) {
189
208
  /**
190
- * Computes the final page options for a node (if possible). Otherwise, returns `null`.
209
+ * Computes the final page options (may include load function as `load: null`; special case) for a node (if possible). Otherwise, returns `null`.
191
210
  * @param {import('types').PageNode} node
192
211
  * @returns {Promise<Record<string, any> | null>}
193
212
  */
@@ -11,7 +11,7 @@ import {
11
11
  deep_set,
12
12
  normalize_issue,
13
13
  flatten_issues
14
- } from '../../../form-utils.svelte.js';
14
+ } from '../../../form-utils.js';
15
15
  import { get_cache, run_remote_function } from './shared.js';
16
16
 
17
17
  /**
@@ -215,7 +215,6 @@ export function form(validate_or_fn, maybe_fn) {
215
215
  return create_field_proxy(
216
216
  {},
217
217
  () => data?.input ?? {},
218
- () => {},
219
218
  (path, value) => {
220
219
  if (data?.submission) {
221
220
  // don't override a submission
@@ -318,7 +317,7 @@ function handle_issues(output, issues, is_remote_request, form_data) {
318
317
 
319
318
  if (is_array) key = key.slice(0, -2);
320
319
 
321
- output.input = set_nested_value(
320
+ set_nested_value(
322
321
  /** @type {Record<string, any>} */ (output.input),
323
322
  key,
324
323
  is_array ? values : values[0]
@@ -732,7 +732,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node
732
732
  }
733
733
  }
734
734
 
735
- if (node.universal?.load) {
735
+ if (__SVELTEKIT_HAS_UNIVERSAL_LOAD__ && node.universal?.load) {
736
736
  /** @param {string[]} deps */
737
737
  function depends(...deps) {
738
738
  for (const dep of deps) {
@@ -1004,49 +1004,52 @@ async function load_route({ id, invalidating, url, params, route, preload }) {
1004
1004
  const search_params_changed = diff_search_params(current.url, url);
1005
1005
 
1006
1006
  let parent_invalid = false;
1007
- const invalid_server_nodes = loaders.map((loader, i) => {
1008
- const previous = current.branch[i];
1009
1007
 
1010
- const invalid =
1011
- !!loader?.[0] &&
1012
- (previous?.loader !== loader[1] ||
1013
- has_changed(
1014
- parent_invalid,
1015
- route_changed,
1016
- url_changed,
1017
- search_params_changed,
1018
- previous.server?.uses,
1019
- params
1020
- ));
1021
-
1022
- if (invalid) {
1023
- // For the next one
1024
- parent_invalid = true;
1025
- }
1008
+ if (__SVELTEKIT_HAS_SERVER_LOAD__) {
1009
+ const invalid_server_nodes = loaders.map((loader, i) => {
1010
+ const previous = current.branch[i];
1011
+
1012
+ const invalid =
1013
+ !!loader?.[0] &&
1014
+ (previous?.loader !== loader[1] ||
1015
+ has_changed(
1016
+ parent_invalid,
1017
+ route_changed,
1018
+ url_changed,
1019
+ search_params_changed,
1020
+ previous.server?.uses,
1021
+ params
1022
+ ));
1023
+
1024
+ if (invalid) {
1025
+ // For the next one
1026
+ parent_invalid = true;
1027
+ }
1026
1028
 
1027
- return invalid;
1028
- });
1029
+ return invalid;
1030
+ });
1029
1031
 
1030
- if (invalid_server_nodes.some(Boolean)) {
1031
- try {
1032
- server_data = await load_data(url, invalid_server_nodes);
1033
- } catch (error) {
1034
- const handled_error = await handle_error(error, { url, params, route: { id } });
1032
+ if (invalid_server_nodes.some(Boolean)) {
1033
+ try {
1034
+ server_data = await load_data(url, invalid_server_nodes);
1035
+ } catch (error) {
1036
+ const handled_error = await handle_error(error, { url, params, route: { id } });
1035
1037
 
1036
- if (preload_tokens.has(preload)) {
1037
- return preload_error({ error: handled_error, url, params, route });
1038
- }
1038
+ if (preload_tokens.has(preload)) {
1039
+ return preload_error({ error: handled_error, url, params, route });
1040
+ }
1039
1041
 
1040
- return load_root_error_page({
1041
- status: get_status(error),
1042
- error: handled_error,
1043
- url,
1044
- route
1045
- });
1046
- }
1042
+ return load_root_error_page({
1043
+ status: get_status(error),
1044
+ error: handled_error,
1045
+ url,
1046
+ route
1047
+ });
1048
+ }
1047
1049
 
1048
- if (server_data.type === 'redirect') {
1049
- return server_data;
1050
+ if (server_data.type === 'redirect') {
1051
+ return server_data;
1052
+ }
1050
1053
  }
1051
1054
  }
1052
1055
 
@@ -1232,27 +1235,29 @@ async function load_root_error_page({ status, error, url, route }) {
1232
1235
  /** @type {import('types').ServerDataNode | null} */
1233
1236
  let server_data_node = null;
1234
1237
 
1235
- const default_layout_has_server_load = app.server_loads[0] === 0;
1238
+ if (__SVELTEKIT_HAS_SERVER_LOAD__) {
1239
+ const default_layout_has_server_load = app.server_loads[0] === 0;
1236
1240
 
1237
- if (default_layout_has_server_load) {
1238
- // TODO post-https://github.com/sveltejs/kit/discussions/6124 we can use
1239
- // existing root layout data
1240
- try {
1241
- const server_data = await load_data(url, [true]);
1241
+ if (default_layout_has_server_load) {
1242
+ // TODO post-https://github.com/sveltejs/kit/discussions/6124 we can use
1243
+ // existing root layout data
1244
+ try {
1245
+ const server_data = await load_data(url, [true]);
1242
1246
 
1243
- if (
1244
- server_data.type !== 'data' ||
1245
- (server_data.nodes[0] && server_data.nodes[0].type !== 'data')
1246
- ) {
1247
- throw 0;
1248
- }
1247
+ if (
1248
+ server_data.type !== 'data' ||
1249
+ (server_data.nodes[0] && server_data.nodes[0].type !== 'data')
1250
+ ) {
1251
+ throw 0;
1252
+ }
1249
1253
 
1250
- server_data_node = server_data.nodes[0] ?? null;
1251
- } catch {
1252
- // at this point we have no choice but to fall back to the server, if it wouldn't
1253
- // bring us right back here, turning this into an endless loop
1254
- if (url.origin !== origin || url.pathname !== location.pathname || hydrated) {
1255
- await native_navigation(url);
1254
+ server_data_node = server_data.nodes[0] ?? null;
1255
+ } catch {
1256
+ // at this point we have no choice but to fall back to the server, if it wouldn't
1257
+ // bring us right back here, turning this into an endless loop
1258
+ if (url.origin !== origin || url.pathname !== location.pathname || hydrated) {
1259
+ await native_navigation(url);
1260
+ }
1256
1261
  }
1257
1262
  }
1258
1263
  }
@@ -17,10 +17,9 @@ import {
17
17
  deep_set,
18
18
  set_nested_value,
19
19
  throw_on_old_property_access,
20
- split_path,
21
20
  build_path_string,
22
21
  normalize_issue
23
- } from '../../form-utils.svelte.js';
22
+ } from '../../form-utils.js';
24
23
 
25
24
  /**
26
25
  * Merge client issues into server issues. Server issues are persisted unless
@@ -60,24 +59,9 @@ export function form(id) {
60
59
  const action = '?/remote=' + encodeURIComponent(action_id);
61
60
 
62
61
  /**
63
- * By making this $state.raw() and creating a new object each time we update it,
64
- * all consumers along the update chain are properly invalidated.
65
62
  * @type {Record<string, string | string[] | File | File[]>}
66
63
  */
67
- let input = $state.raw({});
68
-
69
- // TODO 3.0: Remove versions state and related logic; it's a workaround for $derived not updating when created inside $effects
70
- /**
71
- * This allows us to update individual fields granularly
72
- * @type {Record<string, number>}
73
- */
74
- const versions = $state({});
75
-
76
- /**
77
- * This ensures that `{field.value()}` is updated even if the version hasn't been initialized
78
- * @type {Set<string>}
79
- */
80
- const version_reads = new Set();
64
+ let input = $state({});
81
65
 
82
66
  /** @type {InternalRemoteFormIssue[]} */
83
67
  let raw_issues = $state.raw([]);
@@ -101,16 +85,6 @@ export function form(id) {
101
85
 
102
86
  let submitted = false;
103
87
 
104
- function update_all_versions() {
105
- for (const path of version_reads) {
106
- versions[path] ??= 0;
107
- }
108
-
109
- for (const key of Object.keys(versions)) {
110
- versions[key] += 1;
111
- }
112
- }
113
-
114
88
  /**
115
89
  * @param {FormData} form_data
116
90
  * @returns {Record<string, any>}
@@ -235,8 +209,6 @@ export function form(id) {
235
209
  if (issues.$) {
236
210
  release_overrides(updates);
237
211
  } else {
238
- update_all_versions();
239
-
240
212
  if (form_result.refreshes) {
241
213
  refresh_queries(form_result.refreshes, updates);
242
214
  } else {
@@ -386,7 +358,7 @@ export function form(id) {
386
358
  }
387
359
  }
388
360
 
389
- input = set_nested_value(input, name, value);
361
+ set_nested_value(input, name, value);
390
362
  } else if (is_file) {
391
363
  if (DEV && element.multiple) {
392
364
  throw new Error(
@@ -397,7 +369,7 @@ export function form(id) {
397
369
  const file = /** @type {HTMLInputElement & { files: FileList }} */ (element).files[0];
398
370
 
399
371
  if (file) {
400
- input = set_nested_value(input, name, file);
372
+ set_nested_value(input, name, file);
401
373
  } else {
402
374
  // Remove the property by setting to undefined and clean up
403
375
  const path_parts = name.split(/\.|\[|\]/).filter(Boolean);
@@ -409,7 +381,7 @@ export function form(id) {
409
381
  delete current[path_parts[path_parts.length - 1]];
410
382
  }
411
383
  } else {
412
- input = set_nested_value(
384
+ set_nested_value(
413
385
  input,
414
386
  name,
415
387
  element.type === 'checkbox' && !element.checked ? null : element.value
@@ -418,17 +390,7 @@ export function form(id) {
418
390
 
419
391
  name = name.replace(/^[nb]:/, '');
420
392
 
421
- versions[name] ??= 0;
422
- versions[name] += 1;
423
-
424
- const path = split_path(name);
425
-
426
- while (path.pop() !== undefined) {
427
- const name = build_path_string(path);
428
-
429
- versions[name] ??= 0;
430
- versions[name] += 1;
431
- }
393
+ touched[name] = true;
432
394
  });
433
395
 
434
396
  form.addEventListener('reset', async () => {
@@ -437,7 +399,6 @@ export function form(id) {
437
399
  await tick();
438
400
 
439
401
  input = convert_formdata(new FormData(form));
440
- update_all_versions();
441
402
  });
442
403
 
443
404
  return () => {
@@ -530,28 +491,14 @@ export function form(id) {
530
491
  create_field_proxy(
531
492
  {},
532
493
  () => input,
533
- (path) => {
534
- version_reads.add(path);
535
- versions[path];
536
- },
537
494
  (path, value) => {
538
495
  if (path.length === 0) {
539
496
  input = value;
540
- update_all_versions();
541
497
  } else {
542
- input = deep_set(input, path.map(String), value);
498
+ deep_set(input, path.map(String), value);
543
499
 
544
500
  const key = build_path_string(path);
545
- versions[key] ??= 0;
546
- versions[key] += 1;
547
501
  touched[key] = true;
548
-
549
- const parent_path = path.slice();
550
- while (parent_path.pop() !== undefined) {
551
- const parent_key = build_path_string(parent_path);
552
- versions[parent_key] ??= 0;
553
- versions[parent_key] += 1;
554
- }
555
502
  }
556
503
  },
557
504
  () => issues
@@ -3,12 +3,9 @@
3
3
  /** @import { StandardSchemaV1 } from '@standard-schema/spec' */
4
4
 
5
5
  import { DEV } from 'esm-env';
6
- import * as svelte from 'svelte';
7
- // Svelte 4 and under don't have `untrack` - you'll not be able to use remote functions with Svelte 4 but this will still be loaded
8
- const untrack = svelte.untrack ?? ((value) => value());
9
6
 
10
7
  /**
11
- * Sets a value in a nested object using a path string, not mutating the original object but returning a new object
8
+ * Sets a value in a nested object using a path string, mutating the original object
12
9
  * @param {Record<string, any>} object
13
10
  * @param {string} path_string
14
11
  * @param {any} value
@@ -22,7 +19,7 @@ export function set_nested_value(object, path_string, value) {
22
19
  value = value === 'on';
23
20
  }
24
21
 
25
- return deep_set(object, split_path(path_string), value);
22
+ deep_set(object, split_path(path_string), value);
26
23
  }
27
24
 
28
25
  /**
@@ -31,7 +28,7 @@ export function set_nested_value(object, path_string, value) {
31
28
  */
32
29
  export function convert_formdata(data) {
33
30
  /** @type {Record<string, any>} */
34
- let result = Object.create(null); // guard against prototype pollution
31
+ const result = {};
35
32
 
36
33
  for (let key of data.keys()) {
37
34
  if (key.startsWith('sveltekit:')) {
@@ -61,7 +58,7 @@ export function convert_formdata(data) {
61
58
  values = values.map((v) => v === 'on');
62
59
  }
63
60
 
64
- result = set_nested_value(result, key, is_array ? values : values[0]);
61
+ set_nested_value(result, key, is_array ? values : values[0]);
65
62
  }
66
63
 
67
64
  return result;
@@ -81,18 +78,32 @@ export function split_path(path) {
81
78
  }
82
79
 
83
80
  /**
84
- * Sets a value in a nested object using an array of keys.
85
- * Does not mutate the original object; returns a new object.
81
+ * Check if a property key is dangerous and could lead to prototype pollution
82
+ * @param {string} key
83
+ */
84
+ function check_prototype_pollution(key) {
85
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
86
+ throw new Error(
87
+ `Invalid key "${key}"` +
88
+ (DEV ? ': This key is not allowed to prevent prototype pollution.' : '')
89
+ );
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Sets a value in a nested object using an array of keys, mutating the original object.
86
95
  * @param {Record<string, any>} object
87
96
  * @param {string[]} keys
88
97
  * @param {any} value
89
98
  */
90
99
  export function deep_set(object, keys, value) {
91
- const result = Object.assign(Object.create(null), object); // guard against prototype pollution
92
- let current = result;
100
+ let current = object;
93
101
 
94
102
  for (let i = 0; i < keys.length - 1; i += 1) {
95
103
  const key = keys[i];
104
+
105
+ check_prototype_pollution(key);
106
+
96
107
  const is_array = /^\d+$/.test(keys[i + 1]);
97
108
  const exists = key in current;
98
109
  const inner = current[key];
@@ -101,18 +112,16 @@ export function deep_set(object, keys, value) {
101
112
  throw new Error(`Invalid array key ${keys[i + 1]}`);
102
113
  }
103
114
 
104
- current[key] = is_array
105
- ? exists
106
- ? [...inner]
107
- : []
108
- : // guard against prototype pollution
109
- Object.assign(Object.create(null), inner);
115
+ if (!exists) {
116
+ current[key] = is_array ? [] : {};
117
+ }
110
118
 
111
119
  current = current[key];
112
120
  }
113
121
 
114
- current[keys[keys.length - 1]] = value;
115
- return result;
122
+ const final_key = keys[keys.length - 1];
123
+ check_prototype_pollution(final_key);
124
+ current[final_key] = value;
116
125
  }
117
126
 
118
127
  /**
@@ -196,18 +205,14 @@ export function deep_get(object, path) {
196
205
  * Creates a proxy-based field accessor for form data
197
206
  * @param {any} target - Function or empty POJO
198
207
  * @param {() => Record<string, any>} get_input - Function to get current input data
199
- * @param {(path: string) => void} depend - Function to make an effect depend on a specific field
200
208
  * @param {(path: (string | number)[], value: any) => void} set_input - Function to set input data
201
209
  * @param {() => Record<string, InternalRemoteFormIssue[]>} get_issues - Function to get current issues
202
210
  * @param {(string | number)[]} path - Current access path
203
211
  * @returns {any} Proxy object with name(), value(), and issues() methods
204
212
  */
205
- export function create_field_proxy(target, get_input, depend, set_input, get_issues, path = []) {
206
- const path_string = build_path_string(path);
207
-
213
+ export function create_field_proxy(target, get_input, set_input, get_issues, path = []) {
208
214
  const get_value = () => {
209
- depend(path_string);
210
- return untrack(() => deep_get(get_input(), path));
215
+ return deep_get(get_input(), path);
211
216
  };
212
217
 
213
218
  return new Proxy(target, {
@@ -216,7 +221,7 @@ export function create_field_proxy(target, get_input, depend, set_input, get_iss
216
221
 
217
222
  // Handle array access like jobs[0]
218
223
  if (/^\d+$/.test(prop)) {
219
- return create_field_proxy({}, get_input, depend, set_input, get_issues, [
224
+ return create_field_proxy({}, get_input, set_input, get_issues, [
220
225
  ...path,
221
226
  parseInt(prop, 10)
222
227
  ]);
@@ -229,17 +234,11 @@ export function create_field_proxy(target, get_input, depend, set_input, get_iss
229
234
  set_input(path, newValue);
230
235
  return newValue;
231
236
  };
232
- return create_field_proxy(set_func, get_input, depend, set_input, get_issues, [
233
- ...path,
234
- prop
235
- ]);
237
+ return create_field_proxy(set_func, get_input, set_input, get_issues, [...path, prop]);
236
238
  }
237
239
 
238
240
  if (prop === 'value') {
239
- return create_field_proxy(get_value, get_input, depend, set_input, get_issues, [
240
- ...path,
241
- prop
242
- ]);
241
+ return create_field_proxy(get_value, get_input, set_input, get_issues, [...path, prop]);
243
242
  }
244
243
 
245
244
  if (prop === 'issues' || prop === 'allIssues') {
@@ -259,10 +258,7 @@ export function create_field_proxy(target, get_input, depend, set_input, get_iss
259
258
  }));
260
259
  };
261
260
 
262
- return create_field_proxy(issues_func, get_input, depend, set_input, get_issues, [
263
- ...path,
264
- prop
265
- ]);
261
+ return create_field_proxy(issues_func, get_input, set_input, get_issues, [...path, prop]);
266
262
  }
267
263
 
268
264
  if (prop === 'as') {
@@ -411,14 +407,11 @@ export function create_field_proxy(target, get_input, depend, set_input, get_iss
411
407
  });
412
408
  };
413
409
 
414
- return create_field_proxy(as_func, get_input, depend, set_input, get_issues, [
415
- ...path,
416
- 'as'
417
- ]);
410
+ return create_field_proxy(as_func, get_input, set_input, get_issues, [...path, 'as']);
418
411
  }
419
412
 
420
413
  // Handle property access (nested fields)
421
- return create_field_proxy({}, get_input, depend, set_input, get_issues, [...path, prop]);
414
+ return create_field_proxy({}, get_input, set_input, get_issues, [...path, prop]);
422
415
  }
423
416
  });
424
417
  }
@@ -227,7 +227,6 @@ export async function render_response({
227
227
  paths.reset();
228
228
  }
229
229
 
230
- // eslint-disable-next-line
231
230
  const { head, html, css } = options.async ? await rendered : rendered;
232
231
 
233
232
  return { head, html, css };
@@ -654,7 +653,7 @@ export async function render_response({
654
653
  async start(controller) {
655
654
  controller.enqueue(text_encoder.encode(transformed + '\n'));
656
655
  for await (const chunk of chunks) {
657
- controller.enqueue(text_encoder.encode(chunk));
656
+ if (chunk.length) controller.enqueue(text_encoder.encode(chunk));
658
657
  }
659
658
  controller.close();
660
659
  },
@@ -13,6 +13,16 @@ declare global {
13
13
  const __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: boolean;
14
14
  /** True if `config.kit.router.resolution === 'client'` */
15
15
  const __SVELTEKIT_CLIENT_ROUTING__: boolean;
16
+ /**
17
+ * True if any node in the manifest has a server load function.
18
+ * Used for treeshaking server load code from client bundles when no server loads exist.
19
+ */
20
+ const __SVELTEKIT_HAS_SERVER_LOAD__: boolean;
21
+ /**
22
+ * True if any node in the manifest has a universal load function.
23
+ * Used for treeshaking universal load code from client bundles when no universal loads exist.
24
+ */
25
+ const __SVELTEKIT_HAS_UNIVERSAL_LOAD__: boolean;
16
26
  /** The `__sveltekit_abc123` object in the init `<script>` */
17
27
  const __SVELTEKIT_PAYLOAD__: {
18
28
  /** The basepath, usually relative to the current page */
@@ -370,6 +370,7 @@ export interface ServerMetadata {
370
370
  nodes: Array<{
371
371
  /** Also `true` when using `trailingSlash`, because we need to do a server request in that case to get its value. */
372
372
  has_server_load: boolean;
373
+ has_universal_load: boolean;
373
374
  }>;
374
375
  routes: Map<string, ServerMetadataRoute>;
375
376
  /** For each hashed remote file, a map of export name -> { type, dynamic }, where `dynamic` is `false` for non-dynamic prerender functions */
@@ -395,6 +396,7 @@ export interface SSRComponent {
395
396
  export type SSRComponentLoader = () => Promise<SSRComponent>;
396
397
 
397
398
  export interface UniversalNode {
399
+ /** Is `null` in case static analysis succeeds but the node is ssr=false */
398
400
  load?: Load;
399
401
  prerender?: PrerenderOption;
400
402
  ssr?: boolean;
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.47.2';
4
+ export const VERSION = '2.47.3';
package/types/index.d.ts CHANGED
@@ -1890,10 +1890,28 @@ declare module '@sveltejs/kit' {
1890
1890
  allIssues(): RemoteFormIssue[] | undefined;
1891
1891
  };
1892
1892
 
1893
+ type UnknownField<Value> = RemoteFormFieldMethods<Value> & {
1894
+ /** Validation issues belonging to this or any of the fields that belong to it, if any */
1895
+ allIssues(): RemoteFormIssue[] | undefined;
1896
+ /**
1897
+ * Returns an object that can be spread onto an input element with the correct type attribute,
1898
+ * aria-invalid attribute if the field is invalid, and appropriate value/checked property getters/setters.
1899
+ * @example
1900
+ * ```svelte
1901
+ * <input {...myForm.fields.myString.as('text')} />
1902
+ * <input {...myForm.fields.myNumber.as('number')} />
1903
+ * <input {...myForm.fields.myBoolean.as('checkbox')} />
1904
+ * ```
1905
+ */
1906
+ as<T extends RemoteFormFieldType<Value>>(...args: AsArgs<T, Value>): InputElementProps<T>;
1907
+ } & {
1908
+ [key: string | number]: UnknownField<any>;
1909
+ };
1910
+
1893
1911
  /**
1894
1912
  * Recursive type to build form fields structure with proxy access
1895
1913
  */
1896
- type RemoteFormFields<T> =
1914
+ export type RemoteFormFields<T> =
1897
1915
  WillRecurseIndefinitely<T> extends true
1898
1916
  ? RecursiveFormFields
1899
1917
  : NonNullable<T> extends string | number | boolean | File
@@ -1901,11 +1919,17 @@ declare module '@sveltejs/kit' {
1901
1919
  : T extends string[] | File[]
1902
1920
  ? RemoteFormField<T> & { [K in number]: RemoteFormField<T[number]> }
1903
1921
  : T extends Array<infer U>
1904
- ? RemoteFormFieldContainer<T> & { [K in number]: RemoteFormFields<U> }
1905
- : RemoteFormFieldContainer<T> & { [K in keyof T]-?: RemoteFormFields<T[K]> };
1922
+ ? RemoteFormFieldContainer<T> & {
1923
+ [K in number]: RemoteFormFields<U>;
1924
+ }
1925
+ : RemoteFormFieldContainer<T> & {
1926
+ [K in keyof T]-?: RemoteFormFields<T[K]>;
1927
+ };
1906
1928
 
1907
1929
  // By breaking this out into its own type, we avoid the TS recursion depth limit
1908
- type RecursiveFormFields = RemoteFormField<any> & { [key: string | number]: RecursiveFormFields };
1930
+ type RecursiveFormFields = RemoteFormFieldContainer<any> & {
1931
+ [key: string | number]: UnknownField<any>;
1932
+ };
1909
1933
 
1910
1934
  type MaybeArray<T> = T | T[];
1911
1935
 
@@ -2491,6 +2515,7 @@ declare module '@sveltejs/kit' {
2491
2515
  type SSRComponentLoader = () => Promise<SSRComponent>;
2492
2516
 
2493
2517
  interface UniversalNode {
2518
+ /** Is `null` in case static analysis succeeds but the node is ssr=false */
2494
2519
  load?: Load;
2495
2520
  prerender?: PrerenderOption;
2496
2521
  ssr?: boolean;
@@ -66,6 +66,7 @@
66
66
  "AsArgs",
67
67
  "RemoteFormField",
68
68
  "RemoteFormFieldContainer",
69
+ "UnknownField",
69
70
  "RemoteFormFields",
70
71
  "RecursiveFormFields",
71
72
  "MaybeArray",
@@ -211,6 +212,6 @@
211
212
  null,
212
213
  null
213
214
  ],
214
- "mappings": "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",
215
+ "mappings": "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",
215
216
  "ignoreList": []
216
217
  }