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

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.
@@ -1,6 +1,6 @@
1
1
  import fs__default from 'fs';
2
2
  import path__default from 'path';
3
- import { p as print_config_conflicts, a as SVELTE_KIT, d as copy_assets, f as posixify, e as get_aliases, r as resolve_entry, b as runtime, l as load_template, m as mkdirp, h as rimraf } from '../cli.js';
3
+ import { p as print_config_conflicts, a as SVELTE_KIT, d as copy_assets, f as posixify, e as get_aliases, r as resolve_entry, l as load_template, b as runtime, m as mkdirp, h as rimraf } from '../cli.js';
4
4
  import { d as deep_merge, a as create_app, c as create_manifest_data } from './index2.js';
5
5
  import { g as generate_manifest } from './index4.js';
6
6
  import vite from 'vite';
@@ -241,24 +241,25 @@ async function build_client({
241
241
 
242
242
  /**
243
243
  * @param {{
244
- * cwd: string;
245
244
  * hooks: string;
246
245
  * config: import('types/config').ValidatedConfig;
247
246
  * has_service_worker: boolean;
247
+ * template: string;
248
248
  * }} opts
249
249
  * @returns
250
250
  */
251
- const template = ({ cwd, config, hooks, has_service_worker }) => `
251
+ const app_template = ({ config, hooks, has_service_worker, template }) => `
252
252
  import root from '__GENERATED__/root.svelte';
253
253
  import { respond } from '${runtime}/server/index.js';
254
254
  import { set_paths, assets, base } from '${runtime}/paths.js';
255
255
  import { set_prerendering } from '${runtime}/env.js';
256
256
  import * as user_hooks from ${s(hooks)};
257
257
 
258
- const template = ({ head, body, assets }) => ${s(load_template(cwd, config))
258
+ const template = ({ head, body, assets, nonce }) => ${s(template)
259
259
  .replace('%svelte.head%', '" + head + "')
260
260
  .replace('%svelte.body%', '" + body + "')
261
- .replace(/%svelte\.assets%/g, '" + assets + "')};
261
+ .replace(/%svelte\.assets%/g, '" + assets + "')
262
+ .replace(/%svelte\.nonce%/g, '" + nonce + "')};
262
263
 
263
264
  let read = null;
264
265
 
@@ -290,6 +291,7 @@ export class App {
290
291
 
291
292
  this.options = {
292
293
  amp: ${config.kit.amp},
294
+ csp: ${s(config.kit.csp)},
293
295
  dev: false,
294
296
  floc: ${config.kit.floc},
295
297
  get_stack: error => String(error), // for security
@@ -319,18 +321,17 @@ export class App {
319
321
  router: ${s(config.kit.router)},
320
322
  target: ${s(config.kit.target)},
321
323
  template,
324
+ template_contains_nonce: ${template.includes('%svelte.nonce%')},
322
325
  trailing_slash: ${s(config.kit.trailingSlash)}
323
326
  };
324
327
  }
325
328
 
326
- render(request, {
327
- prerender
328
- } = {}) {
329
+ render(request, options = {}) {
329
330
  if (!(request instanceof Request)) {
330
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');
331
332
  }
332
333
 
333
- return respond(request, this.options, { prerender });
334
+ return respond(request, this.options, options);
334
335
  }
335
336
  }
336
337
  `;
@@ -399,14 +400,13 @@ async function build_server(
399
400
  return relative_file[0] === '.' ? relative_file : `./${relative_file}`;
400
401
  };
401
402
 
402
- // prettier-ignore
403
403
  fs__default.writeFileSync(
404
404
  input.app,
405
- template({
406
- cwd,
405
+ app_template({
407
406
  config,
408
407
  hooks: app_relative(hooks_file),
409
- has_service_worker: service_worker_register && !!service_worker_entry_file
408
+ has_service_worker: service_worker_register && !!service_worker_entry_file,
409
+ template: load_template(cwd, config)
410
410
  })
411
411
  );
412
412
 
@@ -412,8 +412,9 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
412
412
  * @param {string?} referrer
413
413
  */
414
414
  async function visit(path, decoded_path, referrer) {
415
- /** @type {Map<string, Response>} */
415
+ /** @type {Map<string, import('types/internal').PrerenderDependency>} */
416
416
  const dependencies = new Map();
417
+
417
418
  const render_path = config.kit.paths?.base
418
419
  ? `http://sveltekit-prerender${config.kit.paths.base}${path === '/' ? '' : path}`
419
420
  : `http://sveltekit-prerender${path}`;
@@ -474,9 +475,11 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
474
475
  }
475
476
 
476
477
  for (const [dependency_path, result] of dependencies) {
477
- const response_type = Math.floor(result.status / 100);
478
+ const { status, headers } = result.response;
479
+
480
+ const response_type = Math.floor(status / 100);
478
481
 
479
- const is_html = result.headers.get('content-type') === 'text/html';
482
+ const is_html = headers.get('content-type') === 'text/html';
480
483
 
481
484
  const parts = dependency_path.split('/');
482
485
  if (is_html && parts[parts.length - 1] !== 'index.html') {
@@ -486,16 +489,17 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
486
489
  const file = `${out}${parts.join('/')}`;
487
490
  mkdirp(dirname(file));
488
491
 
489
- if (result.body) {
490
- writeFileSync(file, await result.text());
491
- paths.push(dependency_path);
492
- }
492
+ writeFileSync(
493
+ file,
494
+ result.body === null ? new Uint8Array(await result.response.arrayBuffer()) : result.body
495
+ );
496
+ paths.push(dependency_path);
493
497
 
494
498
  if (response_type === OK) {
495
- log.info(`${result.status} ${dependency_path}`);
499
+ log.info(`${status} ${dependency_path}`);
496
500
  } else {
497
501
  error({
498
- status: result.status,
502
+ status,
499
503
  path: dependency_path,
500
504
  referrer: path,
501
505
  referenceType: 'fetched'
@@ -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
@@ -1,5 +1,5 @@
1
1
  import sade from 'sade';
2
- import path__default, { relative } from 'path';
2
+ import path__default, { join, relative } from 'path';
3
3
  import { exec as exec$1 } from 'child_process';
4
4
  import { createConnection, createServer } from 'net';
5
5
  import fs__default from 'fs';
@@ -490,13 +490,50 @@ const options = object(
490
490
  return input;
491
491
  }),
492
492
 
493
+ csp: object({
494
+ mode: list(['auto', 'hash', 'nonce']),
495
+ directives: object({
496
+ 'child-src': string_array(),
497
+ 'default-src': string_array(),
498
+ 'frame-src': string_array(),
499
+ 'worker-src': string_array(),
500
+ 'connect-src': string_array(),
501
+ 'font-src': string_array(),
502
+ 'img-src': string_array(),
503
+ 'manifest-src': string_array(),
504
+ 'media-src': string_array(),
505
+ 'object-src': string_array(),
506
+ 'prefetch-src': string_array(),
507
+ 'script-src': string_array(),
508
+ 'script-src-elem': string_array(),
509
+ 'script-src-attr': string_array(),
510
+ 'style-src': string_array(),
511
+ 'style-src-elem': string_array(),
512
+ 'style-src-attr': string_array(),
513
+ 'base-uri': string_array(),
514
+ sandbox: string_array(),
515
+ 'form-action': string_array(),
516
+ 'frame-ancestors': string_array(),
517
+ 'navigate-to': string_array(),
518
+ 'report-uri': string_array(),
519
+ 'report-to': string_array(),
520
+ 'require-trusted-types-for': string_array(),
521
+ 'trusted-types': string_array(),
522
+ 'upgrade-insecure-requests': boolean(false),
523
+ 'require-sri-for': string_array(),
524
+ 'block-all-mixed-content': boolean(false),
525
+ 'plugin-types': string_array(),
526
+ referrer: string_array()
527
+ })
528
+ }),
529
+
493
530
  files: object({
494
531
  assets: string('static'),
495
- hooks: string('src/hooks'),
496
- lib: string('src/lib'),
497
- routes: string('src/routes'),
498
- serviceWorker: string('src/service-worker'),
499
- template: string('src/app.html')
532
+ hooks: string(join('src', 'hooks')),
533
+ lib: string(join('src', 'lib')),
534
+ routes: string(join('src', 'routes')),
535
+ serviceWorker: string(join('src', 'service-worker')),
536
+ template: string(join('src', 'app.html'))
500
537
  }),
501
538
 
502
539
  floc: boolean(false),
@@ -747,6 +784,22 @@ function string(fallback, allow_empty = true) {
747
784
  });
748
785
  }
749
786
 
787
+ /**
788
+ * @param {string[] | undefined} [fallback]
789
+ * @returns {Validator}
790
+ */
791
+ function string_array(fallback) {
792
+ return validate(fallback, (input, keypath) => {
793
+ if (input === undefined) return input;
794
+
795
+ if (!Array.isArray(input) || input.some((value) => typeof value !== 'string')) {
796
+ throw new Error(`${keypath} must be an array of strings, if specified`);
797
+ }
798
+
799
+ return input;
800
+ });
801
+ }
802
+
750
803
  /**
751
804
  * @param {number} fallback
752
805
  * @returns {Validator}
@@ -933,7 +986,7 @@ async function launch(port, https) {
933
986
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
934
987
  }
935
988
 
936
- const prog = sade('svelte-kit').version('1.0.0-next.242');
989
+ const prog = sade('svelte-kit').version('1.0.0-next.246');
937
990
 
938
991
  prog
939
992
  .command('dev')
@@ -1085,7 +1138,7 @@ async function check_port(port) {
1085
1138
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1086
1139
  if (open) launch(port, https);
1087
1140
 
1088
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.242'}\n`));
1141
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.246'}\n`));
1089
1142
 
1090
1143
  const protocol = https ? 'https:' : 'http:';
1091
1144
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
@@ -6489,7 +6489,7 @@ function fixResponseChunkedTransferBadEnding(request, errorCallback) {
6489
6489
  });
6490
6490
  }
6491
6491
 
6492
- // exported for dev, prerender, and preview
6492
+ // exported for dev/preview and node environments
6493
6493
  function __fetch_polyfill() {
6494
6494
  Object.defineProperties(globalThis, {
6495
6495
  fetch: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.242",
3
+ "version": "1.0.0-next.246",
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
  }
package/types/config.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { CompileOptions } from 'svelte/types/compiler/interfaces';
2
2
  import { UserConfig as ViteConfig } from 'vite';
3
+ import { CspDirectives } from './csp';
3
4
  import { RecursiveRequired } from './helper';
4
5
  import { HttpMethod, Logger, RouteSegment, TrailingSlash } from './internal';
5
6
 
@@ -117,6 +118,10 @@ export interface Config {
117
118
  adapter?: Adapter;
118
119
  amp?: boolean;
119
120
  appDir?: string;
121
+ csp?: {
122
+ mode?: 'hash' | 'nonce' | 'auto';
123
+ directives?: CspDirectives;
124
+ };
120
125
  files?: {
121
126
  assets?: string;
122
127
  hooks?: string;
package/types/csp.d.ts ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts
3
+ *
4
+ * MIT License
5
+ *
6
+ * Copyright (c) 2021-present, Joshua Hemphill
7
+ * Copyright (c) 2021, Tecnico Corporation
8
+ *
9
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ * of this software and associated documentation files (the "Software"), to deal
11
+ * in the Software without restriction, including without limitation the rights
12
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the Software is
14
+ * furnished to do so, subject to the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be included in all
17
+ * copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ */
27
+ type SchemeSource = 'http:' | 'https:' | 'data:' | 'mediastream:' | 'blob:' | 'filesystem:';
28
+
29
+ type HostProtocolSchemes = `${string}://` | '';
30
+ type PortScheme = `:${number}` | '' | ':*';
31
+ /** Can actually be any string, but typed more explicitly to
32
+ * restrict the combined optional types of Source from collapsing to just bing `string` */
33
+ type HostNameScheme = `${string}.${string}` | `localhost`;
34
+ type HostSource = `${HostProtocolSchemes}${HostNameScheme}${PortScheme}`;
35
+
36
+ type CryptoSource = `${'nonce' | 'sha256' | 'sha384' | 'sha512'}-${string}`;
37
+
38
+ type BaseSource = 'self' | 'unsafe-eval' | 'unsafe-hashes' | 'unsafe-inline' | 'none';
39
+
40
+ export type Source = HostSource | SchemeSource | CryptoSource | BaseSource;
41
+ type Sources = Source[];
42
+
43
+ type ActionSource = 'strict-dynamic' | 'report-sample';
44
+
45
+ type FrameSource = HostSource | SchemeSource | 'self' | 'none';
46
+
47
+ type HttpDelineator = '/' | '?' | '#' | '\\';
48
+ type UriPath = `${HttpDelineator}${string}`;
49
+
50
+ export type CspDirectives = {
51
+ 'child-src'?: Sources;
52
+ 'default-src'?: Array<Source | ActionSource>;
53
+ 'frame-src'?: Sources;
54
+ 'worker-src'?: Sources;
55
+ 'connect-src'?: Sources;
56
+ 'font-src'?: Sources;
57
+ 'img-src'?: Sources;
58
+ 'manifest-src'?: Sources;
59
+ 'media-src'?: Sources;
60
+ 'object-src'?: Sources;
61
+ 'prefetch-src'?: Sources;
62
+ 'script-src'?: Array<Source | ActionSource>;
63
+ 'script-src-elem'?: Sources;
64
+ 'script-src-attr'?: Sources;
65
+ 'style-src'?: Array<Source | ActionSource>;
66
+ 'style-src-elem'?: Sources;
67
+ 'style-src-attr'?: Sources;
68
+ 'base-uri'?: Array<Source | ActionSource>;
69
+ sandbox?: Array<
70
+ | 'allow-downloads-without-user-activation'
71
+ | 'allow-forms'
72
+ | 'allow-modals'
73
+ | 'allow-orientation-lock'
74
+ | 'allow-pointer-lock'
75
+ | 'allow-popups'
76
+ | 'allow-popups-to-escape-sandbox'
77
+ | 'allow-presentation'
78
+ | 'allow-same-origin'
79
+ | 'allow-scripts'
80
+ | 'allow-storage-access-by-user-activation'
81
+ | 'allow-top-navigation'
82
+ | 'allow-top-navigation-by-user-activation'
83
+ >;
84
+ 'form-action'?: Array<Source | ActionSource>;
85
+ 'frame-ancestors'?: Array<HostSource | SchemeSource | FrameSource>;
86
+ 'navigate-to'?: Array<Source | ActionSource>;
87
+ 'report-uri'?: UriPath[];
88
+ 'report-to'?: string[];
89
+
90
+ 'require-trusted-types-for'?: Array<'script'>;
91
+ 'trusted-types'?: Array<'none' | 'allow-duplicates' | '*' | string>;
92
+ 'upgrade-insecure-requests'?: boolean;
93
+
94
+ /** @deprecated */
95
+ 'require-sri-for'?: Array<'script' | 'style' | 'script style'>;
96
+
97
+ /** @deprecated */
98
+ 'block-all-mixed-content'?: boolean;
99
+
100
+ /** @deprecated */
101
+ 'plugin-types'?: Array<`${string}/${string}` | 'none'>;
102
+
103
+ /** @deprecated */
104
+ referrer?: Array<
105
+ | 'no-referrer'
106
+ | 'no-referrer-when-downgrade'
107
+ | 'origin'
108
+ | 'origin-when-cross-origin'
109
+ | 'same-origin'
110
+ | 'strict-origin'
111
+ | 'strict-origin-when-cross-origin'
112
+ | 'unsafe-url'
113
+ | 'none'
114
+ >;
115
+ };
@@ -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/helper.d.ts CHANGED
@@ -13,7 +13,7 @@ export type JSONString =
13
13
  export type ResponseHeaders = Record<string, string | string[]>;
14
14
 
15
15
  // <-- Utility Types -->
16
- type Only<T, U> = { [P in keyof T]: T[P] } & { [P in keyof U]?: never };
16
+ type Only<T, U> = { [P in keyof T]: T[P] } & { [P in Exclude<keyof U, keyof T>]?: never };
17
17
 
18
18
  export type Either<T, U> = Only<T, U> | Only<U, T>;
19
19
  export type InferValue<T, Key extends keyof T, Default> = T extends Record<Key, infer Val>
package/types/hooks.d.ts CHANGED
@@ -2,37 +2,33 @@ 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
 
27
- // internally, `resolve` could return `undefined`, so we differentiate InternalHandle
28
- // from the public Handle type
29
- export interface InternalHandle<Locals = Record<string, any>> {
30
- (input: {
31
- event: RequestEvent<Locals>;
32
- resolve(event: RequestEvent<Locals>, opts?: ResolveOpts): MaybePromise<Response | undefined>;
33
- }): MaybePromise<Response | undefined>;
34
- }
35
-
36
32
  export interface HandleError<Locals = Record<string, any>> {
37
33
  (input: { error: Error & { frame?: string }; event: RequestEvent<Locals> }): void;
38
34
  }
@@ -1,14 +1,20 @@
1
1
  import { OutputAsset, OutputChunk } from 'rollup';
2
+ import { ValidatedConfig } from './config';
2
3
  import { InternalApp, SSRManifest } from './app';
3
4
  import { Fallthrough, RequestHandler } from './endpoint';
4
5
  import { Either } from './helper';
5
- import { ExternalFetch, GetSession, HandleError, InternalHandle, RequestEvent } from './hooks';
6
+ import { ExternalFetch, GetSession, Handle, HandleError, RequestEvent } from './hooks';
6
7
  import { Load } from './page';
7
8
 
9
+ export interface PrerenderDependency {
10
+ response: Response;
11
+ body: null | string | Uint8Array;
12
+ }
13
+
8
14
  export interface PrerenderOptions {
9
15
  fallback?: string;
10
16
  all: boolean;
11
- dependencies: Map<string, Response>;
17
+ dependencies: Map<string, PrerenderDependency>;
12
18
  }
13
19
 
14
20
  export interface AppModule {
@@ -97,7 +103,7 @@ export type SSRNodeLoader = () => Promise<SSRNode>;
97
103
  export interface Hooks {
98
104
  externalFetch: ExternalFetch;
99
105
  getSession: GetSession;
100
- handle: InternalHandle;
106
+ handle: Handle;
101
107
  handleError: HandleError;
102
108
  }
103
109
 
@@ -115,6 +121,7 @@ export interface SSRNode {
115
121
 
116
122
  export interface SSRRenderOptions {
117
123
  amp: boolean;
124
+ csp: ValidatedConfig['kit']['csp'];
118
125
  dev: boolean;
119
126
  floc: boolean;
120
127
  get_stack: (error: Error) => string | undefined;
@@ -134,13 +141,25 @@ export interface SSRRenderOptions {
134
141
  router: boolean;
135
142
  service_worker?: string;
136
143
  target: string;
137
- template({ head, body, assets }: { head: string; body: string; assets: string }): string;
144
+ template({
145
+ head,
146
+ body,
147
+ assets,
148
+ nonce
149
+ }: {
150
+ head: string;
151
+ body: string;
152
+ assets: string;
153
+ nonce: string;
154
+ }): string;
155
+ template_contains_nonce: boolean;
138
156
  trailing_slash: TrailingSlash;
139
157
  }
140
158
 
141
159
  export interface SSRRenderState {
142
160
  fetched?: string;
143
161
  initiator?: SSRPage | null;
162
+ platform?: any;
144
163
  prerender?: PrerenderOptions;
145
164
  fallback?: string;
146
165
  }
@@ -228,7 +247,5 @@ export interface MethodOverride {
228
247
  }
229
248
 
230
249
  export interface Respond {
231
- (request: Request, options: SSRRenderOptions, state?: SSRRenderState): Promise<
232
- Response | undefined
233
- >;
250
+ (request: Request, options: SSRRenderOptions, state?: SSRRenderState): Promise<Response>;
234
251
  }