@sveltejs/kit 3.0.0-next.21 → 3.0.0-next.23

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 (47) hide show
  1. package/package.json +1 -5
  2. package/src/core/postbuild/prerender.js +19 -19
  3. package/src/core/sync/write_types/index.js +1 -3
  4. package/src/exports/hooks/public.d.ts +1 -2
  5. package/src/exports/hooks/sequence.js +1 -1
  6. package/src/exports/index.js +10 -0
  7. package/src/exports/internal/server/event.js +1 -1
  8. package/src/exports/public.d.ts +205 -2
  9. package/src/exports/vite/dev/index.js +1 -2
  10. package/src/exports/vite/index.js +2 -2
  11. package/src/runtime/app/server/public.d.ts +480 -168
  12. package/src/runtime/app/server/remote/command.js +1 -1
  13. package/src/runtime/app/server/remote/form.js +5 -5
  14. package/src/runtime/app/server/remote/prerender.js +1 -1
  15. package/src/runtime/app/server/remote/query.js +2 -2
  16. package/src/runtime/app/server/remote/requested.js +3 -3
  17. package/src/runtime/app/server/remote/shared.js +1 -1
  18. package/src/runtime/client/remote-functions/command.svelte.js +1 -1
  19. package/src/runtime/client/remote-functions/form.svelte.js +1 -1
  20. package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
  21. package/src/runtime/client/remote-functions/query/index.js +1 -1
  22. package/src/runtime/client/remote-functions/query/instance.svelte.js +2 -1
  23. package/src/runtime/client/remote-functions/query-batch.svelte.js +1 -1
  24. package/src/runtime/client/remote-functions/query-live/index.js +1 -1
  25. package/src/runtime/client/remote-functions/query-live/instance.svelte.js +4 -3
  26. package/src/runtime/client/remote-functions/shared.svelte.js +1 -1
  27. package/src/runtime/server/cookie.js +2 -2
  28. package/src/runtime/server/data/index.js +1 -1
  29. package/src/runtime/server/endpoint.js +3 -3
  30. package/src/runtime/server/errors.js +2 -2
  31. package/src/runtime/server/fetch.js +1 -1
  32. package/src/runtime/server/page/actions.js +1 -2
  33. package/src/runtime/server/page/data_serializer.js +2 -2
  34. package/src/runtime/server/page/index.js +1 -2
  35. package/src/runtime/server/page/load_data.js +3 -3
  36. package/src/runtime/server/page/render.js +1 -1
  37. package/src/runtime/server/page/respond_with_error.js +1 -1
  38. package/src/runtime/server/remote-functions.js +2 -3
  39. package/src/runtime/server/respond.js +2 -2
  40. package/src/runtime/server/utils.js +1 -1
  41. package/src/types/internal.d.ts +2 -2
  42. package/src/utils/promise.js +25 -0
  43. package/src/version.js +1 -1
  44. package/types/index.d.ts +750 -762
  45. package/types/index.d.ts.map +46 -50
  46. package/src/exports/remote/index.js +0 -11
  47. package/src/exports/remote/public.d.ts +0 -519
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "3.0.0-next.21",
3
+ "version": "3.0.0-next.23",
4
4
  "description": "SvelteKit is the fastest way to build Svelte apps",
5
5
  "keywords": [
6
6
  "framework",
@@ -129,10 +129,6 @@
129
129
  "types": "./types/index.d.ts",
130
130
  "import": "./src/exports/params/index.js"
131
131
  },
132
- "./remote": {
133
- "types": "./types/index.d.ts",
134
- "import": "./src/exports/remote/index.js"
135
- },
136
132
  "./vite": {
137
133
  "types": "./types/index.d.ts",
138
134
  "import": "./src/exports/vite/index.js"
@@ -1,7 +1,6 @@
1
1
  import process from 'node:process';
2
2
  import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
- import { clearLine, moveCursor } from 'node:readline';
5
4
  import { pathToFileURL } from 'node:url';
6
5
  import { walk } from '../../utils/filesystem.js';
7
6
  import { posixify } from '../../utils/os.js';
@@ -283,26 +282,31 @@ async function prerender({
283
282
  // currently requesting, then clearing the line once the response comes in.
284
283
  // This avoids the wall of text that happens when you prerender
285
284
  // many pages and log each response
285
+ const { stdout, stderr } = process;
286
+
286
287
  let current = false;
287
- let mid_line = false;
288
- const stdout_write = process.stdout.write;
289
- const stderr_write = process.stderr.write;
288
+ let needs_newline = true;
289
+
290
+ const write = stdout.write;
291
+
292
+ /** @param {string} value */
293
+ const print = (value) => write.call(stdout, value);
290
294
 
291
- /** @type {ProxyHandler<typeof stdout_write>} */
292
- const track_output = {
295
+ /** @type {ProxyHandler<typeof stdout.write>} */
296
+ const intercept = {
293
297
  apply(target, this_arg, args) {
294
298
  const chunk = args[0];
295
299
  if (chunk.length > 0) {
296
300
  current = false;
297
- mid_line =
301
+ needs_newline =
298
302
  typeof chunk === 'string' ? !chunk.endsWith('\n') : chunk[chunk.length - 1] !== 10;
299
303
  }
300
304
  return Reflect.apply(target, this_arg, args);
301
305
  }
302
306
  };
303
307
 
304
- process.stdout.write = new Proxy(stdout_write, track_output);
305
- process.stderr.write = new Proxy(stderr_write, track_output);
308
+ stdout.write = new Proxy(stdout.write, intercept);
309
+ stderr.write = new Proxy(stderr.write, intercept);
306
310
 
307
311
  progress = {
308
312
  clear: () => {
@@ -310,25 +314,21 @@ async function prerender({
310
314
  // the previous progress log, because that will corrupt things
311
315
  if (!current) return;
312
316
 
313
- moveCursor(process.stdout, 0, -1);
314
- clearLine(process.stdout, 0);
317
+ print('\x1B[1A'); // move cursor to start of progress update
318
+ print('\x1B[2K'); // clear current line
315
319
  },
316
320
 
317
321
  update: (path) => {
318
- if (mid_line) {
319
- // app output ended mid-line — start a fresh one rather than appending to it
320
- stdout_write.call(process.stdout, '\n');
321
- }
322
+ // if we're in the middle of a line, start a new one
323
+ if (needs_newline) print('\n');
322
324
 
323
- stdout_write.call(process.stdout, `crawling ${path}\n`);
325
+ print(`crawling ${path}\n`);
324
326
  current = true;
325
- mid_line = false;
327
+ needs_newline = false;
326
328
  },
327
329
 
328
330
  updated: 0
329
331
  };
330
-
331
- console.log('');
332
332
  }
333
333
 
334
334
  /** @type {Set<string>} */
@@ -354,9 +354,7 @@ function update_types(config, routes, route, root, to_delete = new Set()) {
354
354
  }
355
355
 
356
356
  if (route.leaf?.server || route.layout?.server || route.endpoint) {
357
- exports.push(
358
- "export type RequestEvent = import('$app/server').RequestEvent<RouteParams, RouteId>;"
359
- );
357
+ exports.push('export type RequestEvent = Kit.RequestEvent<RouteParams, RouteId>;');
360
358
  }
361
359
 
362
360
  const output = [imports.join('\n'), declarations.join('\n'), exports.join('\n')]
@@ -1,6 +1,5 @@
1
1
  import { StandardSchemaV1 } from '@standard-schema/spec';
2
- import { NavigationEvent } from '@sveltejs/kit';
3
- import { RequestEvent } from '$app/server';
2
+ import { NavigationEvent, RequestEvent } from '@sveltejs/kit';
4
3
  import { MaybePromise } from 'types';
5
4
 
6
5
  export * from './index.js';
@@ -1,4 +1,4 @@
1
- /** @import { RequestEvent } from '$app/server' */
1
+ /** @import { RequestEvent } from '@sveltejs/kit' */
2
2
  /** @import { Handle, ResolveOptions } from '@sveltejs/kit/hooks' */
3
3
  import {
4
4
  merge_tracing,
@@ -270,6 +270,16 @@ export function invalid(...issues) {
270
270
  );
271
271
  }
272
272
 
273
+ /**
274
+ * Checks whether this is a validation error thrown by {@link invalid}.
275
+ * @param {unknown} e The object to check.
276
+ * @return {e is import('./public.js').ValidationError}
277
+ * @since 2.47.3
278
+ */
279
+ export function isValidationError(e) {
280
+ return e instanceof ValidationError;
281
+ }
282
+
273
283
  /**
274
284
  * Strips possible SvelteKit-internal suffixes and trailing slashes from the URL pathname.
275
285
  * Returns the normalized URL as well as a method for adding the potential suffix back
@@ -1,4 +1,4 @@
1
- /** @import { RequestEvent } from '$app/server' */
1
+ /** @import { RequestEvent } from '@sveltejs/kit' */
2
2
  /** @import { RequestStore } from 'types' */
3
3
  /** @import { AsyncLocalStorage } from 'node:async_hooks' */
4
4
  import { IN_WEBCONTAINER } from '../../../constants.js';
@@ -14,9 +14,9 @@ import {
14
14
  } from '../types/private.js';
15
15
  import { BuildData, SSRNodeLoader, SSRRoute, ValidatedConfig } from 'types';
16
16
  import { Plugin } from 'vite';
17
- import { RequestEvent } from '$app/server';
18
17
  import { RouteId as AppRouteId, LayoutParams as AppLayoutParams } from '$app/types';
19
18
  import { ParamMatcher } from '@sveltejs/kit/params';
19
+ import { StandardSchemaV1 } from '@standard-schema/spec';
20
20
 
21
21
  export { PrerenderOption } from '../types/private.js';
22
22
 
@@ -100,6 +100,14 @@ export interface ActionFailure<T = undefined> {
100
100
  [uniqueSymbol]: true; // necessary or else UnpackValidationError could wrongly unpack objects with the same shape as ActionFailure
101
101
  }
102
102
 
103
+ /**
104
+ * A validation error thrown by `invalid`.
105
+ */
106
+ export interface ValidationError {
107
+ /** The validation issues */
108
+ issues: StandardSchemaV1.Issue[];
109
+ }
110
+
103
111
  type UnpackValidationError<T> =
104
112
  T extends ActionFailure<infer X>
105
113
  ? X
@@ -257,6 +265,80 @@ export interface Builder {
257
265
  compress: (directory: string) => Promise<string[]>;
258
266
  }
259
267
 
268
+ export interface Cookies {
269
+ /**
270
+ * Gets a cookie that was previously set with `cookies.set`, or from the request headers.
271
+ * @param name the name of the cookie
272
+ * @param opts the options, passed directly to `cookie.parseCookie`. See documentation [here](https://github.com/jshttp/cookie?tab=readme-ov-file#cookieparsecookiestr-options)
273
+ */
274
+ get: (name: string, opts?: import('cookie').ParseOptions) => string | undefined;
275
+
276
+ /**
277
+ * Gets all cookies that were previously set with `cookies.set`, or from the request headers.
278
+ * @param opts the options, passed directly to `cookie.parseCookie`. See documentation [here](https://github.com/jshttp/cookie?tab=readme-ov-file#cookieparsecookiestr-options)
279
+ */
280
+ getAll: (opts?: import('cookie').ParseOptions) => Array<{ name: string; value: string }>;
281
+
282
+ /**
283
+ * Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request.
284
+ *
285
+ * The `httpOnly` is `true` by default, as is `secure`, except during development, when it defaults to `false`. These must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP.
286
+ *
287
+ * The `path` option is `'/'` by default. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children.
288
+ * @param name the name of the cookie
289
+ * @param value the cookie value
290
+ * @param opts the options passed to `cookie.stringifySetCookie` with the SvelteKit defaults described above. See documentation [here](https://github.com/jshttp/cookie?tab=readme-ov-file#cookiestringifysetcookiesetcookieobj-options)
291
+ */
292
+ set: (name: string, value: string, opts: import('cookie').SerializeOptions) => void;
293
+
294
+ /**
295
+ * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past.
296
+ *
297
+ * The `httpOnly` is `true` by default, as is `secure`, except during development, when it defaults to `false`. These must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP.
298
+ *
299
+ * The `path` option is `'/'` by default. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children.
300
+ * @param name the name of the cookie
301
+ * @param opts the options passed to `cookie.stringifySetCookie` with the SvelteKit defaults described above. See documentation [here](https://github.com/jshttp/cookie?tab=readme-ov-file#cookiestringifysetcookiesetcookieobj-options)
302
+ */
303
+ delete: (name: string, opts: import('cookie').SerializeOptions) => void;
304
+
305
+ /**
306
+ * Parses a single `Set-Cookie` header. This allows you to apply cookies received from an external source:
307
+ *
308
+ * ```js
309
+ * import { getRequestEvent } from '$app/server';
310
+ *
311
+ * export async function GET() {
312
+ * const { cookies } = getRequestEvent();
313
+ *
314
+ * const response = await fetch('...');
315
+ *
316
+ * for (const str of response.headers.getSetCookie()) {
317
+ * const { name, value, ...options } = cookies.parse(str);
318
+ * cookies.set(name, value, { ...options, path: '/' });
319
+ * }
320
+ *
321
+ * // ...
322
+ * }
323
+ * ```
324
+ *
325
+ * Note the use of `headers.getSetCookie()`, which returns an array of cookie headers, _not_ `headers.get('set-cookie')` which returns a single comma-separated string.
326
+ */
327
+ parse: typeof import('cookie').parseSetCookie;
328
+
329
+ /**
330
+ * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response.
331
+ *
332
+ * The `httpOnly` is `true` by default, as is `secure`, except during development, when it defaults to `false`. These must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP.
333
+ *
334
+ * The `path` option is `'/'` by default. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children.
335
+ * @param name the name of the cookie
336
+ * @param value the cookie value
337
+ * @param opts the options passed to `cookie.stringifySetCookie` with the SvelteKit defaults described above. See documentation [here](https://github.com/jshttp/cookie?tab=readme-ov-file#cookiestringifysetcookiesetcookieobj-options)
338
+ */
339
+ serialize: (name: string, value: string, opts: import('cookie').SerializeOptions) => string;
340
+ }
341
+
260
342
  /**
261
343
  * A collection of functions that influence the environment during dev, build and prerendering
262
344
  */
@@ -326,7 +408,7 @@ export interface LoadEvent<
326
408
  *
327
409
  * Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once.
328
410
  *
329
- * You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/$app-server#Cookies) API in a server-only `load` function instead.
411
+ * You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/@sveltejs-kit#Cookies) API in a server-only `load` function instead.
330
412
  *
331
413
  * `setHeaders` has no effect when a `load` function runs in the browser.
332
414
  */
@@ -428,6 +510,127 @@ export interface NavigationEvent<
428
510
  url: URL;
429
511
  }
430
512
 
513
+ export interface RequestEvent<
514
+ Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>,
515
+ RouteId extends AppRouteId | null = AppRouteId | null
516
+ > {
517
+ /**
518
+ * Get or set cookies related to the current request
519
+ */
520
+ readonly cookies: Cookies;
521
+ /**
522
+ * `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:
523
+ *
524
+ * - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request.
525
+ * - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context).
526
+ * - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call.
527
+ * - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://svelte.dev/docs/kit/hooks#handle)
528
+ * - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request.
529
+ *
530
+ * You can learn more about making credentialed requests with cookies [here](https://svelte.dev/docs/kit/load#Cookies).
531
+ */
532
+ readonly fetch: typeof fetch;
533
+ /**
534
+ * The client's IP address, set by the adapter.
535
+ */
536
+ readonly getClientAddress: () => string;
537
+ /**
538
+ * Contains custom data that was added to the request within the [`server handle hook`](https://svelte.dev/docs/kit/hooks#handle).
539
+ */
540
+ readonly locals: App.Locals;
541
+ /**
542
+ * The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object.
543
+ *
544
+ * Inside `query` functions (including `query.batch` and `query.live`), accessing this property throws an error.
545
+ * Pass values from the page as arguments to the query instead. Inside `form` and `command` functions it relates to the page
546
+ * the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use it
547
+ * to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
548
+ */
549
+ readonly params: Params;
550
+ /**
551
+ * Additional data made available through the adapter.
552
+ */
553
+ readonly platform: Readonly<App.Platform> | undefined;
554
+ /**
555
+ * The original request object.
556
+ */
557
+ readonly request: Request;
558
+ /**
559
+ * Info about the current route.
560
+ */
561
+ readonly route: {
562
+ /**
563
+ * The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched.
564
+ *
565
+ * Inside `query` functions (including `query.batch` and `query.live`), accessing this property throws an error.
566
+ * Pass values from the page as arguments to the query instead. Inside `form` and `command` functions it relates to the page
567
+ * the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use it
568
+ * to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
569
+ */
570
+ id: RouteId;
571
+ };
572
+ /**
573
+ * If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example:
574
+ *
575
+ * ```js
576
+ * /// file: src/routes/blog/+page.js
577
+ * export async function load({ fetch, setHeaders }) {
578
+ * const url = `https://cms.example.com/articles.json`;
579
+ * const response = await fetch(url);
580
+ *
581
+ * setHeaders({
582
+ * age: response.headers.get('age'),
583
+ * 'cache-control': response.headers.get('cache-control')
584
+ * });
585
+ *
586
+ * return response.json();
587
+ * }
588
+ * ```
589
+ *
590
+ * Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once.
591
+ *
592
+ * You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/@sveltejs-kit#Cookies) API instead.
593
+ */
594
+ readonly setHeaders: (headers: Record<string, string>) => void;
595
+ /**
596
+ * The requested URL.
597
+ *
598
+ * Inside `query` functions (including `query.batch` and `query.live`), accessing this property throws an error.
599
+ * Pass values from the page as arguments to the query instead. Inside `form` and `command` functions it relates to the page
600
+ * the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use it
601
+ * to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
602
+ */
603
+ readonly url: URL;
604
+ /**
605
+ * `true` if the request comes from the client asking for `+page/layout.server.js` data. The `url` property will be stripped of the internal information
606
+ * related to the data request in this case. Use this property instead if the distinction is important to you.
607
+ */
608
+ readonly isDataRequest: boolean;
609
+ /**
610
+ * `true` for `+server.js` calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin `fetch` requests on the server.
611
+ */
612
+ readonly isSubRequest: boolean;
613
+
614
+ /**
615
+ * Access to spans for tracing. If tracing is not enabled, these spans will do nothing.
616
+ * @since 2.31.0
617
+ */
618
+ readonly tracing: {
619
+ /** Whether tracing is enabled. */
620
+ enabled: boolean;
621
+ /** The root span for the request. This span is named `sveltekit.handle.root`. */
622
+ root: Span;
623
+ /** The span associated with the current `handle` hook, `load` function, or form action. */
624
+ current: Span;
625
+ };
626
+
627
+ /**
628
+ * `true` if the request comes from the client via a remote function. The `url` property will be stripped of the internal information
629
+ * related to the data request in this case. Use this property instead if the distinction is important to you.
630
+ */
631
+ readonly isRemoteRequest: boolean;
632
+ }
633
+
431
634
  /**
432
635
  * A `(event: RequestEvent) => Response` function exported from a `+server.js` file that corresponds to an HTTP verb (`GET`, `PUT`, `PATCH`, etc) and handles requests with that method.
433
636
  *
@@ -1,5 +1,4 @@
1
- /** @import { SSRManifest } from '@sveltejs/kit' */
2
- /** @import { RequestEvent } from '$app/server' */
1
+ /** @import { RequestEvent, SSRManifest } from '@sveltejs/kit' */
3
2
  /** @import { EnvironmentModuleNode, ErrorPayload, ResolvedConfig, ViteDevServer } from 'vite' */
4
3
  /** @import { ManifestData, PrerenderOption, RemoteChunk, ServerModule, SSRNode, UniversalNode, ValidatedConfig } from 'types' */
5
4
  import process from 'node:process';
@@ -635,7 +635,7 @@ function kit({ svelte_config }) {
635
635
 
636
636
  const unsupported_plugins = vite_config.plugins.filter((plugin) => plugin.transformIndexHtml);
637
637
  if (unsupported_plugins.length) {
638
- const verbose = vite_config.logLevel === 'info';
638
+ const verbose = vite_config.logLevel === 'info' || vite_config.logLevel === undefined;
639
639
  const log = logger({ verbose });
640
640
 
641
641
  const list = unsupported_plugins
@@ -1689,7 +1689,7 @@ function kit({ svelte_config }) {
1689
1689
  fs.rmSync(out, { force: true, recursive: true });
1690
1690
  fs.mkdirSync(out, { recursive: true });
1691
1691
 
1692
- const verbose = builder.config.logLevel === 'info';
1692
+ const verbose = builder.config.logLevel === 'info' || builder.config.logLevel === undefined;
1693
1693
  const log = logger({ verbose });
1694
1694
 
1695
1695
  let ssr_build = await builder.build(builder.environments.ssr);