@sveltejs/kit 1.1.1 → 1.1.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
package/src/cli.js CHANGED
@@ -24,7 +24,7 @@ const prog = sade('svelte-kit').version(pkg.version);
24
24
 
25
25
  prog
26
26
  .command('sync')
27
- .describe('Synchronise generated files')
27
+ .describe('Synchronise generated type definitions')
28
28
  .option('--mode', 'Specify a mode for loading environment variables', 'development')
29
29
  .action(async ({ mode }) => {
30
30
  if (!fs.existsSync('svelte.config.js')) {
@@ -35,7 +35,7 @@ prog
35
35
  try {
36
36
  const config = await load_config();
37
37
  const sync = await import('./core/sync/sync.js');
38
- await sync.all(config, mode);
38
+ await sync.all_types(config, mode);
39
39
  } catch (error) {
40
40
  handle_error(error);
41
41
  }
@@ -51,7 +51,7 @@ export async function update(config, manifest_data, file) {
51
51
  }
52
52
 
53
53
  /**
54
- * Run sync.init and sync.update in series, returning the result from sync.update.
54
+ * Run sync.init and sync.create in series, returning the result from sync.create.
55
55
  * @param {import('types').ValidatedConfig} config
56
56
  * @param {string} mode The Vite mode
57
57
  */
@@ -60,6 +60,17 @@ export async function all(config, mode) {
60
60
  return await create(config);
61
61
  }
62
62
 
63
+ /**
64
+ * Run sync.init and then generate all type files.
65
+ * @param {import('types').ValidatedConfig} config
66
+ * @param {string} mode The Vite mode
67
+ */
68
+ export async function all_types(config, mode) {
69
+ init(config, mode);
70
+ const manifest_data = create_manifest_data({ config });
71
+ await write_all_types(config, manifest_data);
72
+ }
73
+
63
74
  /**
64
75
  * Regenerate server-internal.js in response to src/{app.html,error.html,service-worker.js} changing
65
76
  * @param {import('types').ValidatedConfig} config
@@ -35,19 +35,48 @@ function remove_trailing_slashstar(file) {
35
35
 
36
36
  /**
37
37
  * Writes the tsconfig that the user's tsconfig inherits from.
38
- * @param {import('types').ValidatedKitConfig} config
38
+ * @param {import('types').ValidatedKitConfig} kit
39
39
  */
40
- export function write_tsconfig(config, cwd = process.cwd()) {
41
- const out = path.join(config.outDir, 'tsconfig.json');
42
- const user_file = maybe_file(cwd, 'tsconfig.json') || maybe_file(cwd, 'jsconfig.json');
40
+ export function write_tsconfig(kit, cwd = process.cwd()) {
41
+ const out = path.join(kit.outDir, 'tsconfig.json');
42
+
43
+ const user_config = load_user_tsconfig(cwd);
44
+ if (user_config) validate_user_config(kit, cwd, out, user_config);
45
+
46
+ // only specify baseUrl if a) the user doesn't specify their own baseUrl
47
+ // and b) they have non-relative paths. this causes problems with auto-imports,
48
+ // so we print a suggestion that they use relative paths instead
49
+ // TODO(v2): never include base URL, and skip the check below
50
+ let include_base_url = false;
51
+
52
+ if (user_config && !user_config.options.compilerOptions?.baseUrl) {
53
+ const non_relative_paths = new Set();
54
+ for (const paths of Object.values(user_config?.options.compilerOptions?.paths || {})) {
55
+ for (const path of paths) {
56
+ if (!path.startsWith('.')) non_relative_paths.add(path);
57
+ }
58
+ }
59
+
60
+ if (non_relative_paths.size) {
61
+ include_base_url = true;
43
62
 
44
- if (user_file) validate(config, cwd, out, user_file);
63
+ console.log(colors.bold().yellow('Please replace non-relative compilerOptions.paths:\n'));
64
+
65
+ for (const path of non_relative_paths) {
66
+ console.log(` - "${path}" -> "./${path}"`);
67
+ }
68
+
69
+ console.log(
70
+ '\nDoing so allows us to omit "baseUrl" — which causes problems with imports — from the generated tsconfig.json. See https://github.com/sveltejs/kit/pull/8437 for more information.'
71
+ );
72
+ }
73
+ }
45
74
 
46
75
  /** @param {string} file */
47
- const config_relative = (file) => posixify(path.relative(config.outDir, file));
76
+ const config_relative = (file) => posixify(path.relative(kit.outDir, file));
48
77
 
49
78
  const include = ['ambient.d.ts', './types/**/$types.d.ts', config_relative('vite.config.ts')];
50
- for (const dir of [config.files.routes, config.files.lib]) {
79
+ for (const dir of [kit.files.routes, kit.files.lib]) {
51
80
  const relative = project_relative(path.dirname(dir));
52
81
  include.push(config_relative(`${relative}/**/*.js`));
53
82
  include.push(config_relative(`${relative}/**/*.ts`));
@@ -61,12 +90,12 @@ export function write_tsconfig(config, cwd = process.cwd()) {
61
90
  include.push(config_relative(`${test_folder}/**/*.svelte`));
62
91
 
63
92
  const exclude = [config_relative('node_modules/**'), './[!ambient.d.ts]**'];
64
- if (path.extname(config.files.serviceWorker)) {
65
- exclude.push(config_relative(config.files.serviceWorker));
93
+ if (path.extname(kit.files.serviceWorker)) {
94
+ exclude.push(config_relative(kit.files.serviceWorker));
66
95
  } else {
67
- exclude.push(config_relative(`${config.files.serviceWorker}.js`));
68
- exclude.push(config_relative(`${config.files.serviceWorker}.ts`));
69
- exclude.push(config_relative(`${config.files.serviceWorker}.d.ts`));
96
+ exclude.push(config_relative(`${kit.files.serviceWorker}.js`));
97
+ exclude.push(config_relative(`${kit.files.serviceWorker}.ts`));
98
+ exclude.push(config_relative(`${kit.files.serviceWorker}.d.ts`));
70
99
  }
71
100
 
72
101
  write_if_changed(
@@ -75,8 +104,8 @@ export function write_tsconfig(config, cwd = process.cwd()) {
75
104
  {
76
105
  compilerOptions: {
77
106
  // generated options
78
- baseUrl: config_relative('.'),
79
- paths: get_tsconfig_paths(config),
107
+ baseUrl: include_base_url ? config_relative('.') : undefined,
108
+ paths: get_tsconfig_paths(kit, include_base_url),
80
109
  rootDirs: [config_relative('.'), './types'],
81
110
 
82
111
  // essential options
@@ -105,43 +134,56 @@ export function write_tsconfig(config, cwd = process.cwd()) {
105
134
  );
106
135
  }
107
136
 
137
+ /** @param {string} cwd */
138
+ function load_user_tsconfig(cwd) {
139
+ const file = maybe_file(cwd, 'tsconfig.json') || maybe_file(cwd, 'jsconfig.json');
140
+
141
+ if (!file) return;
142
+
143
+ // we have to eval the file, since it's not parseable as JSON (contains comments)
144
+ const json = fs.readFileSync(file, 'utf-8');
145
+
146
+ return {
147
+ kind: path.basename(file),
148
+ options: (0, eval)(`(${json})`)
149
+ };
150
+ }
151
+
108
152
  /**
109
- * @param {import('types').ValidatedKitConfig} config
153
+ * @param {import('types').ValidatedKitConfig} kit
110
154
  * @param {string} cwd
111
155
  * @param {string} out
112
- * @param {string} user_file
156
+ * @param {{ kind: string, options: any }} config
113
157
  */
114
- function validate(config, cwd, out, user_file) {
115
- // we have to eval the file, since it's not parseable as JSON (contains comments)
116
- const user_tsconfig_json = fs.readFileSync(user_file, 'utf-8');
117
- const user_tsconfig = (0, eval)(`(${user_tsconfig_json})`);
118
-
158
+ function validate_user_config(kit, cwd, out, config) {
119
159
  // we need to check that the user's tsconfig extends the framework config
120
- const extend = user_tsconfig.extends;
160
+ const extend = config.options.extends;
121
161
  const extends_framework_config = extend && path.resolve(cwd, extend) === out;
122
162
 
123
- const kind = path.basename(user_file);
163
+ const options = config.options.compilerOptions || {};
124
164
 
125
165
  if (extends_framework_config) {
126
- const { paths: user_paths } = user_tsconfig.compilerOptions || {};
166
+ const { paths: user_paths } = options;
127
167
 
128
- if (user_paths && fs.existsSync(config.files.lib)) {
168
+ if (user_paths && fs.existsSync(kit.files.lib)) {
129
169
  /** @type {string[]} */
130
170
  const lib = user_paths['$lib'] || [];
131
171
  /** @type {string[]} */
132
172
  const lib_ = user_paths['$lib/*'] || [];
133
173
 
174
+ // TODO(v2): check needs to be adjusted when we remove the base path
134
175
  const missing_lib_paths =
135
- !lib.some((relative) => path.resolve(cwd, relative) === config.files.lib) ||
136
- !lib_.some((relative) => path.resolve(cwd, relative) === path.join(config.files.lib, '/*'));
176
+ !lib.some((relative) => path.resolve(cwd, relative) === kit.files.lib) ||
177
+ !lib_.some((relative) => path.resolve(cwd, relative) === path.join(kit.files.lib, '/*'));
137
178
 
138
179
  if (missing_lib_paths) {
139
180
  console.warn(
140
181
  colors
141
182
  .bold()
142
- .yellow(`Your compilerOptions.paths in ${kind} should include the following:`)
183
+ .yellow(`Your compilerOptions.paths in ${config.kind} should include the following:`)
143
184
  );
144
- const relative = posixify(path.relative('.', config.files.lib));
185
+ let relative = posixify(path.relative('.', kit.files.lib));
186
+ if (!relative.startsWith('.')) relative = `./${relative}`;
145
187
  console.warn(`{\n "$lib":["${relative}"],\n "$lib/*":["${relative}/*"]\n}`);
146
188
  }
147
189
  }
@@ -150,7 +192,9 @@ function validate(config, cwd, out, user_file) {
150
192
  if (!relative.startsWith('./')) relative = './' + relative;
151
193
 
152
194
  console.warn(
153
- colors.bold().yellow(`Your ${kind} should extend the configuration generated by SvelteKit:`)
195
+ colors
196
+ .bold()
197
+ .yellow(`Your ${config.kind} should extend the configuration generated by SvelteKit:`)
154
198
  );
155
199
  console.warn(`{\n "extends": "${relative}"\n}`);
156
200
  }
@@ -166,11 +210,13 @@ const value_regex = /^(.*?)((\/\*)|(\.\w+))?$/;
166
210
  * Related to vite alias creation.
167
211
  *
168
212
  * @param {import('types').ValidatedKitConfig} config
213
+ * @param {boolean} include_base_url
169
214
  */
170
- export function get_tsconfig_paths(config) {
171
- const alias = {
172
- ...config.alias
173
- };
215
+ export function get_tsconfig_paths(config, include_base_url) {
216
+ /** @param {string} file */
217
+ const config_relative = (file) => posixify(path.relative(config.outDir, file));
218
+
219
+ const alias = { ...config.alias };
174
220
  if (fs.existsSync(project_relative(config.files.lib))) {
175
221
  alias['$lib'] = project_relative(config.files.lib);
176
222
  }
@@ -185,7 +231,9 @@ export function get_tsconfig_paths(config) {
185
231
  const value_match = value_regex.exec(value);
186
232
  if (!value_match) throw new Error(`Invalid alias value: ${value}`);
187
233
 
188
- const rel_path = project_relative(remove_trailing_slashstar(value));
234
+ const rel_path = (include_base_url ? project_relative : config_relative)(
235
+ remove_trailing_slashstar(value)
236
+ );
189
237
  const slashstar = key_match[2];
190
238
 
191
239
  if (slashstar) {
@@ -48,8 +48,3 @@ export function json(data, init) {
48
48
  export function fail(status, data) {
49
49
  return new ActionFailure(status, data);
50
50
  }
51
-
52
- // TODO remove for 1.0
53
- export function invalid() {
54
- throw new Error('invalid(...) is now fail(...)');
55
- }
@@ -32,6 +32,7 @@ import { unwrap_promises } from '../../utils/promises.js';
32
32
  import * as devalue from 'devalue';
33
33
  import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY } from './constants.js';
34
34
  import { validate_common_exports } from '../../utils/exports.js';
35
+ import { compact } from '../../utils/array.js';
35
36
 
36
37
  const routes = parse(nodes, server_loads, dictionary, matchers);
37
38
 
@@ -414,8 +415,6 @@ export function create_client({ target, base }) {
414
415
  route,
415
416
  form
416
417
  }) {
417
- const filtered = /** @type {import('./types').BranchNode[] } */ (branch.filter(Boolean));
418
-
419
418
  /** @type {import('types').TrailingSlash} */
420
419
  let slash = 'never';
421
420
  for (const node of branch) {
@@ -436,7 +435,7 @@ export function create_client({ target, base }) {
436
435
  },
437
436
  props: {
438
437
  // @ts-ignore Somehow it's getting SvelteComponent and SvelteComponentDev mixed up
439
- components: filtered.map((branch_node) => branch_node.node.component)
438
+ components: compact(branch).map((branch_node) => branch_node.node.component)
440
439
  }
441
440
  };
442
441
 
@@ -446,21 +445,24 @@ export function create_client({ target, base }) {
446
445
 
447
446
  let data = {};
448
447
  let data_changed = !page;
449
- for (let i = 0; i < filtered.length; i += 1) {
450
- const node = filtered[i];
448
+
449
+ let p = 0;
450
+
451
+ for (let i = 0; i < Math.max(branch.length, current.branch.length); i += 1) {
452
+ const node = branch[i];
453
+ const prev = current.branch[i];
454
+
455
+ if (node?.data !== prev?.data) data_changed = true;
456
+ if (!node) continue;
457
+
451
458
  data = { ...data, ...node.data };
452
459
 
453
460
  // Only set props if the node actually updated. This prevents needless rerenders.
454
- if (data_changed || !current.branch.some((previous) => previous === node)) {
455
- result.props[`data_${i}`] = data;
456
- data_changed = data_changed || Object.keys(node.data ?? {}).length > 0;
461
+ if (data_changed) {
462
+ result.props[`data_${p}`] = data;
457
463
  }
458
- }
459
- if (!data_changed) {
460
- // If nothing was added, and the object entries are the same length, this means
461
- // that nothing was removed either and therefore the data is the same as the previous one.
462
- // This would be more readable with a separate boolean but that would cost us some bytes.
463
- data_changed = Object.keys(page.data).length !== Object.keys(data).length;
464
+
465
+ p += 1;
464
466
  }
465
467
 
466
468
  const page_changed =
@@ -1387,10 +1389,17 @@ export function create_client({ target, base }) {
1387
1389
  const a = find_anchor(/** @type {Element} */ (event.composedPath()[0]), container);
1388
1390
  if (!a) return;
1389
1391
 
1390
- const { url, external, has } = get_link_info(a, base);
1391
- const options = get_router_options(a);
1392
+ const { url, external, target } = get_link_info(a, base);
1392
1393
  if (!url) return;
1393
1394
 
1395
+ // bail out before `beforeNavigate` if link opens in a different tab
1396
+ if (target === '_parent' || target === '_top') {
1397
+ if (window.parent !== window) return;
1398
+ } else if (target && target !== '_self') {
1399
+ return;
1400
+ }
1401
+
1402
+ const options = get_router_options(a);
1394
1403
  const is_svg_a_element = a instanceof SVGAElement;
1395
1404
 
1396
1405
  // Ignore URL protocols that differ to the current one and are not http(s) (e.g. `mailto:`, `tel:`, `myapp:`, etc.)
@@ -1408,8 +1417,6 @@ export function create_client({ target, base }) {
1408
1417
  )
1409
1418
  return;
1410
1419
 
1411
- if (has.download) return;
1412
-
1413
1420
  // Ignore the following but fire beforeNavigate
1414
1421
  if (external || options.reload) {
1415
1422
  const navigation = before_navigate({ url, type: 'link' });
@@ -124,16 +124,16 @@ export function get_link_info(a, base) {
124
124
  url = new URL(a instanceof SVGAElement ? a.href.baseVal : a.href, document.baseURI);
125
125
  } catch {}
126
126
 
127
- const has = {
128
- rel_external: (a.getAttribute('rel') || '').split(/\s+/).includes('external'),
129
- download: a.hasAttribute('download'),
130
- target: !!(a instanceof SVGAElement ? a.target.baseVal : a.target)
131
- };
127
+ const target = a instanceof SVGAElement ? a.target.baseVal : a.target;
132
128
 
133
129
  const external =
134
- !url || is_external_url(url, base) || has.rel_external || has.target || has.download;
130
+ !url ||
131
+ !!target ||
132
+ is_external_url(url, base) ||
133
+ (a.getAttribute('rel') || '').split(/\s+/).includes('external') ||
134
+ a.hasAttribute('download');
135
135
 
136
- return { url, has, external };
136
+ return { url, external, target };
137
137
  }
138
138
 
139
139
  /**
@@ -11,9 +11,12 @@
11
11
  * }
12
12
  * }
13
13
  *
14
- * export default undefined;
14
+ * export {};
15
15
  * ```
16
16
  *
17
+ * The `export {}` line exists because without it, the file would be treated as an _ambient module_ which prevents you from adding `import` declarations.
18
+ * If you need to add ambient `declare module` declarations, do so in a separate file like `src/ambient.d.ts`.
19
+ *
17
20
  * By populating these interfaces, you will gain type safety when using `event.locals`, `event.platform`, and `data` from `load` functions.
18
21
  */
19
22
  declare namespace App {
@@ -243,7 +246,8 @@ declare module '$app/navigation' {
243
246
 
244
247
  /**
245
248
  * A navigation interceptor that triggers before we navigate to a new URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls.
246
- * Calling `cancel()` will prevent the navigation from completing.
249
+ * Calling `cancel()` will prevent the navigation from completing. If the navigation would have directly unloaded the current page, calling `cancel` will trigger the native
250
+ * browser unload confirmation dialog. In these cases, `navigation.willUnload` is `true`.
247
251
  *
248
252
  * When a navigation isn't client side, `navigation.to.route.id` will be `null`.
249
253
  *
package/types/index.d.ts CHANGED
@@ -1044,7 +1044,7 @@ export interface ServerLoadEvent<
1044
1044
 
1045
1045
  /**
1046
1046
  * Shape of a form action method that is part of `export const actions = {..}` in `+page.server.js`.
1047
- * See [form actions](https://kit-svelte-d4b3r0pff-svelte.vercel.app/docs/form-actions) for more information.
1047
+ * See [form actions](https://kit.svelte.dev/docs/form-actions) for more information.
1048
1048
  */
1049
1049
  export interface Action<
1050
1050
  Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,
@@ -1056,7 +1056,7 @@ export interface Action<
1056
1056
 
1057
1057
  /**
1058
1058
  * Shape of the `export const actions = {..}` object in `+page.server.js`.
1059
- * See [form actions](https://kit-svelte-d4b3r0pff-svelte.vercel.app/docs/form-actions) for more information.
1059
+ * See [form actions](https://kit.svelte.dev/docs/form-actions) for more information.
1060
1060
  */
1061
1061
  export type Actions<
1062
1062
  Params extends Partial<Record<string, string>> = Partial<Record<string, string>>,