@sveltejs/kit 2.42.1 → 2.43.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.
Files changed (37) hide show
  1. package/package.json +8 -2
  2. package/src/core/postbuild/analyse.js +4 -0
  3. package/src/core/postbuild/prerender.js +18 -6
  4. package/src/core/sync/write_server.js +2 -1
  5. package/src/exports/public.d.ts +39 -38
  6. package/src/exports/vite/dev/index.js +1 -1
  7. package/src/exports/vite/index.js +14 -52
  8. package/src/exports/vite/module_ids.js +0 -1
  9. package/src/runtime/app/paths/client.js +57 -0
  10. package/src/runtime/app/paths/index.js +1 -16
  11. package/src/runtime/app/paths/internal/client.js +3 -0
  12. package/src/runtime/app/paths/internal/server.js +24 -0
  13. package/src/runtime/app/paths/public.d.ts +29 -0
  14. package/src/runtime/app/paths/server.js +31 -0
  15. package/src/runtime/app/paths/types.d.ts +2 -65
  16. package/src/runtime/app/server/index.js +1 -1
  17. package/src/runtime/app/server/remote/form.js +4 -6
  18. package/src/runtime/app/server/remote/prerender.js +21 -16
  19. package/src/runtime/app/server/remote/query.js +9 -5
  20. package/src/runtime/app/server/remote/shared.js +22 -6
  21. package/src/runtime/client/client.js +3 -3
  22. package/src/runtime/client/remote-functions/command.svelte.js +1 -1
  23. package/src/runtime/client/remote-functions/form.svelte.js +1 -1
  24. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  25. package/src/runtime/client/remote-functions/query.svelte.js +1 -1
  26. package/src/runtime/client/utils.js +1 -1
  27. package/src/runtime/server/fetch.js +1 -1
  28. package/src/runtime/server/page/render.js +55 -38
  29. package/src/runtime/server/page/server_routing.js +1 -1
  30. package/src/runtime/server/remote.js +1 -1
  31. package/src/runtime/server/respond.js +1 -1
  32. package/src/runtime/utils.js +2 -1
  33. package/src/types/global-private.d.ts +4 -0
  34. package/src/types/internal.d.ts +2 -1
  35. package/src/version.js +1 -1
  36. package/types/index.d.ts +65 -65
  37. package/types/index.d.ts.map +7 -3
@@ -4,10 +4,11 @@
4
4
  import { error, json } from '@sveltejs/kit';
5
5
  import { DEV } from 'esm-env';
6
6
  import { get_request_store } from '@sveltejs/kit/internal/server';
7
- import { create_remote_cache_key, stringify, stringify_remote_arg } from '../../../shared.js';
8
- import { app_dir, base } from '__sveltekit/paths';
7
+ import { stringify, stringify_remote_arg } from '../../../shared.js';
8
+ import { app_dir, base } from '$app/paths/internal/server';
9
9
  import {
10
10
  create_validator,
11
+ get_cache,
11
12
  get_response,
12
13
  parse_remote_response,
13
14
  run_remote_function
@@ -96,25 +97,29 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
96
97
 
97
98
  if (!state.prerendering && !DEV && !event.isRemoteRequest) {
98
99
  try {
99
- return await get_response(id, arg, state, async () => {
100
+ return await get_response(__, arg, state, async () => {
101
+ const key = stringify_remote_arg(arg, state.transport);
102
+ const cache = get_cache(__, state);
103
+
100
104
  // TODO adapters can provide prerendered data more efficiently than
101
105
  // fetching from the public internet
102
- const response = await fetch(new URL(url, event.url.origin).href);
103
-
104
- if (!response.ok) {
105
- throw new Error('Prerendered response not found');
106
- }
106
+ const promise = (cache[key] ??= fetch(new URL(url, event.url.origin).href).then(
107
+ async (response) => {
108
+ if (!response.ok) {
109
+ throw new Error('Prerendered response not found');
110
+ }
107
111
 
108
- const prerendered = await response.json();
112
+ const prerendered = await response.json();
109
113
 
110
- if (prerendered.type === 'error') {
111
- error(prerendered.status, prerendered.error);
112
- }
114
+ if (prerendered.type === 'error') {
115
+ error(prerendered.status, prerendered.error);
116
+ }
113
117
 
114
- // TODO can we redirect here?
118
+ return prerendered.result;
119
+ }
120
+ ));
115
121
 
116
- (state.remote_data ??= {})[create_remote_cache_key(id, payload)] = prerendered.result;
117
- return parse_remote_response(prerendered.result, state.transport);
122
+ return parse_remote_response(await promise, state.transport);
118
123
  });
119
124
  } catch {
120
125
  // not available prerendered, fallback to normal function
@@ -125,7 +130,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
125
130
  return /** @type {Promise<any>} */ (state.prerendering.remote_responses.get(url));
126
131
  }
127
132
 
128
- const promise = get_response(id, arg, state, () =>
133
+ const promise = get_response(__, arg, state, () =>
129
134
  run_remote_function(event, state, false, arg, validate, fn)
130
135
  );
131
136
 
@@ -4,7 +4,7 @@
4
4
  import { get_request_store } from '@sveltejs/kit/internal/server';
5
5
  import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js';
6
6
  import { prerendering } from '__sveltekit/environment';
7
- import { create_validator, get_response, run_remote_function } from './shared.js';
7
+ import { create_validator, get_cache, get_response, run_remote_function } from './shared.js';
8
8
 
9
9
  /**
10
10
  * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call.
@@ -73,7 +73,7 @@ export function query(validate_or_fn, maybe_fn) {
73
73
  const { event, state } = get_request_store();
74
74
 
75
75
  /** @type {Promise<any> & Partial<RemoteQuery<any>>} */
76
- const promise = get_response(__.id, arg, state, () =>
76
+ const promise = get_response(__, arg, state, () =>
77
77
  run_remote_function(event, state, false, arg, validate, fn)
78
78
  );
79
79
 
@@ -90,8 +90,12 @@ export function query(validate_or_fn, maybe_fn) {
90
90
  );
91
91
  }
92
92
 
93
- const cache_key = create_remote_cache_key(__.id, stringify_remote_arg(arg, state.transport));
94
- refreshes[cache_key] = (state.remote_data ??= {})[cache_key] = Promise.resolve(value);
93
+ const cache = get_cache(__, state);
94
+ const key = stringify_remote_arg(arg, state.transport);
95
+
96
+ if (__.id) {
97
+ refreshes[__.id + '/' + key] = cache[key] = Promise.resolve(value);
98
+ }
95
99
  };
96
100
 
97
101
  promise.refresh = () => {
@@ -198,7 +202,7 @@ function batch(validate_or_fn, maybe_fn) {
198
202
  const { event, state } = get_request_store();
199
203
 
200
204
  /** @type {Promise<any> & Partial<RemoteQuery<any>>} */
201
- const promise = get_response(__.id, arg, state, () => {
205
+ const promise = get_response(__, arg, state, () => {
202
206
  // Collect all the calls to the same query in the same macrotask,
203
207
  // then execute them as one backend request.
204
208
  return new Promise((resolve, reject) => {
@@ -1,9 +1,9 @@
1
1
  /** @import { RequestEvent } from '@sveltejs/kit' */
2
- /** @import { ServerHooks, MaybePromise, RequestState } from 'types' */
2
+ /** @import { ServerHooks, MaybePromise, RequestState, RemoteInfo } 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';
6
- import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js';
6
+ import { stringify_remote_arg } from '../../../shared.js';
7
7
 
8
8
  /**
9
9
  * @param {any} validate_or_fn
@@ -62,19 +62,20 @@ export function create_validator(validate_or_fn, maybe_fn) {
62
62
  * Also saves an uneval'ed version of the result for later HTML inlining for hydration.
63
63
  *
64
64
  * @template {MaybePromise<any>} T
65
- * @param {string} id
65
+ * @param {RemoteInfo} info
66
66
  * @param {any} arg
67
67
  * @param {RequestState} state
68
68
  * @param {() => Promise<T>} get_result
69
69
  * @returns {Promise<T>}
70
70
  */
71
- export async function get_response(id, arg, state, get_result) {
71
+ export async function get_response(info, arg, state, get_result) {
72
72
  // wait a beat, in case `myQuery().set(...)` is immediately called
73
73
  // eslint-disable-next-line @typescript-eslint/await-thenable
74
74
  await 0;
75
75
 
76
- const cache_key = create_remote_cache_key(id, stringify_remote_arg(arg, state.transport));
77
- return ((state.remote_data ??= {})[cache_key] ??= get_result());
76
+ const cache = get_cache(info, state);
77
+
78
+ return (cache[stringify_remote_arg(arg, state.transport)] ??= get_result());
78
79
  }
79
80
 
80
81
  /**
@@ -141,3 +142,18 @@ export async function run_remote_function(event, state, allow_cookies, arg, vali
141
142
  const validated = await with_request_store({ event: cleansed, state }, () => validate(arg));
142
143
  return with_request_store({ event: cleansed, state }, () => fn(validated));
143
144
  }
145
+
146
+ /**
147
+ * @param {RemoteInfo} info
148
+ * @param {RequestState} state
149
+ */
150
+ export function get_cache(info, state = get_request_store().state) {
151
+ let cache = state.remote_data?.get(info);
152
+
153
+ if (cache === undefined) {
154
+ cache = {};
155
+ (state.remote_data ??= new Map()).set(info, cache);
156
+ }
157
+
158
+ return cache;
159
+ }
@@ -26,7 +26,7 @@ import {
26
26
  create_updated_store,
27
27
  load_css
28
28
  } from './utils.js';
29
- import { base } from '__sveltekit/paths';
29
+ import { base } from '$app/paths';
30
30
  import * as devalue from 'devalue';
31
31
  import {
32
32
  HISTORY_INDEX,
@@ -291,8 +291,8 @@ export async function start(_app, _target, hydrate) {
291
291
  );
292
292
  }
293
293
 
294
- if (__SVELTEKIT_PAYLOAD__.data) {
295
- remote_responses = __SVELTEKIT_PAYLOAD__?.data;
294
+ if (__SVELTEKIT_PAYLOAD__?.data) {
295
+ remote_responses = __SVELTEKIT_PAYLOAD__.data;
296
296
  }
297
297
 
298
298
  // detect basic auth credentials in the current URL
@@ -1,7 +1,7 @@
1
1
  /** @import { RemoteCommand, RemoteQueryOverride } from '@sveltejs/kit' */
2
2
  /** @import { RemoteFunctionResponse } from 'types' */
3
3
  /** @import { Query } from './query.svelte.js' */
4
- import { app_dir, base } from '__sveltekit/paths';
4
+ import { app_dir, base } from '$app/paths/internal/client';
5
5
  import * as devalue from 'devalue';
6
6
  import { HttpError } from '@sveltejs/kit/internal';
7
7
  import { app } from '../client.js';
@@ -2,7 +2,7 @@
2
2
  /** @import { RemoteFormInput, RemoteForm, RemoteQueryOverride } from '@sveltejs/kit' */
3
3
  /** @import { RemoteFunctionResponse } from 'types' */
4
4
  /** @import { Query } from './query.svelte.js' */
5
- import { app_dir, base } from '__sveltekit/paths';
5
+ import { app_dir, base } from '$app/paths/internal/client';
6
6
  import * as devalue from 'devalue';
7
7
  import { DEV } from 'esm-env';
8
8
  import { HttpError } from '@sveltejs/kit/internal';
@@ -1,5 +1,5 @@
1
1
  /** @import { RemoteFunctionResponse } from 'types' */
2
- import { app_dir, base } from '__sveltekit/paths';
2
+ import { app_dir, base } from '$app/paths/internal/client';
3
3
  import { version } from '__sveltekit/environment';
4
4
  import * as devalue from 'devalue';
5
5
  import { DEV } from 'esm-env';
@@ -1,6 +1,6 @@
1
1
  /** @import { RemoteQueryFunction } from '@sveltejs/kit' */
2
2
  /** @import { RemoteFunctionResponse } from 'types' */
3
- import { app_dir, base } from '__sveltekit/paths';
3
+ import { app_dir, base } from '$app/paths/internal/client';
4
4
  import { app, goto, remote_responses, started } from '../client.js';
5
5
  import { tick } from 'svelte';
6
6
  import { create_remote_function, remote_request } from './shared.svelte.js';
@@ -1,6 +1,6 @@
1
1
  import { BROWSER, DEV } from 'esm-env';
2
2
  import { writable } from 'svelte/store';
3
- import { assets } from '__sveltekit/paths';
3
+ import { assets } from '$app/paths';
4
4
  import { version } from '__sveltekit/environment';
5
5
  import { PRELOAD_PRIORITIES } from './constants.js';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import * as set_cookie_parser from 'set-cookie-parser';
2
2
  import { respond } from './respond.js';
3
- import * as paths from '__sveltekit/paths';
3
+ import * as paths from '$app/paths/internal/server';
4
4
  import { read_implementation } from '__sveltekit/server';
5
5
  import { has_prerendered_path } from './utils.js';
6
6
 
@@ -2,7 +2,7 @@ import * as devalue from 'devalue';
2
2
  import { readable, writable } from 'svelte/store';
3
3
  import { DEV } from 'esm-env';
4
4
  import { text } from '@sveltejs/kit';
5
- import * as paths from '__sveltekit/paths';
5
+ import * as paths from '$app/paths/internal/server';
6
6
  import { hash } from '../../../utils/hash.js';
7
7
  import { serialize_data } from './serialize_data.js';
8
8
  import { s } from '../../../utils/misc.js';
@@ -168,10 +168,6 @@ export async function render_response({
168
168
  state: {}
169
169
  };
170
170
 
171
- // use relative paths during rendering, so that the resulting HTML is as
172
- // portable as possible, but reset afterwards
173
- if (paths.relative) paths.override({ base, assets });
174
-
175
171
  const render_opts = {
176
172
  context: new Map([
177
173
  [
@@ -183,40 +179,55 @@ export async function render_response({
183
179
  ])
184
180
  };
185
181
 
186
- if (DEV) {
187
- const fetch = globalThis.fetch;
188
- let warned = false;
189
- globalThis.fetch = (info, init) => {
190
- if (typeof info === 'string' && !SCHEME.test(info)) {
191
- throw new Error(
192
- `Cannot call \`fetch\` eagerly during server-side rendering with relative URL (${info}) — put your \`fetch\` calls inside \`onMount\` or a \`load\` function instead`
193
- );
194
- } else if (!warned) {
195
- console.warn(
196
- 'Avoid calling `fetch` eagerly during server-side rendering — put your `fetch` calls inside `onMount` or a `load` function instead'
197
- );
198
- warned = true;
182
+ const fetch = globalThis.fetch;
183
+
184
+ try {
185
+ if (DEV) {
186
+ let warned = false;
187
+ globalThis.fetch = (info, init) => {
188
+ if (typeof info === 'string' && !SCHEME.test(info)) {
189
+ throw new Error(
190
+ `Cannot call \`fetch\` eagerly during server-side rendering with relative URL (${info}) — put your \`fetch\` calls inside \`onMount\` or a \`load\` function instead`
191
+ );
192
+ } else if (!warned) {
193
+ console.warn(
194
+ 'Avoid calling `fetch` eagerly during server-side rendering — put your `fetch` calls inside `onMount` or a `load` function instead'
195
+ );
196
+ warned = true;
197
+ }
198
+
199
+ return fetch(info, init);
200
+ };
201
+ }
202
+
203
+ rendered = await with_request_store({ event, state: event_state }, async () => {
204
+ // use relative paths during rendering, so that the resulting HTML is as
205
+ // portable as possible, but reset afterwards
206
+ if (paths.relative) paths.override({ base, assets });
207
+
208
+ const rendered = options.root.render(props, render_opts);
209
+
210
+ // TODO 3.0 remove options.async
211
+ if (options.async) {
212
+ // we reset this synchronously, rather than after async rendering is complete,
213
+ // to avoid cross-talk between requests. This is a breaking change for
214
+ // anyone who opts into async SSR, since `base` and `assets` will no
215
+ // longer be relative to the current pathname.
216
+ // TODO 3.0 remove `base` and `assets` in favour of `resolve(...)` and `asset(...)`
217
+ paths.reset();
199
218
  }
200
219
 
201
- return fetch(info, init);
202
- };
220
+ // eslint-disable-next-line
221
+ const { head, html, css } = options.async ? await rendered : rendered;
203
222
 
204
- try {
205
- rendered = with_request_store({ event, state: event_state }, () =>
206
- options.root.render(props, render_opts)
207
- );
208
- } finally {
223
+ return { head, html, css };
224
+ });
225
+ } finally {
226
+ if (DEV) {
209
227
  globalThis.fetch = fetch;
210
- paths.reset();
211
- }
212
- } else {
213
- try {
214
- rendered = with_request_store({ event, state: event_state }, () =>
215
- options.root.render(props, render_opts)
216
- );
217
- } finally {
218
- paths.reset();
219
228
  }
229
+
230
+ paths.reset(); // just in case `options.root.render(...)` failed
220
231
  }
221
232
 
222
233
  for (const { node } of branch) {
@@ -459,16 +470,22 @@ export async function render_response({
459
470
  args.push(`{\n${indent}\t${hydrate.join(`,\n${indent}\t`)}\n${indent}}`);
460
471
  }
461
472
 
462
- const { remote_data } = event_state;
473
+ const { remote_data: remote_cache } = event_state;
463
474
 
464
475
  let serialized_remote_data = '';
465
476
 
466
- if (remote_data) {
477
+ if (remote_cache) {
467
478
  /** @type {Record<string, any>} */
468
479
  const remote = {};
469
480
 
470
- for (const key in remote_data) {
471
- remote[key] = await remote_data[key];
481
+ for (const [info, cache] of remote_cache) {
482
+ // remote functions without an `id` aren't exported, and thus
483
+ // cannot be called from the client
484
+ if (!info.id) continue;
485
+
486
+ for (const key in cache) {
487
+ remote[key ? info.id + '/' + key : info.id] = await cache[key];
488
+ }
472
489
  }
473
490
 
474
491
  // TODO this is repeated in a few places — dedupe it
@@ -1,4 +1,4 @@
1
- import { base, assets, relative } from '__sveltekit/paths';
1
+ import { base, assets, relative } from '$app/paths/internal/server';
2
2
  import { text } from '@sveltejs/kit';
3
3
  import { s } from '../../../utils/misc.js';
4
4
  import { exec } from '../../../utils/routing.js';
@@ -4,7 +4,7 @@
4
4
  import { json, error } from '@sveltejs/kit';
5
5
  import { HttpError, Redirect, SvelteKitError } from '@sveltejs/kit/internal';
6
6
  import { with_request_store, merge_tracing } from '@sveltejs/kit/internal/server';
7
- import { app_dir, base } from '__sveltekit/paths';
7
+ import { app_dir, base } from '$app/paths/internal/server';
8
8
  import { is_form_content_type } from '../../utils/http.js';
9
9
  import { parse_remote_arg, stringify } from '../shared.js';
10
10
  import { handle_error_and_jsonify } from './utils.js';
@@ -3,7 +3,7 @@ import { DEV } from 'esm-env';
3
3
  import { json, text } from '@sveltejs/kit';
4
4
  import { Redirect, SvelteKitError } from '@sveltejs/kit/internal';
5
5
  import { merge_tracing, with_request_store } from '@sveltejs/kit/internal/server';
6
- import { base, app_dir } from '__sveltekit/paths';
6
+ import { base, app_dir } from '$app/paths/internal/server';
7
7
  import { is_endpoint_request, render_endpoint } from './endpoint.js';
8
8
  import { render_page } from './page/index.js';
9
9
  import { render_response } from './page/render.js';
@@ -123,8 +123,9 @@ export function deep_set(object, keys, value) {
123
123
  throw new Error(`Invalid array key ${keys[i + 1]}`);
124
124
  }
125
125
  } else {
126
- object = object[key] ??= is_array ? [] : Object.create(null); // guard against prototype pollution
126
+ object[key] ??= is_array ? [] : Object.create(null); // guard against prototype pollution
127
127
  }
128
+ object = object[key];
128
129
  }
129
130
 
130
131
  object[keys[keys.length - 1]] = value;
@@ -1,8 +1,12 @@
1
1
  declare global {
2
2
  const __SVELTEKIT_ADAPTER_NAME__: string;
3
+ const __SVELTEKIT_APP_DIR__: string;
3
4
  const __SVELTEKIT_APP_VERSION_FILE__: string;
4
5
  const __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: number;
5
6
  const __SVELTEKIT_EMBEDDED__: boolean;
7
+ const __SVELTEKIT_PATHS_ASSETS__: string;
8
+ const __SVELTEKIT_PATHS_BASE__: string;
9
+ const __SVELTEKIT_PATHS_RELATIVE__: boolean;
6
10
  /** True if `config.kit.experimental.instrumentation.server` is `true` */
7
11
  const __SVELTEKIT_SERVER_TRACING_ENABLED__: boolean;
8
12
  /** true if corresponding config option is set to true */
@@ -441,6 +441,7 @@ export type SSRNodeLoader = () => Promise<SSRNode>;
441
441
 
442
442
  export interface SSROptions {
443
443
  app_template_contains_nonce: boolean;
444
+ async: boolean;
444
445
  csp: ValidatedConfig['kit']['csp'];
445
446
  csrf_check_origin: boolean;
446
447
  csrf_trusted_origins: string[];
@@ -597,7 +598,7 @@ export interface RequestState {
597
598
  record_span: RecordSpan;
598
599
  };
599
600
  form_instances?: Map<any, any>;
600
- remote_data?: Record<string, MaybePromise<any>>;
601
+ remote_data?: Map<RemoteInfo, Record<string, MaybePromise<any>>>;
601
602
  refreshes?: Record<string, Promise<any>>;
602
603
  is_endpoint_request?: boolean;
603
604
  }
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.42.1';
4
+ export const VERSION = '2.43.0';
package/types/index.d.ts CHANGED
@@ -1786,20 +1786,17 @@ declare module '@sveltejs/kit' {
1786
1786
  restore: (snapshot: T) => void;
1787
1787
  }
1788
1788
 
1789
- // If T is unknown or RemoteFormInput, the types below will recurse indefinitely and create giant unions that TS can't handle
1790
- type WillRecurseIndefinitely<T> = unknown extends T
1791
- ? true
1792
- : RemoteFormInput extends T
1793
- ? true
1794
- : false;
1789
+ // If T is unknown or has an index signature, the types below will recurse indefinitely and create giant unions that TS can't handle
1790
+ type WillRecurseIndefinitely<T> = unknown extends T ? true : string extends keyof T ? true : false;
1795
1791
 
1796
1792
  // Helper type to convert union to intersection
1797
1793
  type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
1798
1794
  ? I
1799
1795
  : never;
1800
1796
 
1801
- type FlattenInput<T, Prefix extends string> =
1802
- WillRecurseIndefinitely<T> extends true
1797
+ type FlattenInput<T, Prefix extends string> = T extends string | number | boolean | null | undefined
1798
+ ? { [P in Prefix]: string }
1799
+ : WillRecurseIndefinitely<T> extends true
1803
1800
  ? { [key: string]: string }
1804
1801
  : T extends Array<infer U>
1805
1802
  ? U extends string | File
@@ -1807,17 +1804,22 @@ declare module '@sveltejs/kit' {
1807
1804
  : FlattenInput<U, `${Prefix}[${number}]`>
1808
1805
  : T extends File
1809
1806
  ? { [P in Prefix]: string }
1810
- : T extends object
1811
- ? {
1812
- [K in keyof T]: FlattenInput<
1813
- T[K],
1814
- Prefix extends '' ? K & string : `${Prefix}.${K & string}`
1815
- >;
1816
- }[keyof T]
1817
- : { [P in Prefix]: string };
1818
-
1819
- type FlattenIssues<T, Prefix extends string> =
1820
- WillRecurseIndefinitely<T> extends true
1807
+ : {
1808
+ // Required<T> is crucial here to avoid an undefined type to sneak into the union, which would turn the intersection into never
1809
+ [K in keyof Required<T>]: FlattenInput<
1810
+ T[K],
1811
+ Prefix extends '' ? K & string : `${Prefix}.${K & string}`
1812
+ >;
1813
+ }[keyof T];
1814
+
1815
+ type FlattenIssues<T, Prefix extends string> = T extends
1816
+ | string
1817
+ | number
1818
+ | boolean
1819
+ | null
1820
+ | undefined
1821
+ ? { [P in Prefix]: RemoteFormIssue[] }
1822
+ : WillRecurseIndefinitely<T> extends true
1821
1823
  ? { [key: string]: RemoteFormIssue[] }
1822
1824
  : T extends Array<infer U>
1823
1825
  ? { [P in Prefix | `${Prefix}[${number}]`]: RemoteFormIssue[] } & FlattenIssues<
@@ -1826,17 +1828,17 @@ declare module '@sveltejs/kit' {
1826
1828
  >
1827
1829
  : T extends File
1828
1830
  ? { [P in Prefix]: RemoteFormIssue[] }
1829
- : T extends object
1830
- ? {
1831
- [K in keyof T]: FlattenIssues<
1832
- T[K],
1833
- Prefix extends '' ? K & string : `${Prefix}.${K & string}`
1834
- >;
1835
- }[keyof T]
1836
- : { [P in Prefix]: RemoteFormIssue[] };
1837
-
1838
- type FlattenKeys<T, Prefix extends string> =
1839
- WillRecurseIndefinitely<T> extends true
1831
+ : {
1832
+ // Required<T> is crucial here to avoid an undefined type to sneak into the union, which would turn the intersection into never
1833
+ [K in keyof Required<T>]: FlattenIssues<
1834
+ T[K],
1835
+ Prefix extends '' ? K & string : `${Prefix}.${K & string}`
1836
+ >;
1837
+ }[keyof T];
1838
+
1839
+ type FlattenKeys<T, Prefix extends string> = T extends string | number | boolean | null | undefined
1840
+ ? { [P in Prefix]: string }
1841
+ : WillRecurseIndefinitely<T> extends true
1840
1842
  ? { [key: string]: string }
1841
1843
  : T extends Array<infer U>
1842
1844
  ? U extends string | File
@@ -1844,14 +1846,13 @@ declare module '@sveltejs/kit' {
1844
1846
  : FlattenKeys<U, `${Prefix}[${number}]`>
1845
1847
  : T extends File
1846
1848
  ? { [P in Prefix]: string }
1847
- : T extends object
1848
- ? {
1849
- [K in keyof T]: FlattenKeys<
1850
- T[K],
1851
- Prefix extends '' ? K & string : `${Prefix}.${K & string}`
1852
- >;
1853
- }[keyof T]
1854
- : { [P in Prefix]: string };
1849
+ : {
1850
+ // Required<T> is crucial here to avoid an undefined type to sneak into the union, which would turn the intersection into never
1851
+ [K in keyof Required<T>]: FlattenKeys<
1852
+ T[K],
1853
+ Prefix extends '' ? K & string : `${Prefix}.${K & string}`
1854
+ >;
1855
+ }[keyof T];
1855
1856
 
1856
1857
  export interface RemoteFormInput {
1857
1858
  [key: string]: FormDataEntryValue | FormDataEntryValue[] | RemoteFormInput | RemoteFormInput[];
@@ -2929,7 +2930,7 @@ declare module '$app/navigation' {
2929
2930
  }
2930
2931
 
2931
2932
  declare module '$app/paths' {
2932
- import type { Asset, RouteId, RouteParams, Pathname, ResolvedPathname } from '$app/types';
2933
+ import type { RouteId, Pathname, ResolvedPathname, RouteParams, Asset } from '$app/types';
2933
2934
  /**
2934
2935
  * A string that matches [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths).
2935
2936
  *
@@ -2948,12 +2949,34 @@ declare module '$app/paths' {
2948
2949
  */
2949
2950
  export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets';
2950
2951
 
2952
+ /**
2953
+ * @deprecated Use [`resolve(...)`](https://svelte.dev/docs/kit/$app-paths#resolve) instead
2954
+ */
2955
+ export function resolveRoute<T extends RouteId | Pathname>(
2956
+ ...args: ResolveArgs<T>
2957
+ ): ResolvedPathname;
2951
2958
  type ResolveArgs<T extends RouteId | Pathname> = T extends RouteId
2952
2959
  ? RouteParams<T> extends Record<string, never>
2953
2960
  ? [route: T]
2954
2961
  : [route: T, params: RouteParams<T>]
2955
2962
  : [route: T];
2956
-
2963
+ /**
2964
+ * Resolve the URL of an asset in your `static` directory, by prefixing it with [`config.kit.paths.assets`](https://svelte.dev/docs/kit/configuration#paths) if configured, or otherwise by prefixing it with the base path.
2965
+ *
2966
+ * During server rendering, the base path is relative and depends on the page currently being rendered.
2967
+ *
2968
+ * @example
2969
+ * ```svelte
2970
+ * <script>
2971
+ * import { asset } from '$app/paths';
2972
+ * </script>
2973
+ *
2974
+ * <img alt="a potato" src={asset('/potato.jpg')} />
2975
+ * ```
2976
+ * @since 2.26
2977
+ *
2978
+ * */
2979
+ export function asset(file: Asset): string;
2957
2980
  /**
2958
2981
  * Resolve a pathname by prefixing it with the base path, if any, or resolve a route ID by populating dynamic segments with parameters.
2959
2982
  *
@@ -2972,32 +2995,9 @@ declare module '$app/paths' {
2972
2995
  * });
2973
2996
  * ```
2974
2997
  * @since 2.26
2975
- */
2976
- export function resolve<T extends RouteId | Pathname>(...args: ResolveArgs<T>): ResolvedPathname;
2977
-
2978
- /**
2979
- * Resolve the URL of an asset in your `static` directory, by prefixing it with [`config.kit.paths.assets`](https://svelte.dev/docs/kit/configuration#paths) if configured, or otherwise by prefixing it with the base path.
2980
2998
  *
2981
- * During server rendering, the base path is relative and depends on the page currently being rendered.
2982
- *
2983
- * @example
2984
- * ```svelte
2985
- * <script>
2986
- * import { asset } from '$app/paths';
2987
- * </script>
2988
- *
2989
- * <img alt="a potato" src={asset('/potato.jpg')} />
2990
- * ```
2991
- * @since 2.26
2992
- */
2993
- export function asset(file: Asset): string;
2994
-
2995
- /**
2996
- * @deprecated Use [`resolve(...)`](https://svelte.dev/docs/kit/$app-paths#resolve) instead
2997
- */
2998
- export function resolveRoute<T extends RouteId | Pathname>(
2999
- ...args: ResolveArgs<T>
3000
- ): ResolvedPathname;
2999
+ * */
3000
+ export function resolve<T extends RouteId | Pathname>(...args: ResolveArgs<T>): ResolvedPathname;
3001
3001
 
3002
3002
  export {};
3003
3003
  }