@sveltejs/kit 1.0.0-next.326 → 1.0.0-next.329

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.
@@ -996,8 +996,10 @@ function create_client({ target, session, base, trailing_slash }) {
996
996
  /** @type {Error | null} */
997
997
  let error = null;
998
998
 
999
- // preload modules
1000
- a.forEach((loader) => loader());
999
+ // preload modules to avoid waterfall, but handle rejections
1000
+ // so they don't get reported to Sentry et al (we don't need
1001
+ // to act on the failures at this point)
1002
+ a.forEach((loader) => loader().catch(() => {}));
1001
1003
 
1002
1004
  load: for (let i = 0; i < a.length; i += 1) {
1003
1005
  /** @type {import('./types').BranchNode | undefined} */
@@ -3142,13 +3142,7 @@ async function respond(request, options, state) {
3142
3142
 
3143
3143
  if (is_data_request) {
3144
3144
  decoded = decoded.slice(0, -DATA_SUFFIX.length) || '/';
3145
-
3146
- const normalized = normalize_path(
3147
- url.pathname.slice(0, -DATA_SUFFIX.length),
3148
- options.trailing_slash
3149
- );
3150
-
3151
- url = new URL(url.origin + normalized + url.search);
3145
+ url = new URL(url.origin + url.pathname.slice(0, -DATA_SUFFIX.length) + url.search);
3152
3146
  }
3153
3147
 
3154
3148
  if (!state.prerender || !state.prerender.fallback) {
@@ -3174,6 +3168,7 @@ async function respond(request, options, state) {
3174
3168
  return new Response(undefined, {
3175
3169
  status: 301,
3176
3170
  headers: {
3171
+ 'x-sveltekit-normalize': '1',
3177
3172
  location:
3178
3173
  // ensure paths starting with '//' are not treated as protocol-relative
3179
3174
  (normalized.startsWith('//') ? url.origin + normalized : normalized) +
@@ -1,7 +1,7 @@
1
1
  import path__default from 'path';
2
2
  import { svelte } from '@sveltejs/vite-plugin-svelte';
3
3
  import vite from 'vite';
4
- import { n as normalize_path, d as deep_merge } from './url.js';
4
+ import { d as deep_merge } from './object.js';
5
5
  import { g as get_runtime_path, r as resolve_entry, $, l as load_template, c as coalesce_to_error, a as get_mime_lookup, b as get_aliases, p as print_config_conflicts } from '../cli.js';
6
6
  import fs__default from 'fs';
7
7
  import { URL } from 'url';
@@ -23,8 +23,13 @@ import 'node:zlib';
23
23
  import 'node:stream';
24
24
  import 'node:util';
25
25
  import 'node:url';
26
+ import './write_tsconfig.js';
26
27
  import 'stream';
27
28
 
29
+ // Vite doesn't expose this so we just copy the list for now
30
+ // https://github.com/vitejs/vite/blob/3edd1af56e980aef56641a5a51cf2932bb580d41/packages/vite/src/node/plugins/css.ts#L96
31
+ const style_pattern = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/;
32
+
28
33
  /**
29
34
  * @param {import('types').ValidatedConfig} config
30
35
  * @param {string} cwd
@@ -89,9 +94,8 @@ async function create_plugin(config, cwd) {
89
94
  const parsed = new URL(dep.url, 'http://localhost/');
90
95
  const query = parsed.searchParams;
91
96
 
92
- // TODO what about .scss files, etc?
93
97
  if (
94
- dep.file.endsWith('.css') ||
98
+ style_pattern.test(dep.file) ||
95
99
  (query.has('svelte') && query.get('type') === 'style')
96
100
  ) {
97
101
  try {
@@ -215,11 +219,7 @@ async function create_plugin(config, cwd) {
215
219
  if (req.url === '/favicon.ico') return not_found(res);
216
220
 
217
221
  if (!decoded.startsWith(config.kit.paths.base)) {
218
- const suggestion = normalize_path(
219
- config.kit.paths.base + req.url,
220
- config.kit.trailingSlash
221
- );
222
- return not_found(res, `Not found (did you mean ${suggestion}?)`);
222
+ return not_found(res, `Not found (did you mean ${config.kit.paths.base + req.url}?)`);
223
223
  }
224
224
 
225
225
  /** @type {Partial<import('types').Hooks>} */
@@ -6,10 +6,11 @@ import { p as print_config_conflicts, b as get_aliases, r as resolve_entry, g as
6
6
  import { g as generate_manifest } from './index3.js';
7
7
  import vite from 'vite';
8
8
  import { s } from './misc.js';
9
- import { n as normalize_path, d as deep_merge, r as resolve, i as is_root_relative } from './url.js';
9
+ import { d as deep_merge } from './object.js';
10
10
  import { svelte } from '@sveltejs/vite-plugin-svelte';
11
11
  import { pathToFileURL, URL as URL$1 } from 'url';
12
12
  import { installFetch } from '../install-fetch.js';
13
+ import './write_tsconfig.js';
13
14
  import 'sade';
14
15
  import 'child_process';
15
16
  import 'net';
@@ -21,6 +22,61 @@ import 'node:stream';
21
22
  import 'node:util';
22
23
  import 'node:url';
23
24
 
25
+ const absolute = /^([a-z]+:)?\/?\//;
26
+ const scheme = /^[a-z]+:/;
27
+
28
+ /**
29
+ * @param {string} base
30
+ * @param {string} path
31
+ */
32
+ function resolve(base, path) {
33
+ if (scheme.test(path)) return path;
34
+
35
+ const base_match = absolute.exec(base);
36
+ const path_match = absolute.exec(path);
37
+
38
+ if (!base_match) {
39
+ throw new Error(`bad base path: "${base}"`);
40
+ }
41
+
42
+ const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/');
43
+ const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/');
44
+
45
+ baseparts.pop();
46
+
47
+ for (let i = 0; i < pathparts.length; i += 1) {
48
+ const part = pathparts[i];
49
+ if (part === '.') continue;
50
+ else if (part === '..') baseparts.pop();
51
+ else baseparts.push(part);
52
+ }
53
+
54
+ const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || '';
55
+
56
+ return `${prefix}${baseparts.join('/')}`;
57
+ }
58
+
59
+ /** @param {string} path */
60
+ function is_root_relative(path) {
61
+ return path[0] === '/' && path[1] !== '/';
62
+ }
63
+
64
+ /**
65
+ * @param {string} path
66
+ * @param {import('types').TrailingSlash} trailing_slash
67
+ */
68
+ function normalize_path(path, trailing_slash) {
69
+ if (path === '/' || trailing_slash === 'ignore') return path;
70
+
71
+ if (trailing_slash === 'never') {
72
+ return path.endsWith('/') ? path.slice(0, -1) : path;
73
+ } else if (trailing_slash === 'always' && !path.endsWith('/')) {
74
+ return path + '/';
75
+ }
76
+
77
+ return path;
78
+ }
79
+
24
80
  /**
25
81
  * @param {{
26
82
  * cwd: string;
@@ -1044,7 +1100,7 @@ async function prerender({ config, entries, files, log }) {
1044
1100
  }
1045
1101
 
1046
1102
  if (is_html && !file.endsWith('.html')) {
1047
- return file + (config.kit.trailingSlash === 'always' ? 'index.html' : '.html');
1103
+ return file + (file.endsWith('/') ? 'index.html' : '.html');
1048
1104
  }
1049
1105
 
1050
1106
  return file;
@@ -1119,11 +1175,8 @@ async function prerender({ config, entries, files, log }) {
1119
1175
  const resolved = resolve(encoded, href);
1120
1176
  if (!is_root_relative(resolved)) continue;
1121
1177
 
1122
- const parsed = new URL$1(resolved, 'http://localhost');
1123
-
1124
- if (parsed.search) ;
1178
+ const { pathname, search } = new URL$1(resolved, 'http://localhost');
1125
1179
 
1126
- const pathname = normalize_path(parsed.pathname, config.kit.trailingSlash);
1127
1180
  enqueue(decoded, decodeURI(pathname), pathname);
1128
1181
  }
1129
1182
  }
@@ -1153,28 +1206,29 @@ async function prerender({ config, entries, files, log }) {
1153
1206
  const location = response.headers.get('location');
1154
1207
 
1155
1208
  if (location) {
1156
- mkdirp(dirname(dest));
1157
-
1158
- log.warn(`${response.status} ${decoded} -> ${location}`);
1159
-
1160
- writeFileSync(
1161
- dest,
1162
- `<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
1163
- );
1164
-
1165
- let resolved = resolve(encoded, location);
1209
+ const resolved = resolve(encoded, location);
1166
1210
  if (is_root_relative(resolved)) {
1167
- resolved = normalize_path(resolved, config.kit.trailingSlash);
1168
1211
  enqueue(decoded, decodeURI(resolved), resolved);
1169
1212
  }
1170
1213
 
1171
- if (!prerendered.redirects.has(decoded)) {
1172
- prerendered.redirects.set(decoded, {
1173
- status: response.status,
1174
- location: resolved
1175
- });
1214
+ if (!response.headers.get('x-sveltekit-normalize')) {
1215
+ mkdirp(dirname(dest));
1176
1216
 
1177
- prerendered.paths.push(normalize_path(decoded, 'never'));
1217
+ log.warn(`${response.status} ${decoded} -> ${location}`);
1218
+
1219
+ writeFileSync(
1220
+ dest,
1221
+ `<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
1222
+ );
1223
+
1224
+ if (!prerendered.redirects.has(decoded)) {
1225
+ prerendered.redirects.set(decoded, {
1226
+ status: response.status,
1227
+ location: resolved
1228
+ });
1229
+
1230
+ prerendered.paths.push(normalize_path(decoded, 'never'));
1231
+ }
1178
1232
  }
1179
1233
  } else {
1180
1234
  log.warn(`location header missing on redirect received from ${decoded}`);
@@ -1209,10 +1263,10 @@ async function prerender({ config, entries, files, log }) {
1209
1263
  for (const entry of config.kit.prerender.entries) {
1210
1264
  if (entry === '*') {
1211
1265
  for (const entry of entries) {
1212
- enqueue(null, normalize_path(config.kit.paths.base + entry, config.kit.trailingSlash)); // TODO can we pre-normalize these?
1266
+ enqueue(null, config.kit.paths.base + entry); // TODO can we pre-normalize these?
1213
1267
  }
1214
1268
  } else {
1215
- enqueue(null, normalize_path(config.kit.paths.base + entry, config.kit.trailingSlash));
1269
+ enqueue(null, config.kit.paths.base + entry);
1216
1270
  }
1217
1271
  }
1218
1272
 
@@ -79,6 +79,18 @@ async function preview({ port, host, config, https: use_https = false }) {
79
79
  })
80
80
  ),
81
81
 
82
+ (req, res, next) => {
83
+ const original_url = /** @type {string} */ (req.url);
84
+ const { pathname } = new URL(original_url, 'http://dummy');
85
+
86
+ if (pathname.startsWith(base)) {
87
+ next();
88
+ } else {
89
+ res.statusCode = 404;
90
+ res.end(`Not found (did you mean ${base + pathname}?)`);
91
+ }
92
+ },
93
+
82
94
  // prerendered dependencies
83
95
  scoped(base, mutable(join(config.kit.outDir, 'output/prerendered/dependencies'))),
84
96
 
@@ -5,6 +5,7 @@ import { $ } from '../cli.js';
5
5
  import chokidar from 'chokidar';
6
6
  import { w as walk$1, m as mkdirp, p as posixify, r as rimraf, c as copy } from './filesystem.js';
7
7
  import { createRequire } from 'module';
8
+ import { a as write_tsconfig } from './write_tsconfig.js';
8
9
  import 'sade';
9
10
  import 'child_process';
10
11
  import 'net';
@@ -15547,6 +15548,9 @@ async function build(config, cwd = process.cwd()) {
15547
15548
  rimraf(dir);
15548
15549
  mkdirp(dir);
15549
15550
 
15551
+ // Make sure generated tsconfig is up-to-date
15552
+ write_tsconfig(config);
15553
+
15550
15554
  const files = scan(config);
15551
15555
 
15552
15556
  if (config.kit.package.emitTypes) {
@@ -80,59 +80,4 @@ function merge_into(a, b, conflicts = [], path = []) {
80
80
  }
81
81
  }
82
82
 
83
- const absolute = /^([a-z]+:)?\/?\//;
84
- const scheme = /^[a-z]+:/;
85
-
86
- /**
87
- * @param {string} base
88
- * @param {string} path
89
- */
90
- function resolve(base, path) {
91
- if (scheme.test(path)) return path;
92
-
93
- const base_match = absolute.exec(base);
94
- const path_match = absolute.exec(path);
95
-
96
- if (!base_match) {
97
- throw new Error(`bad base path: "${base}"`);
98
- }
99
-
100
- const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/');
101
- const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/');
102
-
103
- baseparts.pop();
104
-
105
- for (let i = 0; i < pathparts.length; i += 1) {
106
- const part = pathparts[i];
107
- if (part === '.') continue;
108
- else if (part === '..') baseparts.pop();
109
- else baseparts.push(part);
110
- }
111
-
112
- const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || '';
113
-
114
- return `${prefix}${baseparts.join('/')}`;
115
- }
116
-
117
- /** @param {string} path */
118
- function is_root_relative(path) {
119
- return path[0] === '/' && path[1] !== '/';
120
- }
121
-
122
- /**
123
- * @param {string} path
124
- * @param {import('types').TrailingSlash} trailing_slash
125
- */
126
- function normalize_path(path, trailing_slash) {
127
- if (path === '/' || trailing_slash === 'ignore') return path;
128
-
129
- if (trailing_slash === 'never') {
130
- return path.endsWith('/') ? path.slice(0, -1) : path;
131
- } else if (trailing_slash === 'always' && !path.endsWith('/')) {
132
- return path + '/';
133
- }
134
-
135
- return path;
136
- }
137
-
138
- export { deep_merge as d, is_root_relative as i, normalize_path as n, resolve as r };
83
+ export { deep_merge as d };
@@ -1,9 +1,10 @@
1
1
  import path__default from 'path';
2
2
  import fs__default from 'fs';
3
- import { g as get_runtime_path, $ } from '../cli.js';
4
- import { p as posixify, c as copy, m as mkdirp } from './filesystem.js';
3
+ import { g as get_runtime_path } from '../cli.js';
4
+ import { p as posixify, c as copy } from './filesystem.js';
5
5
  import { p as parse_route_id, s } from './misc.js';
6
6
  import { fileURLToPath } from 'url';
7
+ import { w as write_if_changed, t as trim, a as write_tsconfig } from './write_tsconfig.js';
7
8
  import 'sade';
8
9
  import 'child_process';
9
10
  import 'net';
@@ -581,28 +582,6 @@ function copy_assets(dest) {
581
582
  } while (true); // eslint-disable-line
582
583
  }
583
584
 
584
- /** @type {Map<string, string>} */
585
- const previous_contents = new Map();
586
-
587
- /**
588
- * @param {string} file
589
- * @param {string} code
590
- */
591
- function write_if_changed(file, code) {
592
- if (code !== previous_contents.get(file)) {
593
- previous_contents.set(file, code);
594
- mkdirp(path__default.dirname(file));
595
- fs__default.writeFileSync(file, code);
596
- }
597
- }
598
-
599
- /** @param {string} str */
600
- function trim(str) {
601
- const indentation = /** @type {RegExpExecArray} */ (/\n?(\s*)/.exec(str))[1];
602
- const pattern = new RegExp(`^${indentation}`, 'gm');
603
- return str.replace(pattern, '').trim();
604
- }
605
-
606
585
  /**
607
586
  * @param {import('types').ManifestData} manifest_data
608
587
  * @param {string} base
@@ -763,128 +742,6 @@ function write_root(manifest_data, output) {
763
742
  );
764
743
  }
765
744
 
766
- /** @param {string} file */
767
- const exists = (file) => fs__default.existsSync(file) && file;
768
-
769
- /** @param {import('types').ValidatedConfig} config */
770
- function write_tsconfig(config) {
771
- const out = path__default.join(config.kit.outDir, 'tsconfig.json');
772
- const user_file = exists('tsconfig.json') || exists('jsconfig.json');
773
-
774
- if (user_file) validate(config, out, user_file);
775
-
776
- /** @param {string} file */
777
- const project_relative = (file) => posixify(path__default.relative('.', file));
778
-
779
- /** @param {string} file */
780
- const config_relative = (file) => posixify(path__default.relative(config.kit.outDir, file));
781
-
782
- const dirs = new Set([
783
- project_relative(path__default.dirname(config.kit.files.routes)),
784
- project_relative(path__default.dirname(config.kit.files.lib))
785
- ]);
786
-
787
- /** @type {string[]} */
788
- const include = [];
789
- dirs.forEach((dir) => {
790
- include.push(config_relative(`${dir}/**/*.js`));
791
- include.push(config_relative(`${dir}/**/*.ts`));
792
- include.push(config_relative(`${dir}/**/*.svelte`));
793
- });
794
-
795
- write_if_changed(
796
- out,
797
- JSON.stringify(
798
- {
799
- compilerOptions: {
800
- // generated options
801
- baseUrl: config_relative('.'),
802
- paths: fs__default.existsSync(config.kit.files.lib)
803
- ? {
804
- $lib: [project_relative(config.kit.files.lib)],
805
- '$lib/*': [project_relative(config.kit.files.lib + '/*')]
806
- }
807
- : {},
808
- rootDirs: [config_relative('.'), './types'],
809
-
810
- // essential options
811
- // svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
812
- // to enforce using \`import type\` instead of \`import\` for Types.
813
- importsNotUsedAsValues: 'error',
814
- // Vite compiles modules one at a time
815
- isolatedModules: true,
816
- // TypeScript doesn't know about import usages in the template because it only sees the
817
- // script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher.
818
- preserveValueImports: true,
819
-
820
- // This is required for svelte-kit package to work as expected
821
- // Can be overwritten
822
- lib: ['esnext', 'DOM'],
823
- moduleResolution: 'node',
824
- module: 'esnext',
825
- target: 'esnext'
826
- },
827
- include,
828
- exclude: [config_relative('node_modules/**'), './**']
829
- },
830
- null,
831
- '\t'
832
- )
833
- );
834
- }
835
-
836
- /**
837
- * @param {import('types').ValidatedConfig} config
838
- * @param {string} out
839
- * @param {string} user_file
840
- */
841
- function validate(config, out, user_file) {
842
- // we have to eval the file, since it's not parseable as JSON (contains comments)
843
- const user_tsconfig_json = fs__default.readFileSync(user_file, 'utf-8');
844
- const user_tsconfig = (0, eval)(`(${user_tsconfig_json})`);
845
-
846
- // we need to check that the user's tsconfig extends the framework config
847
- const extend = user_tsconfig.extends;
848
- const extends_framework_config = extend && path__default.resolve('.', extend) === out;
849
-
850
- if (extends_framework_config) {
851
- const { paths: user_paths } = user_tsconfig.compilerOptions || {};
852
-
853
- if (user_paths && fs__default.existsSync(config.kit.files.lib)) {
854
- /** @type {string[]} */
855
- const lib = user_paths['$lib'] || [];
856
- /** @type {string[]} */
857
- const lib_ = user_paths['$lib/*'] || [];
858
-
859
- const missing_lib_paths =
860
- !lib.some((relative) => path__default.resolve('.', relative) === config.kit.files.lib) ||
861
- !lib_.some(
862
- (relative) => path__default.resolve('.', relative) === path__default.join(config.kit.files.lib, '/*')
863
- );
864
-
865
- if (missing_lib_paths) {
866
- console.warn(
867
- $
868
- .bold()
869
- .yellow(`Your compilerOptions.paths in ${user_file} should include the following:`)
870
- );
871
- const relative = posixify(path__default.relative('.', config.kit.files.lib));
872
- console.warn(`{\n "$lib":["${relative}"],\n "$lib/*":["${relative}/*"]\n}`);
873
- }
874
- }
875
- } else {
876
- let relative = posixify(path__default.relative('.', out));
877
- if (!relative.startsWith('./')) relative = './' + relative;
878
-
879
- console.warn(
880
- $
881
- .bold()
882
- .yellow(`Your ${user_file} should extend the configuration generated by SvelteKit:`)
883
- );
884
- console.warn(`{\n "extends": "${relative}"\n}`);
885
- }
886
- }
887
-
888
745
  /** @param {string} imports */
889
746
  const header = (imports) => `
890
747
  // this file is auto-generated
@@ -892,7 +749,7 @@ import type { ${imports} } from '@sveltejs/kit';`;
892
749
 
893
750
  /** @param {string} arg */
894
751
  const endpoint = (arg) => `
895
- export type RequestHandler<Output extends ResponseBody = ResponseBody> = GenericRequestHandler<${arg}, Output>;`;
752
+ export type RequestHandler<Output = ResponseBody> = GenericRequestHandler<${arg}, Output>;`;
896
753
 
897
754
  /** @param {string} arg */
898
755
  const page = (arg) => `
@@ -0,0 +1,150 @@
1
+ import fs__default from 'fs';
2
+ import path__default from 'path';
3
+ import { $ } from '../cli.js';
4
+ import { m as mkdirp, p as posixify } from './filesystem.js';
5
+
6
+ /** @type {Map<string, string>} */
7
+ const previous_contents = new Map();
8
+
9
+ /**
10
+ * @param {string} file
11
+ * @param {string} code
12
+ */
13
+ function write_if_changed(file, code) {
14
+ if (code !== previous_contents.get(file)) {
15
+ previous_contents.set(file, code);
16
+ mkdirp(path__default.dirname(file));
17
+ fs__default.writeFileSync(file, code);
18
+ }
19
+ }
20
+
21
+ /** @param {string} str */
22
+ function trim(str) {
23
+ const indentation = /** @type {RegExpExecArray} */ (/\n?(\s*)/.exec(str))[1];
24
+ const pattern = new RegExp(`^${indentation}`, 'gm');
25
+ return str.replace(pattern, '').trim();
26
+ }
27
+
28
+ /** @param {string} file */
29
+ const exists = (file) => fs__default.existsSync(file) && file;
30
+
31
+ /** @param {import('types').ValidatedConfig} config */
32
+ function write_tsconfig(config) {
33
+ const out = path__default.join(config.kit.outDir, 'tsconfig.json');
34
+ const user_file = exists('tsconfig.json') || exists('jsconfig.json');
35
+
36
+ if (user_file) validate(config, out, user_file);
37
+
38
+ /** @param {string} file */
39
+ const project_relative = (file) => posixify(path__default.relative('.', file));
40
+
41
+ /** @param {string} file */
42
+ const config_relative = (file) => posixify(path__default.relative(config.kit.outDir, file));
43
+
44
+ const dirs = new Set([
45
+ project_relative(path__default.dirname(config.kit.files.routes)),
46
+ project_relative(path__default.dirname(config.kit.files.lib))
47
+ ]);
48
+
49
+ /** @type {string[]} */
50
+ const include = [];
51
+ dirs.forEach((dir) => {
52
+ include.push(config_relative(`${dir}/**/*.js`));
53
+ include.push(config_relative(`${dir}/**/*.ts`));
54
+ include.push(config_relative(`${dir}/**/*.svelte`));
55
+ });
56
+
57
+ write_if_changed(
58
+ out,
59
+ JSON.stringify(
60
+ {
61
+ compilerOptions: {
62
+ // generated options
63
+ baseUrl: config_relative('.'),
64
+ paths: fs__default.existsSync(config.kit.files.lib)
65
+ ? {
66
+ $lib: [project_relative(config.kit.files.lib)],
67
+ '$lib/*': [project_relative(config.kit.files.lib + '/*')]
68
+ }
69
+ : {},
70
+ rootDirs: [config_relative('.'), './types'],
71
+
72
+ // essential options
73
+ // svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
74
+ // to enforce using \`import type\` instead of \`import\` for Types.
75
+ importsNotUsedAsValues: 'error',
76
+ // Vite compiles modules one at a time
77
+ isolatedModules: true,
78
+ // TypeScript doesn't know about import usages in the template because it only sees the
79
+ // script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher.
80
+ preserveValueImports: true,
81
+
82
+ // This is required for svelte-kit package to work as expected
83
+ // Can be overwritten
84
+ lib: ['esnext', 'DOM'],
85
+ moduleResolution: 'node',
86
+ module: 'esnext',
87
+ target: 'esnext'
88
+ },
89
+ include,
90
+ exclude: [config_relative('node_modules/**'), './**']
91
+ },
92
+ null,
93
+ '\t'
94
+ )
95
+ );
96
+ }
97
+
98
+ /**
99
+ * @param {import('types').ValidatedConfig} config
100
+ * @param {string} out
101
+ * @param {string} user_file
102
+ */
103
+ function validate(config, out, user_file) {
104
+ // we have to eval the file, since it's not parseable as JSON (contains comments)
105
+ const user_tsconfig_json = fs__default.readFileSync(user_file, 'utf-8');
106
+ const user_tsconfig = (0, eval)(`(${user_tsconfig_json})`);
107
+
108
+ // we need to check that the user's tsconfig extends the framework config
109
+ const extend = user_tsconfig.extends;
110
+ const extends_framework_config = extend && path__default.resolve('.', extend) === out;
111
+
112
+ if (extends_framework_config) {
113
+ const { paths: user_paths } = user_tsconfig.compilerOptions || {};
114
+
115
+ if (user_paths && fs__default.existsSync(config.kit.files.lib)) {
116
+ /** @type {string[]} */
117
+ const lib = user_paths['$lib'] || [];
118
+ /** @type {string[]} */
119
+ const lib_ = user_paths['$lib/*'] || [];
120
+
121
+ const missing_lib_paths =
122
+ !lib.some((relative) => path__default.resolve('.', relative) === config.kit.files.lib) ||
123
+ !lib_.some(
124
+ (relative) => path__default.resolve('.', relative) === path__default.join(config.kit.files.lib, '/*')
125
+ );
126
+
127
+ if (missing_lib_paths) {
128
+ console.warn(
129
+ $
130
+ .bold()
131
+ .yellow(`Your compilerOptions.paths in ${user_file} should include the following:`)
132
+ );
133
+ const relative = posixify(path__default.relative('.', config.kit.files.lib));
134
+ console.warn(`{\n "$lib":["${relative}"],\n "$lib/*":["${relative}/*"]\n}`);
135
+ }
136
+ }
137
+ } else {
138
+ let relative = posixify(path__default.relative('.', out));
139
+ if (!relative.startsWith('./')) relative = './' + relative;
140
+
141
+ console.warn(
142
+ $
143
+ .bold()
144
+ .yellow(`Your ${user_file} should extend the configuration generated by SvelteKit:`)
145
+ );
146
+ console.warn(`{\n "extends": "${relative}"\n}`);
147
+ }
148
+ }
149
+
150
+ export { write_tsconfig as a, trim as t, write_if_changed as w };
package/dist/cli.js CHANGED
@@ -870,7 +870,7 @@ async function launch(port, https, base) {
870
870
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}${base}`);
871
871
  }
872
872
 
873
- const prog = sade('svelte-kit').version('1.0.0-next.326');
873
+ const prog = sade('svelte-kit').version('1.0.0-next.329');
874
874
 
875
875
  prog
876
876
  .command('dev')
@@ -1049,7 +1049,7 @@ async function check_port(port) {
1049
1049
  function welcome({ port, host, https, open, base, loose, allow, cwd }) {
1050
1050
  if (open) launch(port, https, base);
1051
1051
 
1052
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.326'}\n`));
1052
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.329'}\n`));
1053
1053
 
1054
1054
  const protocol = https ? 'https:' : 'http:';
1055
1055
  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.326",
3
+ "version": "1.0.0-next.329",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -151,7 +151,7 @@ declare module '$app/navigation' {
151
151
  */
152
152
  declare module '$app/paths' {
153
153
  /**
154
- * A string that matches [`config.kit.paths.base`](/docs/configuration#paths). It must begin, but not end, with a `/`.
154
+ * A string that matches [`config.kit.paths.base`](/docs/configuration#paths). It must start, but not end with `/` (e.g. `/base-path`), unless it is the empty string.
155
155
  */
156
156
  export const base: `/${string}`;
157
157
  /**
package/types/index.d.ts CHANGED
@@ -6,6 +6,7 @@ import './ambient';
6
6
  import { CompileOptions } from 'svelte/types/compiler/interfaces';
7
7
  import {
8
8
  AdapterEntry,
9
+ BodyValidator,
9
10
  CspDirectives,
10
11
  JSONValue,
11
12
  Logger,
@@ -136,7 +137,7 @@ export interface Config {
136
137
  crawl?: boolean;
137
138
  default?: boolean;
138
139
  enabled?: boolean;
139
- entries?: string[];
140
+ entries?: Array<'*' | `/${string}`>;
140
141
  onError?: PrerenderOnErrorValue;
141
142
  };
142
143
  routes?: (filepath: string) => boolean;
@@ -241,15 +242,15 @@ export interface ParamMatcher {
241
242
  */
242
243
  export interface RequestHandler<
243
244
  Params extends Record<string, string> = Record<string, string>,
244
- Output extends ResponseBody = ResponseBody
245
+ Output = ResponseBody
245
246
  > {
246
247
  (event: RequestEvent<Params>): MaybePromise<RequestHandlerOutput<Output>>;
247
248
  }
248
249
 
249
- export interface RequestHandlerOutput<Output extends ResponseBody = ResponseBody> {
250
+ export interface RequestHandlerOutput<Output = ResponseBody> {
250
251
  status?: number;
251
252
  headers?: Headers | Partial<ResponseHeaders>;
252
- body?: Output;
253
+ body?: Output extends ResponseBody ? Output : BodyValidator<Output>;
253
254
  }
254
255
 
255
256
  export type ResponseBody = JSONValue | Uint8Array | ReadableStream | import('stream').Readable;
@@ -26,6 +26,10 @@ export interface AdapterEntry {
26
26
  }) => MaybePromise<void>;
27
27
  }
28
28
 
29
+ export type BodyValidator<T> = {
30
+ [P in keyof T]: T[P] extends JSONValue ? BodyValidator<T[P]> : never;
31
+ };
32
+
29
33
  // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts
30
34
  //
31
35
  // MIT License