@sveltejs/kit 1.0.0-next.561 → 1.0.0-next.563

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": "1.0.0-next.561",
3
+ "version": "1.0.0-next.563",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -93,24 +93,22 @@ export function create_builder({ config, build_data, routes, prerendered, log })
93
93
 
94
94
  if (filtered.size > 0) {
95
95
  await complete({
96
- generateManifest: ({ relativePath, format }) =>
96
+ generateManifest: ({ relativePath }) =>
97
97
  generate_manifest({
98
98
  build_data,
99
99
  relative_path: relativePath,
100
- routes: Array.from(filtered),
101
- format
100
+ routes: Array.from(filtered)
102
101
  })
103
102
  });
104
103
  }
105
104
  }
106
105
  },
107
106
 
108
- generateManifest: ({ relativePath, format }) => {
107
+ generateManifest: ({ relativePath }) => {
109
108
  return generate_manifest({
110
109
  build_data,
111
110
  relative_path: relativePath,
112
- routes,
113
- format
111
+ routes
114
112
  });
115
113
  },
116
114
 
@@ -126,10 +124,6 @@ export function create_builder({ config, build_data, routes, prerendered, log })
126
124
  return `${config.kit.outDir}/output/server`;
127
125
  },
128
126
 
129
- getStaticDirectory() {
130
- return config.kit.files.assets;
131
- },
132
-
133
127
  getAppPath() {
134
128
  return build_data.app_path;
135
129
  },
@@ -11,10 +11,9 @@ import { join_relative } from '../../utils/filesystem.js';
11
11
  * build_data: import('types').BuildData;
12
12
  * relative_path: string;
13
13
  * routes: import('types').RouteData[];
14
- * format?: 'esm' | 'cjs'
15
14
  * }} opts
16
15
  */
17
- export function generate_manifest({ build_data, relative_path, routes, format = 'esm' }) {
16
+ export function generate_manifest({ build_data, relative_path, routes }) {
18
17
  /**
19
18
  * @type {Map<any, number>} The new index of each node in the filtered nodes array
20
19
  */
@@ -55,13 +54,7 @@ export function generate_manifest({ build_data, relative_path, routes, format =
55
54
  });
56
55
 
57
56
  /** @type {(path: string) => string} */
58
- const load =
59
- format === 'esm'
60
- ? (path) => `import('${path}')`
61
- : (path) => `Promise.resolve().then(() => require('${path}'))`;
62
-
63
- /** @type {(path: string) => string} */
64
- const loader = (path) => `() => ${load(path)}`;
57
+ const loader = (path) => `() => import('${path}')`;
65
58
 
66
59
  const assets = build_data.manifest_data.assets.map((asset) => asset.file);
67
60
  if (build_data.service_worker) {
@@ -115,7 +108,7 @@ export function generate_manifest({ build_data, relative_path, routes, format =
115
108
  }).filter(Boolean).join(',\n\t\t\t\t')}
116
109
  ],
117
110
  matchers: async () => {
118
- ${Array.from(matchers).map(type => `const { match: ${type} } = await ${load(join_relative(relative_path, `/entries/matchers/${type}.js`))}`).join('\n\t\t\t\t')}
111
+ ${Array.from(matchers).map(type => `const { match: ${type} } = await import ('${(join_relative(relative_path, `/entries/matchers/${type}.js`))}')`).join('\n\t\t\t\t')}
119
112
  return { ${Array.from(matchers).join(', ')} };
120
113
  }
121
114
  }
@@ -426,28 +426,29 @@ export async function dev(vite, vite_config, svelte_config) {
426
426
  check_origin: svelte_config.kit.csrf.checkOrigin
427
427
  },
428
428
  dev: true,
429
- handle_error: (error, event) => {
430
- return (
431
- hooks.handleError({
432
- error: new Proxy(error, {
433
- get: (target, property) => {
434
- if (property === 'stack') {
435
- return fix_stack_trace(error);
436
- }
437
-
438
- return Reflect.get(target, property, target);
429
+ handle_error: async (error, event) => {
430
+ const error_object = await hooks.handleError({
431
+ error: new Proxy(error, {
432
+ get: (target, property) => {
433
+ if (property === 'stack') {
434
+ return fix_stack_trace(error);
439
435
  }
440
- }),
441
- event,
442
-
443
- // TODO remove for 1.0
444
- // @ts-expect-error
445
- get request() {
446
- throw new Error(
447
- 'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
448
- );
436
+
437
+ return Reflect.get(target, property, target);
449
438
  }
450
- }) ?? { message: event.route.id != null ? 'Internal Error' : 'Not Found' }
439
+ }),
440
+ event,
441
+
442
+ // TODO remove for 1.0
443
+ // @ts-expect-error
444
+ get request() {
445
+ throw new Error(
446
+ 'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
447
+ );
448
+ }
449
+ });
450
+ return (
451
+ error_object ?? { message: event.route.id != null ? 'Internal Error' : 'Not Found' }
451
452
  );
452
453
  },
453
454
  hooks,
@@ -248,7 +248,7 @@ export function create_client({ target, base }) {
248
248
  navigation_result = await server_fallback(
249
249
  url,
250
250
  { id: null },
251
- handle_error(new Error(`Not found: ${url.pathname}`), {
251
+ await handle_error(new Error(`Not found: ${url.pathname}`), {
252
252
  url,
253
253
  params: {},
254
254
  route: { id: null }
@@ -268,7 +268,11 @@ export function create_client({ target, base }) {
268
268
  if (redirect_chain.length > 10 || redirect_chain.includes(url.pathname)) {
269
269
  navigation_result = await load_root_error_page({
270
270
  status: 500,
271
- error: handle_error(new Error('Redirect loop'), { url, params: {}, route: { id: null } }),
271
+ error: await handle_error(new Error('Redirect loop'), {
272
+ url,
273
+ params: {},
274
+ route: { id: null }
275
+ }),
272
276
  url,
273
277
  route: { id: null }
274
278
  });
@@ -770,7 +774,7 @@ export function create_client({ target, base }) {
770
774
  } catch (error) {
771
775
  return load_root_error_page({
772
776
  status: 500,
773
- error: handle_error(error, { url, params, route: { id: route.id } }),
777
+ error: await handle_error(error, { url, params, route: { id: route.id } }),
774
778
  url,
775
779
  route
776
780
  });
@@ -859,7 +863,7 @@ export function create_client({ target, base }) {
859
863
  status = err.status;
860
864
  error = err.body;
861
865
  } else {
862
- error = handle_error(err, { params, url, route: { id: route.id } });
866
+ error = await handle_error(err, { params, url, route: { id: route.id } });
863
867
  }
864
868
 
865
869
  const error_load = await load_nearest_error_page(i, branch, errors);
@@ -1385,7 +1389,7 @@ export function create_client({ target, base }) {
1385
1389
  }, 20);
1386
1390
  };
1387
1391
 
1388
- target.addEventListener('touchstart', trigger_prefetch);
1392
+ target.addEventListener('touchstart', trigger_prefetch, { passive: true });
1389
1393
  target.addEventListener('mousemove', handle_mousemove);
1390
1394
  target.addEventListener('sveltekit:trigger_prefetch', trigger_prefetch);
1391
1395
 
@@ -1567,7 +1571,7 @@ export function create_client({ target, base }) {
1567
1571
 
1568
1572
  result = await load_root_error_page({
1569
1573
  status: error instanceof HttpError ? error.status : 500,
1570
- error: handle_error(error, { url, params, route }),
1574
+ error: await handle_error(error, { url, params, route }),
1571
1575
  url,
1572
1576
  route
1573
1577
  });
@@ -1619,7 +1623,7 @@ async function load_data(url, invalid) {
1619
1623
  /**
1620
1624
  * @param {unknown} error
1621
1625
  * @param {import('types').NavigationEvent} event
1622
- * @returns {App.Error}
1626
+ * @returns {import('../../../types/private.js').MaybePromise<App.Error>}
1623
1627
  */
1624
1628
  function handle_error(error, event) {
1625
1629
  if (error instanceof HttpError) {
@@ -1717,8 +1721,8 @@ function reset_focus() {
1717
1721
 
1718
1722
  if (__SVELTEKIT_DEV__) {
1719
1723
  // Nasty hack to silence harmless warnings the user can do nothing about
1720
- const warn = console.warn;
1721
- console.warn = (...args) => {
1724
+ const console_warn = console.warn;
1725
+ console.warn = function warn(...args) {
1722
1726
  if (
1723
1727
  args.length === 1 &&
1724
1728
  /<(Layout|Page)(_[\w$]+)?> was created (with unknown|without expected) prop '(data|form)'/.test(
@@ -1727,6 +1731,6 @@ if (__SVELTEKIT_DEV__) {
1727
1731
  ) {
1728
1732
  return;
1729
1733
  }
1730
- warn(...args);
1734
+ console_warn(...args);
1731
1735
  };
1732
1736
  }
@@ -87,7 +87,7 @@ export async function render_data(event, route, options, state, trailing_slash)
87
87
  let length = promises.length;
88
88
  const nodes = await Promise.all(
89
89
  promises.map((p, i) =>
90
- p.catch((error) => {
90
+ p.catch(async (error) => {
91
91
  if (error instanceof Redirect) {
92
92
  throw error;
93
93
  }
@@ -97,7 +97,7 @@ export async function render_data(event, route, options, state, trailing_slash)
97
97
 
98
98
  return /** @type {import('types').ServerErrorNode} */ ({
99
99
  type: 'error',
100
- error: handle_error_and_jsonify(event, options, error),
100
+ error: await handle_error_and_jsonify(event, options, error),
101
101
  status: error instanceof HttpError ? error.status : undefined
102
102
  });
103
103
  })
@@ -117,15 +117,10 @@ export async function render_data(event, route, options, state, trailing_slash)
117
117
  const error = normalize_error(e);
118
118
 
119
119
  if (error instanceof Redirect) {
120
- return json_response(
121
- JSON.stringify({
122
- type: 'redirect',
123
- location: error.location
124
- })
125
- );
120
+ return redirect_json_response(error);
126
121
  } else {
127
122
  // TODO make it clearer that this was an unexpected error
128
- return json_response(JSON.stringify(handle_error_and_jsonify(event, options, error)));
123
+ return json_response(JSON.stringify(await handle_error_and_jsonify(event, options, error)));
129
124
  }
130
125
  }
131
126
  }
@@ -143,3 +138,15 @@ function json_response(json, status = 200) {
143
138
  }
144
139
  });
145
140
  }
141
+
142
+ /**
143
+ * @param {Redirect} redirect
144
+ */
145
+ export function redirect_json_response(redirect) {
146
+ return json_response(
147
+ JSON.stringify({
148
+ type: 'redirect',
149
+ location: redirect.location
150
+ })
151
+ );
152
+ }
@@ -13,7 +13,7 @@ import {
13
13
  strip_data_suffix
14
14
  } from '../../utils/url.js';
15
15
  import { exec } from '../../utils/routing.js';
16
- import { INVALIDATED_HEADER, render_data } from './data/index.js';
16
+ import { INVALIDATED_HEADER, redirect_json_response, render_data } from './data/index.js';
17
17
  import { add_cookies_to_headers, get_cookies } from './cookie.js';
18
18
  import { create_fetch } from './fetch.js';
19
19
  import { Redirect } from '../control.js';
@@ -289,12 +289,25 @@ export async function respond(request, options, state) {
289
289
  }
290
290
  }
291
291
 
292
+ // Edge case: If user does `return Response(30x)` in handle hook while processing a data request,
293
+ // we need to transform the redirect response to a corresponding JSON response.
294
+ if (is_data_request && response.status >= 300 && response.status <= 308) {
295
+ const location = response.headers.get('location');
296
+ if (location) {
297
+ return redirect_json_response(new Redirect(/** @type {any} */ (response.status), location));
298
+ }
299
+ }
300
+
292
301
  return response;
293
302
  } catch (error) {
294
303
  if (error instanceof Redirect) {
295
- return redirect_response(error.status, error.location);
304
+ if (is_data_request) {
305
+ return redirect_json_response(error);
306
+ } else {
307
+ return redirect_response(error.status, error.location);
308
+ }
296
309
  }
297
- return handle_fatal_error(event, options, error);
310
+ return await handle_fatal_error(event, options, error);
298
311
  }
299
312
 
300
313
  /**
@@ -386,7 +399,7 @@ export async function respond(request, options, state) {
386
399
  return await fetch(request);
387
400
  } catch (error) {
388
401
  // HttpError from endpoint can end up here - TODO should it be handled there instead?
389
- return handle_fatal_error(event, options, error);
402
+ return await handle_fatal_error(event, options, error);
390
403
  } finally {
391
404
  event.cookies.set = () => {
392
405
  throw new Error('Cannot use `cookies.set(...)` after the response has been generated');
@@ -72,7 +72,7 @@ export async function handle_action_json_request(event, options, server) {
72
72
  return action_json(
73
73
  {
74
74
  type: 'error',
75
- error: handle_error_and_jsonify(event, options, check_incorrect_invalid_use(error))
75
+ error: await handle_error_and_jsonify(event, options, check_incorrect_invalid_use(error))
76
76
  },
77
77
  {
78
78
  status: error instanceof HttpError ? error.status : 500
@@ -223,7 +223,7 @@ export async function render_page(event, route, page, options, state, resolve_op
223
223
  }
224
224
 
225
225
  const status = err instanceof HttpError ? err.status : 500;
226
- const error = handle_error_and_jsonify(event, options, err);
226
+ const error = await handle_error_and_jsonify(event, options, err);
227
227
 
228
228
  while (i--) {
229
229
  if (page.errors[i]) {
@@ -80,7 +80,7 @@ export async function respond_with_error({ event, options, state, status, error,
80
80
  csr: get_option([default_layout], 'csr') ?? true
81
81
  },
82
82
  status,
83
- error: handle_error_and_jsonify(event, options, error),
83
+ error: await handle_error_and_jsonify(event, options, error),
84
84
  branch,
85
85
  fetched,
86
86
  event,
@@ -96,7 +96,7 @@ export async function respond_with_error({ event, options, state, status, error,
96
96
  return static_error_page(
97
97
  options,
98
98
  error instanceof HttpError ? error.status : 500,
99
- handle_error_and_jsonify(event, options, error).message
99
+ (await handle_error_and_jsonify(event, options, error)).message
100
100
  );
101
101
  }
102
102
  }
@@ -113,10 +113,10 @@ export function static_error_page(options, status, message) {
113
113
  * @param {import('types').SSROptions} options
114
114
  * @param {unknown} error
115
115
  */
116
- export function handle_fatal_error(event, options, error) {
116
+ export async function handle_fatal_error(event, options, error) {
117
117
  error = error instanceof HttpError ? error : coalesce_to_error(error);
118
118
  const status = error instanceof HttpError ? error.status : 500;
119
- const body = handle_error_and_jsonify(event, options, error);
119
+ const body = await handle_error_and_jsonify(event, options, error);
120
120
 
121
121
  // ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it
122
122
  const type = negotiate(event.request.headers.get('accept') || 'text/html', [
@@ -138,7 +138,7 @@ export function handle_fatal_error(event, options, error) {
138
138
  * @param {import('types').RequestEvent} event
139
139
  * @param {import('types').SSROptions} options
140
140
  * @param {any} error
141
- * @returns {App.Error}
141
+ * @returns {import('types').MaybePromise<App.Error>}
142
142
  */
143
143
  export function handle_error_and_jsonify(event, options, error) {
144
144
  if (error instanceof HttpError) {
package/types/index.d.ts CHANGED
@@ -72,12 +72,11 @@ export interface Builder {
72
72
  */
73
73
  createEntries(fn: (route: RouteDefinition) => AdapterEntry): Promise<void>;
74
74
 
75
- generateManifest(opts: { relativePath: string; format?: 'esm' | 'cjs' }): string;
75
+ generateManifest(opts: { relativePath: string }): string;
76
76
 
77
77
  getBuildDirectory(name: string): string;
78
78
  getClientDirectory(): string;
79
79
  getServerDirectory(): string;
80
- getStaticDirectory(): string;
81
80
  /** The application path including any configured base path */
82
81
  getAppPath(): string;
83
82
 
@@ -242,12 +241,20 @@ export interface Handle {
242
241
  }): MaybePromise<Response>;
243
242
  }
244
243
 
244
+ /**
245
+ * If an unexpected error is thrown during loading or rendering, this function will be called with the error and the event.
246
+ * Make sure that this function _never_ throws an error.
247
+ */
245
248
  export interface HandleServerError {
246
- (input: { error: unknown; event: RequestEvent }): void | App.Error;
249
+ (input: { error: unknown; event: RequestEvent }): MaybePromise<void | App.Error>;
247
250
  }
248
251
 
252
+ /**
253
+ * If an unexpected error is thrown during loading or the following render, this function will be called with the error and the event.
254
+ * Make sure that this function _never_ throws an error.
255
+ */
249
256
  export interface HandleClientError {
250
- (input: { error: unknown; event: NavigationEvent }): void | App.Error;
257
+ (input: { error: unknown; event: NavigationEvent }): MaybePromise<void | App.Error>;
251
258
  }
252
259
 
253
260
  export interface HandleFetch {
@@ -298,7 +298,7 @@ export interface SSROptions {
298
298
  check_origin: boolean;
299
299
  };
300
300
  dev: boolean;
301
- handle_error(error: Error & { frame?: string }, event: RequestEvent): App.Error;
301
+ handle_error(error: Error & { frame?: string }, event: RequestEvent): MaybePromise<App.Error>;
302
302
  hooks: ServerHooks;
303
303
  manifest: SSRManifest;
304
304
  paths: {
@@ -21,9 +21,7 @@ export interface AdapterEntry {
21
21
  * A function that is invoked once the entry has been created. This is where you
22
22
  * should write the function to the filesystem and generate redirect manifests.
23
23
  */
24
- complete(entry: {
25
- generateManifest(opts: { relativePath: string; format?: 'esm' | 'cjs' }): string;
26
- }): MaybePromise<void>;
24
+ complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise<void>;
27
25
  }
28
26
 
29
27
  // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts