@sveltejs/kit 1.0.0-next.245 → 1.0.0-next.249

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.
@@ -1546,7 +1546,7 @@ async function load_node({
1546
1546
  // handle fetch requests for static assets. e.g. prebaked data, etc.
1547
1547
  // we need to support everything the browser's fetch supports
1548
1548
  const prefix = options.paths.assets || options.paths.base;
1549
- const filename = (
1549
+ const filename = decodeURIComponent(
1550
1550
  resolved.startsWith(prefix) ? resolved.slice(prefix.length) : resolved
1551
1551
  ).slice(1);
1552
1552
  const filename_html = `${filename}/index.html`; // path may also match path/index.html
@@ -0,0 +1,56 @@
1
+ /** @type {import('amphtml-validator').Validator} */
2
+ const amp = await (await import('./index8.js').then(function (n) { return n.i; })).getInstance();
3
+
4
+ /** @type {import('types/hooks').Handle} */
5
+ async function handle({ event, resolve }) {
6
+ const response = await resolve(event);
7
+ if (response.headers.get('content-type') !== 'text/html') {
8
+ return response;
9
+ }
10
+
11
+ let rendered = await response.text();
12
+ const result = amp.validateString(rendered);
13
+
14
+ if (result.status !== 'PASS') {
15
+ const lines = rendered.split('\n');
16
+
17
+ /** @param {string} str */
18
+ const escape = (str) => str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
19
+
20
+ rendered = `<!doctype html>
21
+ <head>
22
+ <meta charset="utf-8" />
23
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
24
+ <style>
25
+ body {
26
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
27
+ color: #333;
28
+ }
29
+
30
+ pre {
31
+ background: #f4f4f4;
32
+ padding: 1em;
33
+ overflow-x: auto;
34
+ }
35
+ </style>
36
+ </head>
37
+ <h1>AMP validation failed</h1>
38
+
39
+ ${result.errors
40
+ .map(
41
+ (error) => `
42
+ <h2>${error.severity}</h2>
43
+ <p>Line ${error.line}, column ${error.col}: ${error.message} (<a href="${error.specUrl}">${
44
+ error.code
45
+ }</a>)</p>
46
+ <pre>${escape(lines[error.line - 1])}</pre>
47
+ `
48
+ )
49
+ .join('\n\n')}
50
+ `;
51
+ }
52
+
53
+ return new Response(rendered, { status: response.status, headers: response.headers });
54
+ }
55
+
56
+ export { handle };
@@ -10,6 +10,7 @@ import { e as escape_html_attr, r as resolve, i as is_root_relative, a as escape
10
10
  import { s } from './misc.js';
11
11
  import { __fetch_polyfill } from '../install-fetch.js';
12
12
  import { getRequest, setResponse } from '../node.js';
13
+ import { sequence } from '../hooks.js';
13
14
  import 'sade';
14
15
  import 'child_process';
15
16
  import 'net';
@@ -1440,7 +1441,7 @@ async function load_node({
1440
1441
  // handle fetch requests for static assets. e.g. prebaked data, etc.
1441
1442
  // we need to support everything the browser's fetch supports
1442
1443
  const prefix = options.paths.assets || options.paths.base;
1443
- const filename = (
1444
+ const filename = decodeURIComponent(
1444
1445
  resolved.startsWith(prefix) ? resolved.slice(prefix.length) : resolved
1445
1446
  ).slice(1);
1446
1447
  const filename_html = `${filename}/index.html`; // path may also match path/index.html
@@ -2262,12 +2263,12 @@ async function respond(request, options, state = {}) {
2262
2263
  * @returns {Promise<import('vite').Plugin>}
2263
2264
  */
2264
2265
  async function create_plugin(config, cwd) {
2265
- /** @type {import('amphtml-validator').Validator} */
2266
+ /** @type {import('types/hooks').Handle} */
2266
2267
  let amp;
2267
2268
 
2268
2269
  if (config.kit.amp) {
2269
2270
  process.env.VITE_SVELTEKIT_AMP = 'true';
2270
- amp = await (await import('./index8.js').then(function (n) { return n.i; })).getInstance();
2271
+ amp = (await import('./amp_hook.js')).handle;
2271
2272
  }
2272
2273
 
2273
2274
  return {
@@ -2409,10 +2410,12 @@ async function create_plugin(config, cwd) {
2409
2410
  ? await vite.ssrLoadModule(`/${config.kit.files.hooks}`)
2410
2411
  : {};
2411
2412
 
2413
+ const handle = user_hooks.handle || (({ event, resolve }) => resolve(event));
2414
+
2412
2415
  /** @type {import('types/internal').Hooks} */
2413
2416
  const hooks = {
2414
2417
  getSession: user_hooks.getSession || (() => ({})),
2415
- handle: user_hooks.handle || (({ event, resolve }) => resolve(event)),
2418
+ handle: amp ? sequence(amp, handle) : handle,
2416
2419
  handleError:
2417
2420
  user_hooks.handleError ||
2418
2421
  (({ /** @type {Error & { frame?: string }} */ error }) => {
@@ -2499,58 +2502,14 @@ async function create_plugin(config, cwd) {
2499
2502
  router: config.kit.router,
2500
2503
  target: config.kit.target,
2501
2504
  template: ({ head, body, assets, nonce }) => {
2502
- let rendered = template
2503
- .replace(/%svelte\.assets%/g, assets)
2504
- .replace(/%svelte\.nonce%/g, nonce)
2505
- // head and body must be replaced last, in case someone tries to sneak in %svelte.assets% etc
2506
- .replace('%svelte.head%', () => head)
2507
- .replace('%svelte.body%', () => body);
2508
-
2509
- if (amp) {
2510
- const result = amp.validateString(rendered);
2511
-
2512
- if (result.status !== 'PASS') {
2513
- const lines = rendered.split('\n');
2514
-
2515
- /** @param {string} str */
2516
- const escape = (str) =>
2517
- str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
2518
-
2519
- rendered = `<!doctype html>
2520
- <head>
2521
- <meta charset="utf-8" />
2522
- <meta name="viewport" content="width=device-width, initial-scale=1" />
2523
- <style>
2524
- body {
2525
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
2526
- color: #333;
2527
- }
2528
-
2529
- pre {
2530
- background: #f4f4f4;
2531
- padding: 1em;
2532
- overflow-x: auto;
2533
- }
2534
- </style>
2535
- </head>
2536
- <h1>AMP validation failed</h1>
2537
-
2538
- ${result.errors
2539
- .map(
2540
- (error) => `
2541
- <h2>${error.severity}</h2>
2542
- <p>Line ${error.line}, column ${error.col}: ${error.message} (<a href="${error.specUrl}">${
2543
- error.code
2544
- }</a>)</p>
2545
- <pre>${escape(lines[error.line - 1])}</pre>
2546
- `
2547
- )
2548
- .join('\n\n')}
2549
- `;
2550
- }
2551
- }
2552
-
2553
- return rendered;
2505
+ return (
2506
+ template
2507
+ .replace(/%svelte\.assets%/g, assets)
2508
+ .replace(/%svelte\.nonce%/g, nonce)
2509
+ // head and body must be replaced last, in case someone tries to sneak in %svelte.assets% etc
2510
+ .replace('%svelte.head%', () => head)
2511
+ .replace('%svelte.body%', () => body)
2512
+ );
2554
2513
  },
2555
2514
  template_contains_nonce: template.includes('%svelte.nonce%'),
2556
2515
  trailing_slash: config.kit.trailingSlash
@@ -2710,14 +2669,6 @@ async function dev({ cwd, port, host, https, config }) {
2710
2669
  merged_config.server.https = https;
2711
2670
  }
2712
2671
 
2713
- // by default, when enabling HTTPS in Vite, it also enables HTTP/2
2714
- // however, node-fetch's Request implementation does not like the HTTP/2 headers
2715
- // we set a no-op proxy config to force Vite to downgrade to TLS-only
2716
- // see https://vitejs.dev/config/#server-https
2717
- if (merged_config.server.https && !merged_config.server.proxy) {
2718
- merged_config.server.proxy = {};
2719
- }
2720
-
2721
2672
  if (port) {
2722
2673
  merged_config.server.port = port;
2723
2674
  }
@@ -455,17 +455,16 @@ function create_manifest_data({
455
455
  }
456
456
  });
457
457
 
458
- if (name[0] === '_') {
459
- if (name[1] === '_' && !specials.has(name)) {
460
- throw new Error(`Files and directories prefixed with __ are reserved (saw ${file})`);
461
- }
462
-
463
- return;
458
+ if (basename.startsWith('__') && !specials.has(name)) {
459
+ throw new Error(`Files and directories prefixed with __ are reserved (saw ${file})`);
464
460
  }
465
461
 
466
- if (basename[0] === '.' && basename !== '.well-known') return null;
467
462
  if (!is_dir && !/^(\.[a-z0-9]+)+$/i.test(ext)) return null; // filter out tmp files etc
468
463
 
464
+ if (!config.kit.routes(file)) {
465
+ return;
466
+ }
467
+
469
468
  const segment = is_dir ? basename : name;
470
469
 
471
470
  if (/\]\[/.test(segment)) {
@@ -626,6 +626,7 @@ async function build(config) {
626
626
  const build_data = {
627
627
  app_dir: config.kit.appDir,
628
628
  manifest_data: options.manifest_data,
629
+ service_worker: options.service_worker_entry_file ? 'service_worker.js' : null, // TODO make file configurable?
629
630
  client,
630
631
  server,
631
632
  static: options.manifest_data.assets.map((asset) => posixify(asset.file)),
@@ -47,10 +47,15 @@ function generate_manifest(
47
47
  ? (path) => `() => import('${path}')`
48
48
  : (path) => `() => Promise.resolve().then(() => require('${path}'))`;
49
49
 
50
+ const assets = build_data.manifest_data.assets.map((asset) => asset.file);
51
+ if (build_data.service_worker) {
52
+ assets.push(build_data.service_worker);
53
+ }
54
+
50
55
  // prettier-ignore
51
56
  return `{
52
57
  appDir: ${s(build_data.app_dir)},
53
- assets: new Set(${s(build_data.manifest_data.assets.map(asset => asset.file))}),
58
+ assets: new Set(${s(assets)}),
54
59
  _: {
55
60
  mime: ${s(get_mime_lookup(build_data.manifest_data))},
56
61
  entry: ${s(build_data.client.entry)},
@@ -15254,18 +15254,23 @@ const essential_files = ['README', 'LICENSE', 'CHANGELOG', '.gitignore', '.npmig
15254
15254
  * @param {string} cwd
15255
15255
  */
15256
15256
  async function make_package(config, cwd = process.cwd()) {
15257
- const package_dir = config.kit.package.dir;
15258
- const abs_package_dir = path.isAbsolute(package_dir) ? package_dir : path.join(cwd, package_dir);
15259
- rimraf(abs_package_dir);
15260
- mkdirp(abs_package_dir); // TODO https://github.com/sveltejs/kit/issues/2333
15257
+ if (!fs.existsSync(config.kit.files.lib)) {
15258
+ throw new Error(`${config.kit.files.lib} does not exist`);
15259
+ }
15260
+
15261
+ const package_dir = path.isAbsolute(config.kit.package.dir)
15262
+ ? config.kit.package.dir
15263
+ : path.join(cwd, config.kit.package.dir);
15264
+ rimraf(package_dir);
15265
+ mkdirp(package_dir); // TODO https://github.com/sveltejs/kit/issues/2333
15261
15266
 
15262
15267
  if (config.kit.package.emitTypes) {
15263
15268
  // Generate type definitions first so hand-written types can overwrite generated ones
15264
15269
  await emit_dts(config);
15265
15270
  // Resolve aliases, TS leaves them as-is
15266
- const files = walk$1(abs_package_dir);
15271
+ const files = walk$1(package_dir);
15267
15272
  for (const file of files) {
15268
- const filename = path.join(abs_package_dir, file);
15273
+ const filename = path.join(package_dir, file);
15269
15274
  const source = fs.readFileSync(filename, 'utf8');
15270
15275
  fs.writeFileSync(filename, resolve_$lib_alias(file, source, config));
15271
15276
  }
@@ -15292,7 +15297,7 @@ async function make_package(config, cwd = process.cwd()) {
15292
15297
 
15293
15298
  if (!config.kit.package.files(normalized)) {
15294
15299
  const dts_file = (svelte_ext ? file : file.slice(0, -ext.length)) + '.d.ts';
15295
- const dts_path = path.join(abs_package_dir, dts_file);
15300
+ const dts_path = path.join(package_dir, dts_file);
15296
15301
  if (fs.existsSync(dts_path)) {
15297
15302
  fs.unlinkSync(dts_path);
15298
15303
 
@@ -15327,7 +15332,7 @@ async function make_package(config, cwd = process.cwd()) {
15327
15332
  out_file = file;
15328
15333
  out_contents = source.toString('utf-8');
15329
15334
  out_contents = resolve_$lib_alias(out_file, out_contents, config);
15330
- if (fs.existsSync(path.join(abs_package_dir, out_file))) {
15335
+ if (fs.existsSync(path.join(package_dir, out_file))) {
15331
15336
  console.warn(
15332
15337
  'Found already existing file from d.ts generation for ' +
15333
15338
  out_file +
@@ -15343,7 +15348,7 @@ async function make_package(config, cwd = process.cwd()) {
15343
15348
  out_contents = source;
15344
15349
  }
15345
15350
 
15346
- write(path.join(abs_package_dir, out_file), out_contents);
15351
+ write(path.join(package_dir, out_file), out_contents);
15347
15352
 
15348
15353
  if (config.kit.package.exports(normalized)) {
15349
15354
  const original = `$lib/${normalized}`;
@@ -15390,7 +15395,7 @@ async function make_package(config, cwd = process.cwd()) {
15390
15395
  }
15391
15396
  }
15392
15397
 
15393
- write(path.join(abs_package_dir, 'package.json'), JSON.stringify(pkg, null, ' '));
15398
+ write(path.join(package_dir, 'package.json'), JSON.stringify(pkg, null, 2));
15394
15399
 
15395
15400
  const whitelist = fs.readdirSync(cwd).filter((file) => {
15396
15401
  const lowercased = file.toLowerCase();
@@ -15400,7 +15405,7 @@ async function make_package(config, cwd = process.cwd()) {
15400
15405
  const full_path = path.join(cwd, pathname);
15401
15406
  if (fs.lstatSync(full_path).isDirectory()) continue; // just to be sure
15402
15407
 
15403
- const package_path = path.join(abs_package_dir, pathname);
15408
+ const package_path = path.join(package_dir, pathname);
15404
15409
  if (!fs.existsSync(package_path)) fs.copyFileSync(full_path, package_path);
15405
15410
  }
15406
15411
 
@@ -15568,8 +15573,7 @@ async function try_load_svelte2tsx() {
15568
15573
  return await import('svelte2tsx');
15569
15574
  } catch (e) {
15570
15575
  throw new Error(
15571
- 'You need to install svelte2tsx and typescript if you want to generate type definitions\n' +
15572
- e
15576
+ 'You need svelte2tsx and typescript if you want to generate type definitions. Install it through your package manager, or disable generation which is highly discouraged. See https://kit.svelte.dev/docs#packaging'
15573
15577
  );
15574
15578
  }
15575
15579
  }
package/dist/cli.js CHANGED
@@ -676,6 +676,8 @@ const options = object(
676
676
 
677
677
  router: boolean(true),
678
678
 
679
+ routes: fun((filepath) => !/(?:(?:^_|\/_)|(?:^\.|\/\.)(?!well-known))/.test(filepath)),
680
+
679
681
  serviceWorker: object({
680
682
  register: boolean(true),
681
683
  files: fun((filename) => !/\.DS_STORE/.test(filename))
@@ -986,17 +988,20 @@ async function launch(port, https) {
986
988
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
987
989
  }
988
990
 
989
- const prog = sade('svelte-kit').version('1.0.0-next.245');
991
+ const prog = sade('svelte-kit').version('1.0.0-next.249');
990
992
 
991
993
  prog
992
994
  .command('dev')
993
995
  .describe('Start a development server')
994
996
  .option('-p, --port', 'Port')
995
- .option('-h, --host', 'Host (only use this on trusted networks)')
996
- .option('-H, --https', 'Use self-signed HTTPS certificate')
997
997
  .option('-o, --open', 'Open a browser tab')
998
- .action(async ({ port, host, https, open }) => {
998
+ .option('--host', 'Host (only use this on trusted networks)')
999
+ .option('--https', 'Use self-signed HTTPS certificate')
1000
+ .option('-H', 'no longer supported, use --https instead') // TODO remove for 1.0
1001
+ .action(async ({ port, host, https, open, H }) => {
999
1002
  try {
1003
+ if (H) throw new Error('-H is no longer supported — use --https instead');
1004
+
1000
1005
  process.env.NODE_ENV = process.env.NODE_ENV || 'development';
1001
1006
  const config = await load_config();
1002
1007
 
@@ -1065,11 +1070,14 @@ prog
1065
1070
  .command('preview')
1066
1071
  .describe('Serve an already-built app')
1067
1072
  .option('-p, --port', 'Port', 3000)
1068
- .option('-h, --host', 'Host (only use this on trusted networks)', 'localhost')
1069
- .option('-H, --https', 'Use self-signed HTTPS certificate', false)
1070
1073
  .option('-o, --open', 'Open a browser tab', false)
1071
- .action(async ({ port, host, https, open }) => {
1074
+ .option('--host', 'Host (only use this on trusted networks)', 'localhost')
1075
+ .option('--https', 'Use self-signed HTTPS certificate', false)
1076
+ .option('-H', 'no longer supported, use --https instead') // TODO remove for 1.0
1077
+ .action(async ({ port, host, https, open, H }) => {
1072
1078
  try {
1079
+ if (H) throw new Error('-H is no longer supported — use --https instead');
1080
+
1073
1081
  await check_port(port);
1074
1082
 
1075
1083
  process.env.NODE_ENV = process.env.NODE_ENV || 'production';
@@ -1138,7 +1146,7 @@ async function check_port(port) {
1138
1146
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1139
1147
  if (open) launch(port, https);
1140
1148
 
1141
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.245'}\n`));
1149
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.249'}\n`));
1142
1150
 
1143
1151
  const protocol = https ? 'https:' : 'http:';
1144
1152
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
package/dist/node.js CHANGED
@@ -52,9 +52,19 @@ function get_raw_body(req) {
52
52
 
53
53
  /** @type {import('@sveltejs/kit/node').GetRequest} */
54
54
  async function getRequest(base, req) {
55
+ let headers = /** @type {Record<string, string>} */ (req.headers);
56
+ if (req.httpVersionMajor === 2) {
57
+ // we need to strip out the HTTP/2 pseudo-headers because node-fetch's
58
+ // Request implementation doesn't like them
59
+ headers = Object.assign({}, headers);
60
+ delete headers[':method'];
61
+ delete headers[':path'];
62
+ delete headers[':authority'];
63
+ delete headers[':scheme'];
64
+ }
55
65
  return new Request(base + req.url, {
56
66
  method: req.method,
57
- headers: /** @type {Record<string, string>} */ (req.headers),
67
+ headers,
58
68
  body: await get_raw_body(req) // TODO stream rather than buffer
59
69
  });
60
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.245",
3
+ "version": "1.0.0-next.249",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
package/types/config.d.ts CHANGED
@@ -155,6 +155,7 @@ export interface Config {
155
155
  onError?: PrerenderOnErrorValue;
156
156
  };
157
157
  router?: boolean;
158
+ routes?: (filepath: string) => boolean;
158
159
  serviceWorker?: {
159
160
  register?: boolean;
160
161
  files?: (filepath: string) => boolean;
@@ -209,6 +209,7 @@ export interface ManifestData {
209
209
  export interface BuildData {
210
210
  app_dir: string;
211
211
  manifest_data: ManifestData;
212
+ service_worker: string | null;
212
213
  client: {
213
214
  assets: OutputAsset[];
214
215
  chunks: OutputChunk[];