@sveltejs/kit 1.0.0-next.262 → 1.0.0-next.263

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.
@@ -7,12 +7,12 @@ function to_headers(object) {
7
7
  const value = object[key];
8
8
  if (!value) continue;
9
9
 
10
- if (typeof value === 'string') {
11
- headers.set(key, value);
12
- } else {
10
+ if (Array.isArray(value)) {
13
11
  value.forEach((value) => {
14
- headers.append(key, value);
12
+ headers.append(key, /** @type {string} */ (value));
15
13
  });
14
+ } else {
15
+ headers.set(key, /** @type {string} */ (value));
16
16
  }
17
17
  }
18
18
  }
@@ -38,6 +38,16 @@ function hash(value) {
38
38
  }
39
39
 
40
40
  /** @param {Record<string, any>} obj */
41
+ function lowercase_keys(obj) {
42
+ /** @type {Record<string, any>} */
43
+ const clone = {};
44
+
45
+ for (const key in obj) {
46
+ clone[key.toLowerCase()] = obj[key];
47
+ }
48
+
49
+ return clone;
50
+ }
41
51
 
42
52
  /** @param {Record<string, string>} params */
43
53
  function decode_params(params) {
@@ -475,6 +485,16 @@ function coalesce_to_error(err) {
475
485
 
476
486
  /** @type {Record<string, string>} */
477
487
  const escape_json_in_html_dict = {
488
+ '&': '\\u0026',
489
+ '>': '\\u003e',
490
+ '<': '\\u003c',
491
+ '\u2028': '\\u2028',
492
+ '\u2029': '\\u2029'
493
+ };
494
+
495
+ /** @type {Record<string, string>} */
496
+ const escape_json_value_in_html_dict = {
497
+ '"': '\\"',
478
498
  '<': '\\u003C',
479
499
  '>': '\\u003E',
480
500
  '/': '\\u002F',
@@ -489,53 +509,30 @@ const escape_json_in_html_dict = {
489
509
  '\u2029': '\\u2029'
490
510
  };
491
511
 
492
- /** @type {Record<string, string>} */
493
- const escape_json_string_in_html_dict = {
494
- '"': '\\"',
495
- ...escape_json_in_html_dict
496
- };
497
-
498
512
  /**
499
513
  * Escape a stringified JSON object that's going to be embedded in a `<script>` tag
500
514
  * @param {string} str
501
515
  */
502
516
  function escape_json_in_html(str) {
503
- return escape(str, escape_json_in_html_dict, (code) => `\\u${code.toString(16).toUpperCase()}`);
517
+ // adapted from https://github.com/vercel/next.js/blob/694407450638b037673c6d714bfe4126aeded740/packages/next/server/htmlescape.ts
518
+ // based on https://github.com/zertosh/htmlescape
519
+ // License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
520
+ return str.replace(/[&><\u2028\u2029]/g, (match) => escape_json_in_html_dict[match]);
504
521
  }
505
522
 
506
523
  /**
507
524
  * Escape a string JSON value to be embedded into a `<script>` tag
508
525
  * @param {string} str
509
526
  */
510
- function escape_json_string_in_html(str) {
527
+ function escape_json_value_in_html(str) {
511
528
  return escape(
512
529
  str,
513
- escape_json_string_in_html_dict,
530
+ escape_json_value_in_html_dict,
514
531
  (code) => `\\u${code.toString(16).toUpperCase()}`
515
532
  );
516
533
  }
517
534
 
518
- /** @type {Record<string, string>} */
519
- const escape_html_attr_dict = {
520
- '<': '&lt;',
521
- '>': '&gt;',
522
- '"': '&quot;'
523
- };
524
-
525
535
  /**
526
- * use for escaping string values to be used html attributes on the page
527
- * e.g.
528
- * <script data-url="here">
529
- *
530
- * @param {string} str
531
- * @returns string escaped string
532
- */
533
- function escape_html_attr(str) {
534
- return '"' + escape(str, escape_html_attr_dict, (code) => `&#${code};`) + '"';
535
- }
536
-
537
- /**
538
- *
539
536
  * @param str {string} string to escape
540
537
  * @param dict {Record<string, string>} dictionary of character replacements
541
538
  * @param unicode_encoder {function(number): string} encoder to use for high unicode characters
@@ -568,6 +565,25 @@ function escape(str, dict, unicode_encoder) {
568
565
  return result;
569
566
  }
570
567
 
568
+ /** @type {Record<string, string>} */
569
+ const escape_html_attr_dict = {
570
+ '<': '&lt;',
571
+ '>': '&gt;',
572
+ '"': '&quot;'
573
+ };
574
+
575
+ /**
576
+ * use for escaping string values to be used html attributes on the page
577
+ * e.g.
578
+ * <script data-url="here">
579
+ *
580
+ * @param {string} str
581
+ * @returns string escaped string
582
+ */
583
+ function escape_html_attr(str) {
584
+ return '"' + escape(str, escape_html_attr_dict, (code) => `&#${code};`) + '"';
585
+ }
586
+
571
587
  const s = JSON.stringify;
572
588
 
573
589
  /** @param {URL} url */
@@ -1730,7 +1746,7 @@ async function load_node({
1730
1746
  fetched.push({
1731
1747
  url: requested,
1732
1748
  body: /** @type {string} */ (opts.body),
1733
- json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_string_in_html(body)}"}`
1749
+ json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_value_in_html(body)}"}`
1734
1750
  });
1735
1751
  }
1736
1752
 
@@ -1870,13 +1886,8 @@ async function load_shadow_data(route, event, prerender) {
1870
1886
 
1871
1887
  if (result.fallthrough) return result;
1872
1888
 
1873
- const { status = 200, headers = {}, body = {} } = result;
1874
-
1875
- validate_shadow_output(headers, body);
1876
-
1877
- if (headers['set-cookie']) {
1878
- /** @type {string[]} */ (data.cookies).push(...headers['set-cookie']);
1879
- }
1889
+ const { status, headers, body } = validate_shadow_output(result);
1890
+ add_cookies(/** @type {string[]} */ (data.cookies), headers);
1880
1891
 
1881
1892
  // Redirects are respected...
1882
1893
  if (status >= 300 && status < 400) {
@@ -1900,13 +1911,8 @@ async function load_shadow_data(route, event, prerender) {
1900
1911
 
1901
1912
  if (result.fallthrough) return result;
1902
1913
 
1903
- const { status = 200, headers = {}, body = {} } = result;
1904
-
1905
- validate_shadow_output(headers, body);
1906
-
1907
- if (headers['set-cookie']) {
1908
- /** @type {string[]} */ (data.cookies).push(...headers['set-cookie']);
1909
- }
1914
+ const { status, headers, body } = validate_shadow_output(result);
1915
+ add_cookies(/** @type {string[]} */ (data.cookies), headers);
1910
1916
 
1911
1917
  if (status >= 400) {
1912
1918
  return {
@@ -1937,19 +1943,42 @@ async function load_shadow_data(route, event, prerender) {
1937
1943
  }
1938
1944
 
1939
1945
  /**
1940
- * @param {Headers | Partial<import('types/helper').ResponseHeaders>} headers
1941
- * @param {import('types/helper').JSONValue} body
1946
+ * @param {string[]} target
1947
+ * @param {Partial<import('types/helper').ResponseHeaders>} headers
1942
1948
  */
1943
- function validate_shadow_output(headers, body) {
1944
- if (headers instanceof Headers && headers.has('set-cookie')) {
1945
- throw new Error(
1946
- 'Shadow endpoint request handler cannot use Headers interface with Set-Cookie headers'
1947
- );
1949
+ function add_cookies(target, headers) {
1950
+ const cookies = headers['set-cookie'];
1951
+ if (cookies) {
1952
+ if (Array.isArray(cookies)) {
1953
+ target.push(...cookies);
1954
+ } else {
1955
+ target.push(/** @type {string} */ (cookies));
1956
+ }
1957
+ }
1958
+ }
1959
+
1960
+ /**
1961
+ * @param {import('types/endpoint').ShadowEndpointOutput} result
1962
+ */
1963
+ function validate_shadow_output(result) {
1964
+ const { status = 200, body = {} } = result;
1965
+ let headers = result.headers || {};
1966
+
1967
+ if (headers instanceof Headers) {
1968
+ if (headers.has('set-cookie')) {
1969
+ throw new Error(
1970
+ 'Shadow endpoint request handler cannot use Headers interface with Set-Cookie headers'
1971
+ );
1972
+ }
1973
+ } else {
1974
+ headers = lowercase_keys(/** @type {Record<string, string>} */ (headers));
1948
1975
  }
1949
1976
 
1950
1977
  if (!is_pojo(body)) {
1951
1978
  throw new Error('Body returned from shadow endpoint request handler must be a plain object');
1952
1979
  }
1980
+
1981
+ return { status, headers, body };
1953
1982
  }
1954
1983
 
1955
1984
  /**
@@ -333,27 +333,7 @@ function crawl(html) {
333
333
 
334
334
  /** @type {Record<string, string>} */
335
335
 
336
- /** @type {Record<string, string>} */
337
- const escape_html_attr_dict = {
338
- '<': '&lt;',
339
- '>': '&gt;',
340
- '"': '&quot;'
341
- };
342
-
343
- /**
344
- * use for escaping string values to be used html attributes on the page
345
- * e.g.
346
- * <script data-url="here">
347
- *
348
- * @param {string} str
349
- * @returns string escaped string
350
- */
351
- function escape_html_attr(str) {
352
- return '"' + escape(str, escape_html_attr_dict, (code) => `&#${code};`) + '"';
353
- }
354
-
355
336
  /**
356
- *
357
337
  * @param str {string} string to escape
358
338
  * @param dict {Record<string, string>} dictionary of character replacements
359
339
  * @param unicode_encoder {function(number): string} encoder to use for high unicode characters
@@ -386,6 +366,25 @@ function escape(str, dict, unicode_encoder) {
386
366
  return result;
387
367
  }
388
368
 
369
+ /** @type {Record<string, string>} */
370
+ const escape_html_attr_dict = {
371
+ '<': '&lt;',
372
+ '>': '&gt;',
373
+ '"': '&quot;'
374
+ };
375
+
376
+ /**
377
+ * use for escaping string values to be used html attributes on the page
378
+ * e.g.
379
+ * <script data-url="here">
380
+ *
381
+ * @param {string} str
382
+ * @returns string escaped string
383
+ */
384
+ function escape_html_attr(str) {
385
+ return '"' + escape(str, escape_html_attr_dict, (code) => `&#${code};`) + '"';
386
+ }
387
+
389
388
  /**
390
389
  * @typedef {import('types/config').PrerenderErrorHandler} PrerenderErrorHandler
391
390
  * @typedef {import('types/config').PrerenderOnErrorValue} OnError
package/dist/cli.js CHANGED
@@ -995,7 +995,7 @@ async function launch(port, https) {
995
995
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
996
996
  }
997
997
 
998
- const prog = sade('svelte-kit').version('1.0.0-next.262');
998
+ const prog = sade('svelte-kit').version('1.0.0-next.263');
999
999
 
1000
1000
  prog
1001
1001
  .command('dev')
@@ -1153,7 +1153,7 @@ async function check_port(port) {
1153
1153
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1154
1154
  if (open) launch(port, https);
1155
1155
 
1156
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.262'}\n`));
1156
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.263'}\n`));
1157
1157
 
1158
1158
  const protocol = https ? 'https:' : 'http:';
1159
1159
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.262",
3
+ "version": "1.0.0-next.263",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
package/types/helper.d.ts CHANGED
@@ -4,7 +4,7 @@ export type JSONObject = { [key: string]: JSONValue };
4
4
  export type JSONValue = string | number | boolean | null | ToJSON | JSONValue[] | JSONObject;
5
5
 
6
6
  /** `string[]` is only for set-cookie, everything else must be type of `string` */
7
- export type ResponseHeaders = Record<string, string | string[]>;
7
+ export type ResponseHeaders = Record<string, string | number | string[]>;
8
8
 
9
9
  // <-- Utility Types -->
10
10
  type Only<T, U> = { [P in keyof T]: T[P] } & { [P in Exclude<keyof U, keyof T>]?: never };