@sveltejs/kit 1.0.0-next.239 → 1.0.0-next.242

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.
@@ -1710,7 +1710,7 @@ async function respond(request, options, state = {}) {
1710
1710
  let ssr = true;
1711
1711
 
1712
1712
  try {
1713
- return await options.hooks.handle({
1713
+ const response = await options.hooks.handle({
1714
1714
  event,
1715
1715
  resolve: async (event, opts) => {
1716
1716
  if (opts && 'ssr' in opts) ssr = /** @type {boolean} */ (opts.ssr);
@@ -1806,6 +1806,13 @@ async function respond(request, options, state = {}) {
1806
1806
  throw new Error('request in handle has been replaced with event' + details);
1807
1807
  }
1808
1808
  });
1809
+
1810
+ // TODO for 1.0, change the error message to point to docs rather than PR
1811
+ if (response && !(response instanceof Response)) {
1812
+ throw new Error('handle must return a Response object' + details);
1813
+ }
1814
+
1815
+ return response;
1809
1816
  } catch (/** @type {unknown} */ e) {
1810
1817
  const error = coalesce_to_error(e);
1811
1818
 
@@ -655,26 +655,4 @@ function sirv (dir, opts={}) {
655
655
  };
656
656
  }
657
657
 
658
- /** @param {Partial<import('types/helper').ResponseHeaders> | undefined} object */
659
- function to_headers(object) {
660
- const headers = new Headers();
661
-
662
- if (object) {
663
- for (const key in object) {
664
- const value = object[key];
665
- if (!value) continue;
666
-
667
- if (typeof value === 'string') {
668
- headers.set(key, value);
669
- } else {
670
- value.forEach((value) => {
671
- headers.append(key, value);
672
- });
673
- }
674
- }
675
- }
676
-
677
- return headers;
678
- }
679
-
680
- export { sirv as s, to_headers as t };
658
+ export { sirv as s };
@@ -5,11 +5,11 @@ import { c as create_manifest_data, a as create_app, d as deep_merge } from './i
5
5
  import { c as coalesce_to_error, S as SVELTE_KIT_ASSETS, r as resolve_entry, $, a as SVELTE_KIT, b as runtime, l as load_template, g as get_mime_lookup, d as copy_assets, e as get_aliases, p as print_config_conflicts } from '../cli.js';
6
6
  import fs__default from 'fs';
7
7
  import { URL as URL$1 } from 'url';
8
- import { t as to_headers, s as sirv } from './http.js';
8
+ import { s as sirv } from './build.js';
9
9
  import { e as escape_html_attr, r as resolve, i as is_root_relative, a as escape_json_string_in_html } from './url.js';
10
10
  import { s } from './misc.js';
11
11
  import { __fetch_polyfill } from '../install-fetch.js';
12
- import { getRawBody, setResponse } from '../node.js';
12
+ import { getRequest, setResponse } from '../node.js';
13
13
  import 'sade';
14
14
  import 'child_process';
15
15
  import 'net';
@@ -23,6 +23,28 @@ import 'node:util';
23
23
  import 'node:url';
24
24
  import 'stream';
25
25
 
26
+ /** @param {Partial<import('types/helper').ResponseHeaders> | undefined} object */
27
+ function to_headers(object) {
28
+ const headers = new Headers();
29
+
30
+ if (object) {
31
+ for (const key in object) {
32
+ const value = object[key];
33
+ if (!value) continue;
34
+
35
+ if (typeof value === 'string') {
36
+ headers.set(key, value);
37
+ } else {
38
+ value.forEach((value) => {
39
+ headers.append(key, value);
40
+ });
41
+ }
42
+ }
43
+ }
44
+
45
+ return headers;
46
+ }
47
+
26
48
  /**
27
49
  * Hash using djb2
28
50
  * @param {import('types/hooks').StrictBody} value
@@ -1582,7 +1604,7 @@ async function respond(request, options, state = {}) {
1582
1604
  let ssr = true;
1583
1605
 
1584
1606
  try {
1585
- return await options.hooks.handle({
1607
+ const response = await options.hooks.handle({
1586
1608
  event,
1587
1609
  resolve: async (event, opts) => {
1588
1610
  if (opts && 'ssr' in opts) ssr = /** @type {boolean} */ (opts.ssr);
@@ -1678,6 +1700,13 @@ async function respond(request, options, state = {}) {
1678
1700
  throw new Error('request in handle has been replaced with event' + details);
1679
1701
  }
1680
1702
  });
1703
+
1704
+ // TODO for 1.0, change the error message to point to docs rather than PR
1705
+ if (response && !(response instanceof Response)) {
1706
+ throw new Error('handle must return a Response object' + details);
1707
+ }
1708
+
1709
+ return response;
1681
1710
  } catch (/** @type {unknown} */ e) {
1682
1711
  const error = coalesce_to_error(e);
1683
1712
 
@@ -1834,11 +1863,9 @@ async function create_plugin(config, cwd) {
1834
1863
  if (!req.url || !req.method) throw new Error('Incomplete request');
1835
1864
  if (req.url === '/favicon.ico') return not_found(res);
1836
1865
 
1837
- const url = new URL$1(
1838
- `${vite.config.server.https ? 'https' : 'http'}://${req.headers.host}${req.url}`
1839
- );
1866
+ const base = `${vite.config.server.https ? 'https' : 'http'}://${req.headers.host}`;
1840
1867
 
1841
- const decoded = decodeURI(url.pathname);
1868
+ const decoded = decodeURI(new URL$1(base + req.url).pathname);
1842
1869
 
1843
1870
  if (decoded.startsWith(assets)) {
1844
1871
  const pathname = decoded.slice(assets.length);
@@ -1898,75 +1925,70 @@ async function create_plugin(config, cwd) {
1898
1925
  assets
1899
1926
  });
1900
1927
 
1901
- let body;
1928
+ let request;
1902
1929
 
1903
1930
  try {
1904
- body = await getRawBody(req);
1931
+ request = await getRequest(base, req);
1905
1932
  } catch (/** @type {any} */ err) {
1906
1933
  res.statusCode = err.status || 400;
1907
1934
  return res.end(err.reason || 'Invalid request body');
1908
1935
  }
1909
1936
 
1910
- const rendered = await respond(
1911
- new Request(url.href, {
1912
- headers: /** @type {Record<string, string>} */ (req.headers),
1913
- method: req.method,
1914
- body
1915
- }),
1916
- {
1917
- amp: config.kit.amp,
1918
- dev: true,
1919
- floc: config.kit.floc,
1920
- get_stack: (error) => {
1921
- vite.ssrFixStacktrace(error);
1922
- return error.stack;
1923
- },
1924
- handle_error: (error, event) => {
1925
- vite.ssrFixStacktrace(error);
1926
- hooks.handleError({
1927
- error,
1928
- event,
1929
-
1930
- // TODO remove for 1.0
1931
- // @ts-expect-error
1932
- get request() {
1933
- throw new Error(
1934
- 'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
1935
- );
1936
- }
1937
- });
1938
- },
1939
- hooks,
1940
- hydrate: config.kit.hydrate,
1941
- manifest,
1942
- method_override: config.kit.methodOverride,
1943
- paths: {
1944
- base: config.kit.paths.base,
1945
- assets
1946
- },
1947
- prefix: '',
1948
- prerender: config.kit.prerender.enabled,
1949
- read: (file) => fs__default.readFileSync(path__default.join(config.kit.files.assets, file)),
1950
- root,
1951
- router: config.kit.router,
1952
- target: config.kit.target,
1953
- template: ({ head, body, assets }) => {
1954
- let rendered = load_template(cwd, config)
1955
- .replace('%svelte.head%', () => head)
1956
- .replace('%svelte.body%', () => body)
1957
- .replace(/%svelte\.assets%/g, assets);
1958
-
1959
- if (amp) {
1960
- const result = amp.validateString(rendered);
1961
-
1962
- if (result.status !== 'PASS') {
1963
- const lines = rendered.split('\n');
1964
-
1965
- /** @param {string} str */
1966
- const escape = (str) =>
1967
- str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1968
-
1969
- rendered = `<!doctype html>
1937
+ const rendered = await respond(request, {
1938
+ amp: config.kit.amp,
1939
+ dev: true,
1940
+ floc: config.kit.floc,
1941
+ get_stack: (error) => {
1942
+ vite.ssrFixStacktrace(error);
1943
+ return error.stack;
1944
+ },
1945
+ handle_error: (error, event) => {
1946
+ vite.ssrFixStacktrace(error);
1947
+ hooks.handleError({
1948
+ error,
1949
+ event,
1950
+
1951
+ // TODO remove for 1.0
1952
+ // @ts-expect-error
1953
+ get request() {
1954
+ throw new Error(
1955
+ 'request in handleError has been replaced with event. See https://github.com/sveltejs/kit/pull/3384 for details'
1956
+ );
1957
+ }
1958
+ });
1959
+ },
1960
+ hooks,
1961
+ hydrate: config.kit.hydrate,
1962
+ manifest,
1963
+ method_override: config.kit.methodOverride,
1964
+ paths: {
1965
+ base: config.kit.paths.base,
1966
+ assets
1967
+ },
1968
+ prefix: '',
1969
+ prerender: config.kit.prerender.enabled,
1970
+ read: (file) => fs__default.readFileSync(path__default.join(config.kit.files.assets, file)),
1971
+ root,
1972
+ router: config.kit.router,
1973
+ target: config.kit.target,
1974
+ template: ({ head, body, assets }) => {
1975
+ let rendered = load_template(cwd, config)
1976
+ .replace(/%svelte\.assets%/g, assets)
1977
+ // head and body must be replaced last, in case someone tries to sneak in %svelte.assets% etc
1978
+ .replace('%svelte.head%', () => head)
1979
+ .replace('%svelte.body%', () => body);
1980
+
1981
+ if (amp) {
1982
+ const result = amp.validateString(rendered);
1983
+
1984
+ if (result.status !== 'PASS') {
1985
+ const lines = rendered.split('\n');
1986
+
1987
+ /** @param {string} str */
1988
+ const escape = (str) =>
1989
+ str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1990
+
1991
+ rendered = `<!doctype html>
1970
1992
  <head>
1971
1993
  <meta charset="utf-8" />
1972
1994
  <meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -1997,14 +2019,13 @@ async function create_plugin(config, cwd) {
1997
2019
  )
1998
2020
  .join('\n\n')}
1999
2021
  `;
2000
- }
2001
2022
  }
2023
+ }
2002
2024
 
2003
- return rendered;
2004
- },
2005
- trailing_slash: config.kit.trailingSlash
2006
- }
2007
- );
2025
+ return rendered;
2026
+ },
2027
+ trailing_slash: config.kit.trailingSlash
2028
+ });
2008
2029
 
2009
2030
  if (rendered) {
2010
2031
  setResponse(res, rendered);
@@ -414,8 +414,11 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
414
414
  async function visit(path, decoded_path, referrer) {
415
415
  /** @type {Map<string, Response>} */
416
416
  const dependencies = new Map();
417
+ const render_path = config.kit.paths?.base
418
+ ? `http://sveltekit-prerender${config.kit.paths.base}${path === '/' ? '' : path}`
419
+ : `http://sveltekit-prerender${path}`;
417
420
 
418
- const rendered = await app.render(new Request(`http://sveltekit-prerender${path}`), {
421
+ const rendered = await app.render(new Request(render_path), {
419
422
  prerender: {
420
423
  all,
421
424
  dependencies
@@ -2,9 +2,9 @@ import fs__default from 'fs';
2
2
  import http from 'http';
3
3
  import https from 'https';
4
4
  import { resolve, join } from 'path';
5
- import { s as sirv, t as to_headers } from './http.js';
5
+ import { s as sirv } from './build.js';
6
6
  import { pathToFileURL } from 'url';
7
- import { getRawBody } from '../node.js';
7
+ import { getRequest, setResponse } from '../node.js';
8
8
  import { __fetch_polyfill } from '../install-fetch.js';
9
9
  import { a as SVELTE_KIT, S as SVELTE_KIT_ASSETS } from '../cli.js';
10
10
  import 'querystring';
@@ -91,32 +91,21 @@ async function preview({
91
91
  const initial_url = req.url;
92
92
 
93
93
  const render_handler = async () => {
94
- if (!req.method) throw new Error('Incomplete request');
95
-
96
- let body;
97
-
98
- try {
99
- body = await getRawBody(req);
100
- } catch (/** @type {any} */ err) {
101
- res.statusCode = err.status || 400;
102
- return res.end(err.reason || 'Invalid request body');
103
- }
104
-
105
94
  if (initial_url.startsWith(config.kit.paths.base)) {
106
95
  const protocol = use_https ? 'https' : 'http';
107
96
  const host = req.headers['host'];
108
97
 
109
- const rendered = await app.render(
110
- new Request(`${protocol}://${host}${initial_url}`, {
111
- method: req.method,
112
- headers: to_headers(req.headers),
113
- body
114
- })
115
- );
116
-
117
- res.writeHead(rendered.status, Object.fromEntries(rendered.headers));
118
- if (rendered.body) res.write(new Uint8Array(await rendered.arrayBuffer()));
119
- res.end();
98
+ let request;
99
+
100
+ try {
101
+ req.url = initial_url;
102
+ request = await getRequest(`${protocol}://${host}`, req);
103
+ } catch (/** @type {any} */ err) {
104
+ res.statusCode = err.status || 400;
105
+ return res.end(err.reason || 'Invalid request body');
106
+ }
107
+
108
+ setResponse(res, await app.render(request));
120
109
  } else {
121
110
  res.statusCode = 404;
122
111
  res.end('Not found');
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { createRequire } from 'module';
4
- import { h as rimraf, w as walk$1, $, m as mkdirp } from '../cli.js';
4
+ import { h as rimraf, m as mkdirp, w as walk$1, $ } from '../cli.js';
5
5
  import 'sade';
6
6
  import 'child_process';
7
7
  import 'net';
@@ -15257,6 +15257,7 @@ async function make_package(config, cwd = process.cwd()) {
15257
15257
  const package_dir = config.kit.package.dir;
15258
15258
  const abs_package_dir = path.isAbsolute(package_dir) ? package_dir : path.join(cwd, package_dir);
15259
15259
  rimraf(abs_package_dir);
15260
+ mkdirp(abs_package_dir); // TODO https://github.com/sveltejs/kit/issues/2333
15260
15261
 
15261
15262
  if (config.kit.package.emitTypes) {
15262
15263
  // Generate type definitions first so hand-written types can overwrite generated ones
@@ -15304,25 +15305,28 @@ async function make_package(config, cwd = process.cwd()) {
15304
15305
  }
15305
15306
 
15306
15307
  const filename = path.join(config.kit.files.lib, file);
15307
- const source = fs.readFileSync(filename, 'utf8');
15308
+ const source = fs.readFileSync(filename);
15308
15309
 
15309
15310
  /** @type {string} */
15310
15311
  let out_file;
15311
15312
 
15312
- /** @type {string} */
15313
+ /** @type {string | Buffer} */
15313
15314
  let out_contents;
15314
15315
 
15315
15316
  if (svelte_ext) {
15316
15317
  // it's a Svelte component
15318
+ contains_svelte_files = true;
15317
15319
  out_file = file.slice(0, -svelte_ext.length) + '.svelte';
15320
+ out_contents = source.toString('utf-8');
15318
15321
  out_contents = config.preprocess
15319
- ? strip_lang_tags((await preprocess(source, config.preprocess, { filename })).code)
15320
- : source;
15321
- contains_svelte_files = true;
15322
+ ? strip_lang_tags((await preprocess(out_contents, config.preprocess, { filename })).code)
15323
+ : out_contents;
15324
+ out_contents = resolve_$lib_alias(out_file, out_contents, config);
15322
15325
  } else if (ext === '.ts' && file.endsWith('.d.ts')) {
15323
15326
  // TypeScript's declaration emit won't copy over the d.ts files, so we do it here
15324
15327
  out_file = file;
15325
- out_contents = source;
15328
+ out_contents = source.toString('utf-8');
15329
+ out_contents = resolve_$lib_alias(out_file, out_contents, config);
15326
15330
  if (fs.existsSync(path.join(abs_package_dir, out_file))) {
15327
15331
  console.warn(
15328
15332
  'Found already existing file from d.ts generation for ' +
@@ -15332,12 +15336,12 @@ async function make_package(config, cwd = process.cwd()) {
15332
15336
  }
15333
15337
  } else if (ext === '.ts') {
15334
15338
  out_file = file.slice(0, -'.ts'.length) + '.js';
15335
- out_contents = await transpile_ts(filename, source);
15339
+ out_contents = await transpile_ts(filename, source.toString('utf-8'));
15340
+ out_contents = resolve_$lib_alias(out_file, out_contents, config);
15336
15341
  } else {
15337
15342
  out_file = file;
15338
15343
  out_contents = source;
15339
15344
  }
15340
- out_contents = resolve_$lib_alias(out_file, out_contents, config);
15341
15345
 
15342
15346
  write(path.join(abs_package_dir, out_file), out_contents);
15343
15347
 
@@ -15529,7 +15533,7 @@ function load_tsconfig(filename, ts) {
15529
15533
 
15530
15534
  /**
15531
15535
  * @param {string} file
15532
- * @param {string} contents
15536
+ * @param {Parameters<typeof fs.writeFileSync>[1]} contents
15533
15537
  */
15534
15538
  function write(file, contents) {
15535
15539
  mkdirp(path.dirname(file));
package/dist/cli.js CHANGED
@@ -933,7 +933,7 @@ async function launch(port, https) {
933
933
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
934
934
  }
935
935
 
936
- const prog = sade('svelte-kit').version('1.0.0-next.239');
936
+ const prog = sade('svelte-kit').version('1.0.0-next.242');
937
937
 
938
938
  prog
939
939
  .command('dev')
@@ -1085,7 +1085,7 @@ async function check_port(port) {
1085
1085
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1086
1086
  if (open) launch(port, https);
1087
1087
 
1088
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.239'}\n`));
1088
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.242'}\n`));
1089
1089
 
1090
1090
  const protocol = https ? 'https:' : 'http:';
1091
1091
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
package/dist/node.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Readable } from 'stream';
2
2
 
3
3
  /** @type {import('@sveltejs/kit/node').GetRawBody} */
4
- function getRawBody(req) {
4
+ function get_raw_body(req) {
5
5
  return new Promise((fulfil, reject) => {
6
6
  const h = req.headers;
7
7
 
@@ -55,13 +55,21 @@ async function getRequest(base, req) {
55
55
  return new Request(base + req.url, {
56
56
  method: req.method,
57
57
  headers: /** @type {Record<string, string>} */ (req.headers),
58
- body: await getRawBody(req)
58
+ body: await get_raw_body(req) // TODO stream rather than buffer
59
59
  });
60
60
  }
61
61
 
62
62
  /** @type {import('@sveltejs/kit/node').SetResponse} */
63
63
  async function setResponse(res, response) {
64
- res.writeHead(response.status, Object.fromEntries(response.headers));
64
+ /** @type {import('../types/helper').ResponseHeaders} */
65
+ const headers = Object.fromEntries(response.headers);
66
+
67
+ if (response.headers.has('set-cookie')) {
68
+ // @ts-expect-error (headers.raw() is non-standard)
69
+ headers['set-cookie'] = response.headers.raw()['set-cookie'];
70
+ }
71
+
72
+ res.writeHead(response.status, headers);
65
73
 
66
74
  if (response.body instanceof Readable) {
67
75
  response.body.pipe(res);
@@ -74,4 +82,4 @@ async function setResponse(res, response) {
74
82
  }
75
83
  }
76
84
 
77
- export { getRawBody, getRequest, setResponse };
85
+ export { getRequest, setResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.239",
3
+ "version": "1.0.0-next.242",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -3,16 +3,18 @@ import { Either, JSONString, MaybePromise, ResponseHeaders } from './helper';
3
3
 
4
4
  type Body = JSONString | Uint8Array | ReadableStream | import('stream').Readable;
5
5
 
6
- export interface EndpointOutput {
6
+ export interface EndpointOutput<Output extends Body = Body> {
7
7
  status?: number;
8
8
  headers?: Headers | Partial<ResponseHeaders>;
9
- body?: Body;
9
+ body?: Output;
10
10
  }
11
11
 
12
12
  export interface Fallthrough {
13
13
  fallthrough: true;
14
14
  }
15
15
 
16
- export interface RequestHandler<Locals = Record<string, any>> {
17
- (event: RequestEvent<Locals>): MaybePromise<Either<Response | EndpointOutput, Fallthrough>>;
16
+ export interface RequestHandler<Locals = Record<string, any>, Output extends Body = Body> {
17
+ (event: RequestEvent<Locals>): MaybePromise<
18
+ Either<Response | EndpointOutput<Output>, Fallthrough>
19
+ >;
18
20
  }