@sveltejs/kit 1.0.0-next.244 → 1.0.0-next.248

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
@@ -2187,7 +2187,8 @@ async function respond(request, options, state = {}) {
2187
2187
  request,
2188
2188
  url,
2189
2189
  params: {},
2190
- locals: {}
2190
+ locals: {},
2191
+ platform: state.platform
2191
2192
  };
2192
2193
 
2193
2194
  // TODO remove this for 1.0
@@ -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
@@ -2081,7 +2082,8 @@ async function respond(request, options, state = {}) {
2081
2082
  request,
2082
2083
  url,
2083
2084
  params: {},
2084
- locals: {}
2085
+ locals: {},
2086
+ platform: state.platform
2085
2087
  };
2086
2088
 
2087
2089
  // TODO remove this for 1.0
@@ -2261,12 +2263,12 @@ async function respond(request, options, state = {}) {
2261
2263
  * @returns {Promise<import('vite').Plugin>}
2262
2264
  */
2263
2265
  async function create_plugin(config, cwd) {
2264
- /** @type {import('amphtml-validator').Validator} */
2266
+ /** @type {import('types/hooks').Handle} */
2265
2267
  let amp;
2266
2268
 
2267
2269
  if (config.kit.amp) {
2268
2270
  process.env.VITE_SVELTEKIT_AMP = 'true';
2269
- amp = await (await import('./index8.js').then(function (n) { return n.i; })).getInstance();
2271
+ amp = (await import('./amp_hook.js')).handle;
2270
2272
  }
2271
2273
 
2272
2274
  return {
@@ -2383,7 +2385,6 @@ async function create_plugin(config, cwd) {
2383
2385
  vite.middlewares.use(async (req, res) => {
2384
2386
  try {
2385
2387
  if (!req.url || !req.method) throw new Error('Incomplete request');
2386
- if (req.url === '/favicon.ico') return not_found(res);
2387
2388
 
2388
2389
  const base = `${vite.config.server.https ? 'https' : 'http'}://${req.headers.host}`;
2389
2390
 
@@ -2400,6 +2401,8 @@ async function create_plugin(config, cwd) {
2400
2401
  }
2401
2402
  }
2402
2403
 
2404
+ if (req.url === '/favicon.ico') return not_found(res);
2405
+
2403
2406
  if (!decoded.startsWith(config.kit.paths.base)) return not_found(res);
2404
2407
 
2405
2408
  /** @type {Partial<import('types/internal').Hooks>} */
@@ -2407,10 +2410,12 @@ async function create_plugin(config, cwd) {
2407
2410
  ? await vite.ssrLoadModule(`/${config.kit.files.hooks}`)
2408
2411
  : {};
2409
2412
 
2413
+ const handle = user_hooks.handle || (({ event, resolve }) => resolve(event));
2414
+
2410
2415
  /** @type {import('types/internal').Hooks} */
2411
2416
  const hooks = {
2412
2417
  getSession: user_hooks.getSession || (() => ({})),
2413
- handle: user_hooks.handle || (({ event, resolve }) => resolve(event)),
2418
+ handle: amp ? sequence(amp, handle) : handle,
2414
2419
  handleError:
2415
2420
  user_hooks.handleError ||
2416
2421
  (({ /** @type {Error & { frame?: string }} */ error }) => {
@@ -2497,58 +2502,14 @@ async function create_plugin(config, cwd) {
2497
2502
  router: config.kit.router,
2498
2503
  target: config.kit.target,
2499
2504
  template: ({ head, body, assets, nonce }) => {
2500
- let rendered = template
2501
- .replace(/%svelte\.assets%/g, assets)
2502
- .replace(/%svelte\.nonce%/g, nonce)
2503
- // head and body must be replaced last, in case someone tries to sneak in %svelte.assets% etc
2504
- .replace('%svelte.head%', () => head)
2505
- .replace('%svelte.body%', () => body);
2506
-
2507
- if (amp) {
2508
- const result = amp.validateString(rendered);
2509
-
2510
- if (result.status !== 'PASS') {
2511
- const lines = rendered.split('\n');
2512
-
2513
- /** @param {string} str */
2514
- const escape = (str) =>
2515
- str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
2516
-
2517
- rendered = `<!doctype html>
2518
- <head>
2519
- <meta charset="utf-8" />
2520
- <meta name="viewport" content="width=device-width, initial-scale=1" />
2521
- <style>
2522
- body {
2523
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
2524
- color: #333;
2525
- }
2526
-
2527
- pre {
2528
- background: #f4f4f4;
2529
- padding: 1em;
2530
- overflow-x: auto;
2531
- }
2532
- </style>
2533
- </head>
2534
- <h1>AMP validation failed</h1>
2535
-
2536
- ${result.errors
2537
- .map(
2538
- (error) => `
2539
- <h2>${error.severity}</h2>
2540
- <p>Line ${error.line}, column ${error.col}: ${error.message} (<a href="${error.specUrl}">${
2541
- error.code
2542
- }</a>)</p>
2543
- <pre>${escape(lines[error.line - 1])}</pre>
2544
- `
2545
- )
2546
- .join('\n\n')}
2547
- `;
2548
- }
2549
- }
2550
-
2551
- 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
+ );
2552
2513
  },
2553
2514
  template_contains_nonce: template.includes('%svelte.nonce%'),
2554
2515
  trailing_slash: config.kit.trailingSlash
@@ -2708,14 +2669,6 @@ async function dev({ cwd, port, host, https, config }) {
2708
2669
  merged_config.server.https = https;
2709
2670
  }
2710
2671
 
2711
- // by default, when enabling HTTPS in Vite, it also enables HTTP/2
2712
- // however, node-fetch's Request implementation does not like the HTTP/2 headers
2713
- // we set a no-op proxy config to force Vite to downgrade to TLS-only
2714
- // see https://vitejs.dev/config/#server-https
2715
- if (merged_config.server.https && !merged_config.server.proxy) {
2716
- merged_config.server.proxy = {};
2717
- }
2718
-
2719
2672
  if (port) {
2720
2673
  merged_config.server.port = port;
2721
2674
  }
@@ -326,14 +326,12 @@ export class App {
326
326
  };
327
327
  }
328
328
 
329
- render(request, {
330
- prerender
331
- } = {}) {
329
+ render(request, options = {}) {
332
330
  if (!(request instanceof Request)) {
333
331
  throw new Error('The first argument to app.render must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
334
332
  }
335
333
 
336
- return respond(request, this.options, { prerender });
334
+ return respond(request, this.options, options);
337
335
  }
338
336
  }
339
337
  `;
@@ -402,7 +400,6 @@ async function build_server(
402
400
  return relative_file[0] === '.' ? relative_file : `./${relative_file}`;
403
401
  };
404
402
 
405
- // prettier-ignore
406
403
  fs__default.writeFileSync(
407
404
  input.app,
408
405
  app_template({
@@ -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
@@ -986,17 +986,20 @@ async function launch(port, https) {
986
986
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
987
987
  }
988
988
 
989
- const prog = sade('svelte-kit').version('1.0.0-next.244');
989
+ const prog = sade('svelte-kit').version('1.0.0-next.248');
990
990
 
991
991
  prog
992
992
  .command('dev')
993
993
  .describe('Start a development server')
994
994
  .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
995
  .option('-o, --open', 'Open a browser tab')
998
- .action(async ({ port, host, https, open }) => {
996
+ .option('--host', 'Host (only use this on trusted networks)')
997
+ .option('--https', 'Use self-signed HTTPS certificate')
998
+ .option('-H', 'no longer supported, use --https instead') // TODO remove for 1.0
999
+ .action(async ({ port, host, https, open, H }) => {
999
1000
  try {
1001
+ if (H) throw new Error('-H is no longer supported — use --https instead');
1002
+
1000
1003
  process.env.NODE_ENV = process.env.NODE_ENV || 'development';
1001
1004
  const config = await load_config();
1002
1005
 
@@ -1065,11 +1068,14 @@ prog
1065
1068
  .command('preview')
1066
1069
  .describe('Serve an already-built app')
1067
1070
  .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
1071
  .option('-o, --open', 'Open a browser tab', false)
1071
- .action(async ({ port, host, https, open }) => {
1072
+ .option('--host', 'Host (only use this on trusted networks)', 'localhost')
1073
+ .option('--https', 'Use self-signed HTTPS certificate', false)
1074
+ .option('-H', 'no longer supported, use --https instead') // TODO remove for 1.0
1075
+ .action(async ({ port, host, https, open, H }) => {
1072
1076
  try {
1077
+ if (H) throw new Error('-H is no longer supported — use --https instead');
1078
+
1073
1079
  await check_port(port);
1074
1080
 
1075
1081
  process.env.NODE_ENV = process.env.NODE_ENV || 'production';
@@ -1138,7 +1144,7 @@ async function check_port(port) {
1138
1144
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1139
1145
  if (open) launch(port, https);
1140
1146
 
1141
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.244'}\n`));
1147
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.248'}\n`));
1142
1148
 
1143
1149
  const protocol = https ? 'https:' : 'http:';
1144
1150
  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.244",
3
+ "version": "1.0.0-next.248",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
package/types/app.d.ts CHANGED
@@ -1,15 +1,19 @@
1
1
  import { PrerenderOptions, SSRNodeLoader, SSRRoute } from './internal';
2
2
 
3
+ export interface RequestOptions<Platform = Record<string, any>> {
4
+ platform?: Platform;
5
+ }
6
+
3
7
  export class App {
4
8
  constructor(manifest: SSRManifest);
5
- render(request: Request): Promise<Response>;
9
+ render(request: Request, options?: RequestOptions): Promise<Response>;
6
10
  }
7
11
 
8
12
  export class InternalApp extends App {
9
13
  render(
10
14
  request: Request,
11
- options?: {
12
- prerender: PrerenderOptions;
15
+ options?: RequestOptions & {
16
+ prerender?: PrerenderOptions;
13
17
  }
14
18
  ): Promise<Response>;
15
19
  }
@@ -13,8 +13,12 @@ export interface Fallthrough {
13
13
  fallthrough: true;
14
14
  }
15
15
 
16
- export interface RequestHandler<Locals = Record<string, any>, Output extends Body = Body> {
17
- (event: RequestEvent<Locals>): MaybePromise<
16
+ export interface RequestHandler<
17
+ Locals = Record<string, any>,
18
+ Platform = Record<string, any>,
19
+ Output extends Body = Body
20
+ > {
21
+ (event: RequestEvent<Locals, Platform>): MaybePromise<
18
22
  Either<Response | EndpointOutput<Output>, Fallthrough>
19
23
  >;
20
24
  }
package/types/hooks.d.ts CHANGED
@@ -2,25 +2,30 @@ import { MaybePromise } from './helper';
2
2
 
3
3
  export type StrictBody = string | Uint8Array;
4
4
 
5
- export interface RequestEvent<Locals = Record<string, any>> {
5
+ export interface RequestEvent<Locals = Record<string, any>, Platform = Record<string, any>> {
6
6
  request: Request;
7
7
  url: URL;
8
8
  params: Record<string, string>;
9
9
  locals: Locals;
10
+ platform: Readonly<Platform>;
10
11
  }
11
12
 
12
- export interface GetSession<Locals = Record<string, any>, Session = any> {
13
- (event: RequestEvent<Locals>): MaybePromise<Session>;
13
+ export interface GetSession<
14
+ Locals = Record<string, any>,
15
+ Platform = Record<string, any>,
16
+ Session = any
17
+ > {
18
+ (event: RequestEvent<Locals, Platform>): MaybePromise<Session>;
14
19
  }
15
20
 
16
21
  export interface ResolveOpts {
17
22
  ssr?: boolean;
18
23
  }
19
24
 
20
- export interface Handle<Locals = Record<string, any>> {
25
+ export interface Handle<Locals = Record<string, any>, Platform = Record<string, any>> {
21
26
  (input: {
22
- event: RequestEvent<Locals>;
23
- resolve(event: RequestEvent<Locals>, opts?: ResolveOpts): MaybePromise<Response>;
27
+ event: RequestEvent<Locals, Platform>;
28
+ resolve(event: RequestEvent<Locals, Platform>, opts?: ResolveOpts): MaybePromise<Response>;
24
29
  }): MaybePromise<Response>;
25
30
  }
26
31
 
@@ -159,6 +159,7 @@ export interface SSRRenderOptions {
159
159
  export interface SSRRenderState {
160
160
  fetched?: string;
161
161
  initiator?: SSRPage | null;
162
+ platform?: any;
162
163
  prerender?: PrerenderOptions;
163
164
  fallback?: string;
164
165
  }