@sveltejs/kit 1.0.0-next.316 → 1.0.0-next.319

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.
@@ -492,9 +492,6 @@ function create_client({ target, session, base, trailing_slash }) {
492
492
  });
493
493
  ready = true;
494
494
 
495
- /** Keeps tracks of multiple navigations caused by redirects during rendering */
496
- let navigating = 0;
497
-
498
495
  let router_enabled = true;
499
496
 
500
497
  // keeping track of the history index in order to prevent popstate navigation events if needed
@@ -529,9 +526,6 @@ function create_client({ target, session, base, trailing_slash }) {
529
526
  /** @type {{}} */
530
527
  let token;
531
528
 
532
- /** @type {{}} */
533
- let navigating_token;
534
-
535
529
  /**
536
530
  * @param {string} href
537
531
  * @param {{ noscroll?: boolean; replaceState?: boolean; keepfocus?: boolean; state?: any }} opts
@@ -577,6 +571,7 @@ function create_client({ target, session, base, trailing_slash }) {
577
571
  }
578
572
 
579
573
  /**
574
+ * Returns `true` if update completes, `false` if it is aborted
580
575
  * @param {URL} url
581
576
  * @param {string[]} redirect_chain
582
577
  * @param {boolean} no_cache
@@ -608,11 +603,11 @@ function create_client({ target, session, base, trailing_slash }) {
608
603
 
609
604
  if (!navigation_result) {
610
605
  await native_navigation(url);
611
- return; // unnecessary, but TypeScript prefers it this way
606
+ return false; // unnecessary, but TypeScript prefers it this way
612
607
  }
613
608
 
614
609
  // abort if user navigated during update
615
- if (token !== current_token) return;
610
+ if (token !== current_token) return false;
616
611
 
617
612
  invalidated.length = 0;
618
613
 
@@ -634,7 +629,7 @@ function create_client({ target, session, base, trailing_slash }) {
634
629
  await native_navigation(new URL(navigation_result.redirect, location.href));
635
630
  }
636
631
 
637
- return;
632
+ return false;
638
633
  }
639
634
  } else if (navigation_result.props?.page?.status >= 400) {
640
635
  const updated = await stores.updated.check();
@@ -717,6 +712,8 @@ function create_client({ target, session, base, trailing_slash }) {
717
712
 
718
713
  const leaf_node = navigation_result.state.branch[navigation_result.state.branch.length - 1];
719
714
  router_enabled = leaf_node?.module.router !== false;
715
+
716
+ return true;
720
717
  }
721
718
 
722
719
  /** @param {import('./types').NavigationResult} result */
@@ -1269,10 +1266,6 @@ function create_client({ target, session, base, trailing_slash }) {
1269
1266
 
1270
1267
  accepted();
1271
1268
 
1272
- navigating++;
1273
-
1274
- const current_navigating_token = (navigating_token = {});
1275
-
1276
1269
  if (started) {
1277
1270
  stores.navigating.set({
1278
1271
  from: current.url,
@@ -1280,18 +1273,13 @@ function create_client({ target, session, base, trailing_slash }) {
1280
1273
  });
1281
1274
  }
1282
1275
 
1283
- await update(normalized, redirect_chain, false, {
1276
+ const completed = await update(normalized, redirect_chain, false, {
1284
1277
  scroll,
1285
1278
  keepfocus,
1286
1279
  details
1287
1280
  });
1288
1281
 
1289
- navigating--;
1290
-
1291
- // navigation was aborted
1292
- if (navigating_token !== current_navigating_token) return;
1293
-
1294
- if (!navigating) {
1282
+ if (completed) {
1295
1283
  const navigation = { from, to: normalized };
1296
1284
  callbacks.after_navigate.forEach((fn) => fn(navigation));
1297
1285
 
@@ -1484,11 +1472,6 @@ function create_client({ target, session, base, trailing_slash }) {
1484
1472
  // Ignore if <a> has a target
1485
1473
  if (is_svg_a_element ? a.target.baseVal : a.target) return;
1486
1474
 
1487
- if (url.href === location.href) {
1488
- if (!location.hash) event.preventDefault();
1489
- return;
1490
- }
1491
-
1492
1475
  // Check if new url only differs by hash and use the browser default behavior in that case
1493
1476
  // This will ensure the `hashchange` event is fired
1494
1477
  // Removing the hash does a full page navigation in the browser, so make sure a hash is present
@@ -1513,7 +1496,7 @@ function create_client({ target, session, base, trailing_slash }) {
1513
1496
  redirect_chain: [],
1514
1497
  details: {
1515
1498
  state: {},
1516
- replaceState: false
1499
+ replaceState: url.href === location.href
1517
1500
  },
1518
1501
  accepted: () => event.preventDefault(),
1519
1502
  blocked: () => event.preventDefault()
@@ -42,11 +42,12 @@ function create_builder({ config, build_data, prerendered, log }) {
42
42
  config,
43
43
  prerendered,
44
44
 
45
- createEntries(fn) {
45
+ async createEntries(fn) {
46
46
  const { routes } = build_data.manifest_data;
47
47
 
48
48
  /** @type {import('types').RouteDefinition[]} */
49
49
  const facades = routes.map((route) => ({
50
+ id: route.id,
50
51
  type: route.type,
51
52
  segments: route.id.split('/').map((segment) => ({
52
53
  dynamic: segment.includes('['),
@@ -90,7 +91,7 @@ function create_builder({ config, build_data, prerendered, log }) {
90
91
  });
91
92
 
92
93
  if (filtered.size > 0) {
93
- complete({
94
+ await complete({
94
95
  generateManifest: ({ relativePath, format }) =>
95
96
  generate_manifest({
96
97
  build_data,
@@ -1,8 +1,10 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
- import { createRequire } from 'module';
3
+ import { join, relative, dirname } from 'path';
4
4
  import { $ } from '../cli.js';
5
- import { r as rimraf, m as mkdirp, w as walk$1 } from './filesystem.js';
5
+ import chokidar from 'chokidar';
6
+ import { w as walk$1, m as mkdirp, p as posixify, r as rimraf, c as copy } from './filesystem.js';
7
+ import { createRequire } from 'module';
6
8
  import 'sade';
7
9
  import 'child_process';
8
10
  import 'net';
@@ -15248,178 +15250,6 @@ async function preprocess(source, preprocessor, options) {
15248
15250
  return result.to_processed();
15249
15251
  }
15250
15252
 
15251
- const essential_files = ['README', 'LICENSE', 'CHANGELOG', '.gitignore', '.npmignore'];
15252
-
15253
- /**
15254
- * @param {import('types').ValidatedConfig} config
15255
- * @param {string} cwd
15256
- */
15257
- async function make_package(config, cwd = process.cwd()) {
15258
- if (!fs.existsSync(config.kit.files.lib)) {
15259
- throw new Error(`${config.kit.files.lib} does not exist`);
15260
- }
15261
-
15262
- const package_dir = path.isAbsolute(config.kit.package.dir)
15263
- ? config.kit.package.dir
15264
- : path.join(cwd, config.kit.package.dir);
15265
- rimraf(package_dir);
15266
- mkdirp(package_dir); // TODO https://github.com/sveltejs/kit/issues/2333
15267
-
15268
- if (config.kit.package.emitTypes) {
15269
- // Generate type definitions first so hand-written types can overwrite generated ones
15270
- await emit_dts(config);
15271
- // Resolve aliases, TS leaves them as-is
15272
- const files = walk$1(package_dir);
15273
- for (const file of files) {
15274
- const filename = path.join(package_dir, file);
15275
- const source = fs.readFileSync(filename, 'utf8');
15276
- fs.writeFileSync(filename, resolve_$lib_alias(file, source, config));
15277
- }
15278
- }
15279
-
15280
- const files = walk$1(config.kit.files.lib);
15281
-
15282
- const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
15283
-
15284
- delete pkg.scripts;
15285
- pkg.type = 'module';
15286
-
15287
- /** @type {Record<string, string>} */
15288
- const generated = { './package.json': './package.json' };
15289
-
15290
- /** @type {Record<string, string>} */
15291
- const clashes = {};
15292
- let contains_svelte_files = false;
15293
-
15294
- for (const file of files) {
15295
- const ext = path.extname(file);
15296
- const normalized = file.replace(/\\/g, '/');
15297
- const svelte_ext = config.extensions.find((ext) => file.endsWith(ext)); // unlike `ext`, could be e.g. `.svelte.md`
15298
-
15299
- if (!config.kit.package.files(normalized)) {
15300
- const base = svelte_ext ? file : file.slice(0, -ext.length);
15301
- for (const e of ['.d.ts', '.d.mts', '.d.cts']) {
15302
- const dts_path = path.join(package_dir, base + e);
15303
- if (fs.existsSync(dts_path)) {
15304
- fs.unlinkSync(dts_path);
15305
-
15306
- const dir = path.dirname(dts_path);
15307
- if (fs.readdirSync(dir).length === 0) {
15308
- fs.rmdirSync(dir);
15309
- }
15310
- }
15311
- }
15312
- continue;
15313
- }
15314
-
15315
- const filename = path.join(config.kit.files.lib, file);
15316
- const source = fs.readFileSync(filename);
15317
-
15318
- /** @type {string} */
15319
- let out_file;
15320
-
15321
- /** @type {string | Buffer} */
15322
- let out_contents;
15323
-
15324
- if (svelte_ext) {
15325
- // it's a Svelte component
15326
- contains_svelte_files = true;
15327
- out_file = file.slice(0, -svelte_ext.length) + '.svelte';
15328
- out_contents = source.toString('utf-8');
15329
- out_contents = config.preprocess
15330
- ? strip_lang_tags((await preprocess(out_contents, config.preprocess, { filename })).code)
15331
- : out_contents;
15332
- out_contents = resolve_$lib_alias(out_file, out_contents, config);
15333
- } else if (ext === '.ts' && file.endsWith('.d.ts')) {
15334
- // TypeScript's declaration emit won't copy over the d.ts files, so we do it here
15335
- out_file = file;
15336
- out_contents = source.toString('utf-8');
15337
- out_contents = resolve_$lib_alias(out_file, out_contents, config);
15338
- if (fs.existsSync(path.join(package_dir, out_file))) {
15339
- console.warn(
15340
- 'Found already existing file from d.ts generation for ' +
15341
- out_file +
15342
- '. This file will be overwritten.'
15343
- );
15344
- }
15345
- } else if (ext === '.ts') {
15346
- out_file = file.slice(0, -'.ts'.length) + '.js';
15347
- out_contents = await transpile_ts(filename, source.toString('utf-8'));
15348
- out_contents = resolve_$lib_alias(out_file, out_contents, config);
15349
- } else {
15350
- out_file = file;
15351
- out_contents = source;
15352
- }
15353
-
15354
- write(path.join(package_dir, out_file), out_contents);
15355
-
15356
- if (config.kit.package.exports(normalized)) {
15357
- const original = `$lib/${normalized}`;
15358
- const entry = `./${out_file.replace(/\\/g, '/')}`;
15359
- const key = entry.replace(/\/index\.js$|(\/[^/]+)\.js$/, '$1');
15360
-
15361
- if (clashes[key]) {
15362
- throw new Error(
15363
- `Duplicate "${key}" export. Please remove or rename either ${clashes[key]} or ${original}`
15364
- );
15365
- }
15366
-
15367
- generated[key] = entry;
15368
- clashes[key] = original;
15369
- }
15370
- }
15371
-
15372
- pkg.exports = { ...generated, ...pkg.exports };
15373
-
15374
- if (!pkg.svelte && contains_svelte_files) {
15375
- // Several heuristics in Kit/vite-plugin-svelte to tell Vite to mark Svelte packages
15376
- // rely on the "svelte" property. Vite/Rollup/Webpack plugin can all deal with it.
15377
- // See https://github.com/sveltejs/kit/issues/1959 for more info and related threads.
15378
- if (pkg.exports['.']) {
15379
- const svelte_export =
15380
- typeof pkg.exports['.'] === 'string'
15381
- ? pkg.exports['.']
15382
- : pkg.exports['.'].import || pkg.exports['.'].default;
15383
- if (svelte_export) {
15384
- pkg.svelte = svelte_export;
15385
- } else {
15386
- console.warn(
15387
- 'Cannot generate a "svelte" entry point because ' +
15388
- 'the "." entry in "exports" is not a string. ' +
15389
- 'If you set it by hand, please also set one of the options as a "svelte" entry point\n'
15390
- );
15391
- }
15392
- } else {
15393
- console.warn(
15394
- 'Cannot generate a "svelte" entry point because ' +
15395
- 'the "." entry in "exports" is missing. ' +
15396
- 'Please specify one or set a "svelte" entry point yourself\n'
15397
- );
15398
- }
15399
- }
15400
-
15401
- write(path.join(package_dir, 'package.json'), JSON.stringify(pkg, null, 2));
15402
-
15403
- const whitelist = fs.readdirSync(cwd).filter((file) => {
15404
- const lowercased = file.toLowerCase();
15405
- return essential_files.some((name) => lowercased.startsWith(name.toLowerCase()));
15406
- });
15407
- for (const pathname of whitelist) {
15408
- const full_path = path.join(cwd, pathname);
15409
- if (fs.lstatSync(full_path).isDirectory()) continue; // just to be sure
15410
-
15411
- const package_path = path.join(package_dir, pathname);
15412
- if (!fs.existsSync(package_path)) fs.copyFileSync(full_path, package_path);
15413
- }
15414
-
15415
- const from = path.relative(cwd, config.kit.files.lib);
15416
- const to = path.relative(cwd, config.kit.package.dir);
15417
- console.log($.bold().green(`${from} -> ${to}`));
15418
- console.log(`Successfully built '${pkg.name}' package. To publish it to npm:`);
15419
- console.log($.bold().cyan(` cd ${to}`));
15420
- console.log($.bold().cyan(' npm publish\n'));
15421
- }
15422
-
15423
15253
  /**
15424
15254
  * Resolves the `$lib` alias.
15425
15255
  *
@@ -15433,7 +15263,7 @@ async function make_package(config, cwd = process.cwd()) {
15433
15263
  * @param {import('types').ValidatedConfig} config
15434
15264
  * @returns {string}
15435
15265
  */
15436
- function resolve_$lib_alias(file, content, config) {
15266
+ function resolve_lib_alias(file, content, config) {
15437
15267
  /**
15438
15268
  * @param {string} match
15439
15269
  * @param {string} _
@@ -15446,7 +15276,7 @@ function resolve_$lib_alias(file, content, config) {
15446
15276
 
15447
15277
  const full_path = path.join(config.kit.files.lib, file);
15448
15278
  const full_import_path = path.join(config.kit.files.lib, import_path.slice('$lib/'.length));
15449
- let resolved = path.relative(path.dirname(full_path), full_import_path).replace(/\\/g, '/');
15279
+ let resolved = posixify(path.relative(path.dirname(full_path), full_import_path));
15450
15280
  resolved = resolved.startsWith('.') ? resolved : './' + resolved;
15451
15281
  return match.replace(import_path, resolved);
15452
15282
  };
@@ -15462,27 +15292,170 @@ function resolve_$lib_alias(file, content, config) {
15462
15292
  * @param {string} content
15463
15293
  */
15464
15294
  function strip_lang_tags(content) {
15465
- strip_lang_tag('script');
15466
- strip_lang_tag('style');
15467
- return content;
15295
+ return content
15296
+ .replace(/(<!--[^]*?-->)|(<script[^>]*?)\s(?:type|lang)=(["']).*?\3/g, '$1$2')
15297
+ .replace(/(<!--[^]*?-->)|(<style[^>]*?)\s(?:type|lang)=(["']).*?\3/g, '$1$2');
15298
+ }
15468
15299
 
15469
- /**
15470
- * @param {string} tagname
15471
- */
15472
- function strip_lang_tag(tagname) {
15473
- const regexp = new RegExp(
15474
- `/<!--[^]*?-->|<${tagname}(\\s[^]*?)?(?:>([^]*?)<\\/${tagname}>|\\/>)`,
15475
- 'g'
15300
+ /**
15301
+ * @param {string} file
15302
+ * @param {Parameters<typeof fs.writeFileSync>[1]} contents
15303
+ */
15304
+ function write(file, contents) {
15305
+ mkdirp(path.dirname(file));
15306
+ fs.writeFileSync(file, contents);
15307
+ }
15308
+
15309
+ /**
15310
+ * @param {import('types').ValidatedConfig} config
15311
+ * @returns {import('./types').File[]}
15312
+ */
15313
+ function scan(config) {
15314
+ return walk$1(config.kit.files.lib).map((file) => analyze(config, file));
15315
+ }
15316
+
15317
+ /**
15318
+ * @param {import('types').ValidatedConfig} config
15319
+ * @param {string} file
15320
+ * @returns {import('./types').File}
15321
+ */
15322
+ function analyze(config, file) {
15323
+ const name = posixify(file);
15324
+
15325
+ const svelte_extension = config.extensions.find((ext) => name.endsWith(ext));
15326
+
15327
+ const base = svelte_extension ? name : name.slice(0, -path.extname(name).length);
15328
+
15329
+ const dest = svelte_extension
15330
+ ? name.slice(0, -svelte_extension.length) + '.svelte'
15331
+ : name.endsWith('.d.ts')
15332
+ ? name
15333
+ : name.endsWith('.ts')
15334
+ ? name.slice(0, -3) + '.js'
15335
+ : name;
15336
+
15337
+ return {
15338
+ name,
15339
+ dest,
15340
+ base,
15341
+ is_included: config.kit.package.files(name),
15342
+ is_exported: config.kit.package.exports(name),
15343
+ is_svelte: !!svelte_extension
15344
+ };
15345
+ }
15346
+
15347
+ /**
15348
+ * @param {string} cwd
15349
+ * @param {import('./types').File[]} files
15350
+ */
15351
+ function generate_pkg(cwd, files) {
15352
+ const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf8'));
15353
+
15354
+ delete pkg.scripts;
15355
+ pkg.type = 'module';
15356
+
15357
+ pkg.exports = {
15358
+ './package.json': './package.json',
15359
+ ...pkg.exports
15360
+ };
15361
+
15362
+ /** @type {Record<string, string>} */
15363
+ const clashes = {};
15364
+
15365
+ for (const file of files) {
15366
+ if (file.is_included && file.is_exported) {
15367
+ const original = `$lib/${file.name}`;
15368
+ const entry = `./${file.dest}`;
15369
+ const key = entry.replace(/\/index\.js$|(\/[^/]+)\.js$/, '$1');
15370
+
15371
+ if (clashes[key]) {
15372
+ throw new Error(
15373
+ `Duplicate "${key}" export. Please remove or rename either ${clashes[key]} or ${original}`
15374
+ );
15375
+ }
15376
+
15377
+ if (!pkg.exports[key]) {
15378
+ pkg.exports[key] = entry;
15379
+ }
15380
+
15381
+ clashes[key] = original;
15382
+ }
15383
+ }
15384
+
15385
+ return pkg;
15386
+ }
15387
+
15388
+ /**
15389
+ * @param {import('types').ValidatedConfig} config
15390
+ * @param {string} cwd
15391
+ * @param {import('./types').File[]} files
15392
+ */
15393
+ async function emit_dts(config, cwd, files) {
15394
+ const tmp = `${config.kit.outDir}/package/types`;
15395
+ rimraf(tmp);
15396
+ mkdirp(tmp);
15397
+
15398
+ const require = createRequire(import.meta.url);
15399
+ const emit = await try_load_svelte2tsx();
15400
+ await emit({
15401
+ libRoot: config.kit.files.lib,
15402
+ svelteShimsPath: require.resolve('svelte2tsx/svelte-shims.d.ts'),
15403
+ declarationDir: path.relative(cwd, tmp)
15404
+ });
15405
+
15406
+ const handwritten = new Set();
15407
+ const excluded = new Set();
15408
+
15409
+ // remove excluded files, and files that conflict with hand-written .d.ts
15410
+ for (const file of files) {
15411
+ if (file.name.endsWith('.d.ts')) {
15412
+ handwritten.add(file.name);
15413
+ }
15414
+
15415
+ if (!file.is_included) {
15416
+ excluded.add(file.base + '.d.ts');
15417
+ excluded.add(file.base + '.d.mts');
15418
+ excluded.add(file.base + '.d.cts');
15419
+ }
15420
+ }
15421
+
15422
+ // resolve $lib alias (TODO others), copy into package dir
15423
+ for (const file of walk$1(tmp)) {
15424
+ const normalized = posixify(file);
15425
+
15426
+ if (handwritten.has(normalized)) {
15427
+ console.warn(`Using $lib/${normalized} instead of generated .d.ts file`);
15428
+ }
15429
+
15430
+ // don't overwrite hand-written .d.ts files
15431
+ if (excluded.has(normalized)) continue;
15432
+
15433
+ const source = fs.readFileSync(path.join(tmp, normalized), 'utf8');
15434
+ write(
15435
+ path.join(config.kit.package.dir, normalized),
15436
+ resolve_lib_alias(normalized, source, config)
15437
+ );
15438
+ }
15439
+ }
15440
+
15441
+ async function try_load_svelte2tsx() {
15442
+ const svelte2tsx = await load();
15443
+ const emit_dts = svelte2tsx.emitDts;
15444
+ if (!emit_dts) {
15445
+ throw new Error(
15446
+ 'You need to install svelte2tsx >=0.4.1 if you want to generate type definitions'
15476
15447
  );
15477
- content = content.replace(regexp, (tag, attributes) => {
15478
- if (!attributes) return tag;
15479
- const idx = tag.indexOf(attributes);
15480
- return (
15481
- tag.substring(0, idx) +
15482
- attributes.replace(/\s(type|lang)=(["']).*?\2/, ' ') +
15483
- tag.substring(idx + attributes.length)
15448
+ }
15449
+ return emit_dts;
15450
+
15451
+ async function load() {
15452
+ try {
15453
+ return await import('svelte2tsx');
15454
+ } catch (e) {
15455
+ throw new Error(
15456
+ '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'
15484
15457
  );
15485
- });
15458
+ }
15486
15459
  }
15487
15460
  }
15488
15461
 
@@ -15513,14 +15486,32 @@ async function try_load_ts() {
15513
15486
  * @param {import('typescript')} ts
15514
15487
  */
15515
15488
  function load_tsconfig(filename, ts) {
15516
- const filedir = path.dirname(filename);
15517
- const tsconfig_filename = ts.findConfigFile(filedir, ts.sys.fileExists);
15489
+ let config_filename;
15490
+
15491
+ // ts.findConfigFile is broken (it will favour a distant tsconfig
15492
+ // over a near jsconfig, and then only when you call it twice)
15493
+ // so we implement it ourselves
15494
+ let dir = filename;
15495
+ while (dir !== (dir = path.dirname(dir))) {
15496
+ const tsconfig = path.join(dir, 'tsconfig.json');
15497
+ const jsconfig = path.join(dir, 'jsconfig.json');
15498
+
15499
+ if (fs.existsSync(tsconfig)) {
15500
+ config_filename = tsconfig;
15501
+ break;
15502
+ }
15518
15503
 
15519
- if (!tsconfig_filename) {
15504
+ if (fs.existsSync(jsconfig)) {
15505
+ config_filename = jsconfig;
15506
+ break;
15507
+ }
15508
+ }
15509
+
15510
+ if (!config_filename) {
15520
15511
  throw new Error('Failed to locate tsconfig or jsconfig');
15521
15512
  }
15522
15513
 
15523
- const { error, config } = ts.readConfigFile(tsconfig_filename, ts.sys.readFile);
15514
+ const { error, config } = ts.readConfigFile(config_filename, ts.sys.readFile);
15524
15515
 
15525
15516
  if (error) {
15526
15517
  throw new Error('Malformed tsconfig\n' + JSON.stringify(error, null, 2));
@@ -15532,54 +15523,215 @@ function load_tsconfig(filename, ts) {
15532
15523
  const { options } = ts.parseJsonConfigFileContent(
15533
15524
  config,
15534
15525
  ts.sys,
15535
- path.dirname(tsconfig_filename),
15526
+ path.dirname(config_filename),
15536
15527
  { sourceMap: false },
15537
- tsconfig_filename
15528
+ config_filename
15538
15529
  );
15539
15530
  return options;
15540
15531
  }
15541
15532
 
15533
+ const essential_files = ['README', 'LICENSE', 'CHANGELOG', '.gitignore', '.npmignore'];
15534
+
15542
15535
  /**
15543
- * @param {string} file
15544
- * @param {Parameters<typeof fs.writeFileSync>[1]} contents
15536
+ * @param {import('types').ValidatedConfig} config
15537
+ * @param {string} cwd
15545
15538
  */
15546
- function write(file, contents) {
15547
- mkdirp(path.dirname(file));
15548
- fs.writeFileSync(file, contents);
15539
+ async function build(config, cwd = process.cwd()) {
15540
+ const { lib } = config.kit.files;
15541
+ const { dir } = config.kit.package;
15542
+
15543
+ if (!fs.existsSync(lib)) {
15544
+ throw new Error(`${lib} does not exist`);
15545
+ }
15546
+
15547
+ rimraf(dir);
15548
+ mkdirp(dir);
15549
+
15550
+ const files = scan(config);
15551
+
15552
+ if (config.kit.package.emitTypes) {
15553
+ await emit_dts(config, cwd, files);
15554
+ }
15555
+
15556
+ const pkg = generate_pkg(cwd, files);
15557
+
15558
+ if (!pkg.svelte && files.some((file) => file.is_svelte)) {
15559
+ // Several heuristics in Kit/vite-plugin-svelte to tell Vite to mark Svelte packages
15560
+ // rely on the "svelte" property. Vite/Rollup/Webpack plugin can all deal with it.
15561
+ // See https://github.com/sveltejs/kit/issues/1959 for more info and related threads.
15562
+ if (pkg.exports['.']) {
15563
+ const svelte_export =
15564
+ typeof pkg.exports['.'] === 'string'
15565
+ ? pkg.exports['.']
15566
+ : pkg.exports['.'].import || pkg.exports['.'].default;
15567
+ if (svelte_export) {
15568
+ pkg.svelte = svelte_export;
15569
+ } else {
15570
+ console.warn(
15571
+ 'Cannot generate a "svelte" entry point because the "." entry in "exports" is not a string. If you set it by hand, please also set one of the options as a "svelte" entry point\n'
15572
+ );
15573
+ }
15574
+ } else {
15575
+ console.warn(
15576
+ 'Cannot generate a "svelte" entry point because the "." entry in "exports" is missing. Please specify one or set a "svelte" entry point yourself\n'
15577
+ );
15578
+ }
15579
+ }
15580
+
15581
+ write(join(dir, 'package.json'), JSON.stringify(pkg, null, 2));
15582
+
15583
+ for (const file of files) {
15584
+ await process_file(config, file);
15585
+ }
15586
+
15587
+ const whitelist = fs.readdirSync(cwd).filter((file) => {
15588
+ const lowercased = file.toLowerCase();
15589
+ return essential_files.some((name) => lowercased.startsWith(name.toLowerCase()));
15590
+ });
15591
+
15592
+ for (const pathname of whitelist) {
15593
+ const full_path = join(cwd, pathname);
15594
+ if (fs.lstatSync(full_path).isDirectory()) continue; // just to be sure
15595
+
15596
+ const package_path = join(dir, pathname);
15597
+ if (!fs.existsSync(package_path)) fs.copyFileSync(full_path, package_path);
15598
+ }
15599
+
15600
+ const from = relative(cwd, lib);
15601
+ const to = relative(cwd, dir);
15602
+ console.log($.bold().green(`${from} -> ${to}`));
15603
+ console.log(`Successfully built '${pkg.name}' package. To publish it to npm:`);
15604
+ console.log($.bold().cyan(` cd ${to}`));
15605
+ console.log($.bold().cyan(' npm publish\n'));
15549
15606
  }
15550
15607
 
15551
15608
  /**
15552
15609
  * @param {import('types').ValidatedConfig} config
15553
15610
  */
15554
- async function emit_dts(config) {
15555
- const require = createRequire(import.meta.url);
15556
- const emit = await try_load_svelte2tsx();
15557
- await emit({
15558
- libRoot: config.kit.files.lib,
15559
- svelteShimsPath: require.resolve('svelte2tsx/svelte-shims.d.ts'),
15560
- declarationDir: config.kit.package.dir
15611
+ async function watch(config, cwd = process.cwd()) {
15612
+ await build(config, cwd);
15613
+
15614
+ const message = `\nWatching ${relative(cwd, config.kit.files.lib)} for changes...\n`;
15615
+
15616
+ console.log(message);
15617
+
15618
+ const { lib } = config.kit.files;
15619
+ const { dir } = config.kit.package;
15620
+
15621
+ /** @type {Array<{ file: import('./types').File, type: string }>} */
15622
+ const pending = [];
15623
+
15624
+ /** @type {Array<(value?: any) => void>} */
15625
+ const fulfillers = [];
15626
+
15627
+ /** @type {NodeJS.Timeout} */
15628
+ let timeout;
15629
+
15630
+ const watcher = chokidar.watch(lib, { ignoreInitial: true });
15631
+
15632
+ watcher.on('all', async (type, path) => {
15633
+ const file = analyze(config, relative(lib, path));
15634
+ if (!file.is_included) return;
15635
+
15636
+ pending.push({ file, type });
15637
+
15638
+ clearTimeout(timeout);
15639
+ timeout = setTimeout(async () => {
15640
+ const files = scan(config);
15641
+
15642
+ let should_update_pkg = false;
15643
+
15644
+ const events = pending.slice();
15645
+ pending.length = 0;
15646
+
15647
+ for (const { file, type } of events) {
15648
+ if ((type === 'unlink' || type === 'add') && file.is_exported) {
15649
+ should_update_pkg = true;
15650
+ }
15651
+
15652
+ if (type === 'unlink') {
15653
+ for (const candidate of [
15654
+ file.name,
15655
+ `${file.base}.d.ts`,
15656
+ `${file.base}.d.mts`,
15657
+ `${file.base}.d.cts`
15658
+ ]) {
15659
+ const resolved = join(dir, candidate);
15660
+
15661
+ if (fs.existsSync(resolved)) {
15662
+ fs.unlinkSync(resolved);
15663
+
15664
+ const parent = dirname(resolved);
15665
+ if (parent !== dir && fs.readdirSync(parent).length === 0) {
15666
+ fs.rmdirSync(parent);
15667
+ }
15668
+ }
15669
+ }
15670
+ console.log(`Removed ${file.dest}`);
15671
+ }
15672
+
15673
+ if (type === 'add' || type === 'change') {
15674
+ await process_file(config, file);
15675
+ console.log(`Processing ${file.name}`);
15676
+ }
15677
+ }
15678
+
15679
+ if (should_update_pkg) {
15680
+ const pkg = generate_pkg(cwd, files);
15681
+ write(join(dir, 'package.json'), JSON.stringify(pkg, null, 2));
15682
+ console.log('Updated package.json');
15683
+ }
15684
+
15685
+ if (config.kit.package.emitTypes) {
15686
+ await emit_dts(config, cwd, scan(config));
15687
+ console.log('Updated .d.ts files');
15688
+ }
15689
+
15690
+ console.log(message);
15691
+
15692
+ fulfillers.forEach((fn) => fn());
15693
+ }, 100);
15561
15694
  });
15695
+
15696
+ return {
15697
+ watcher,
15698
+ settled: () =>
15699
+ new Promise((fulfil, reject) => {
15700
+ fulfillers.push(fulfil);
15701
+ setTimeout(() => reject(new Error('Timed out')), 1000);
15702
+ })
15703
+ };
15562
15704
  }
15563
15705
 
15564
- async function try_load_svelte2tsx() {
15565
- const svelte2tsx = await load();
15566
- const emit_dts = svelte2tsx.emitDts;
15567
- if (!emit_dts) {
15568
- throw new Error(
15569
- 'You need to install svelte2tsx >=0.4.1 if you want to generate type definitions'
15570
- );
15571
- }
15572
- return emit_dts;
15706
+ /**
15707
+ * @param {import('types').ValidatedConfig} config
15708
+ * @param {import('./types').File} file
15709
+ */
15710
+ async function process_file(config, file) {
15711
+ if (!file.is_included) return;
15573
15712
 
15574
- async function load() {
15575
- try {
15576
- return await import('svelte2tsx');
15577
- } catch (e) {
15578
- throw new Error(
15579
- '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'
15580
- );
15713
+ const filename = join(config.kit.files.lib, file.name);
15714
+ const dest = join(config.kit.package.dir, file.dest);
15715
+
15716
+ if (file.is_svelte || file.name.endsWith('.ts')) {
15717
+ let contents = fs.readFileSync(filename, 'utf-8');
15718
+
15719
+ if (file.is_svelte) {
15720
+ if (config.preprocess) {
15721
+ const preprocessed = (await preprocess(contents, config.preprocess, { filename })).code;
15722
+ contents = strip_lang_tags(preprocessed);
15723
+ }
15724
+ }
15725
+
15726
+ if (file.name.endsWith('.ts') && !file.name.endsWith('.d.ts')) {
15727
+ contents = await transpile_ts(filename, contents);
15581
15728
  }
15729
+
15730
+ contents = resolve_lib_alias(file.name, contents, config);
15731
+ write(dest, contents);
15732
+ } else {
15733
+ copy(filename, dest);
15582
15734
  }
15583
15735
  }
15584
15736
 
15585
- export { emit_dts, make_package };
15737
+ export { build, watch };
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.316');
873
+ const prog = sade('svelte-kit').version('1.0.0-next.319');
874
874
 
875
875
  prog
876
876
  .command('dev')
@@ -981,13 +981,13 @@ prog
981
981
  prog
982
982
  .command('package')
983
983
  .describe('Create a package')
984
- .action(async () => {
984
+ .option('-w, --watch', 'Rerun when files change', false)
985
+ .action(async ({ watch }) => {
985
986
  try {
986
987
  const config = await load_config();
988
+ const packaging = await import('./chunks/index6.js');
987
989
 
988
- const { make_package } = await import('./chunks/index6.js');
989
-
990
- await make_package(config);
990
+ await (watch ? packaging.watch(config) : packaging.build(config));
991
991
  } catch (error) {
992
992
  handle_error(error);
993
993
  }
@@ -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.316'}\n`));
1052
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.319'}\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.316",
3
+ "version": "1.0.0-next.319",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -11,6 +11,7 @@
11
11
  "type": "module",
12
12
  "dependencies": {
13
13
  "@sveltejs/vite-plugin-svelte": "^1.0.0-next.32",
14
+ "chokidar": "^3.5.3",
14
15
  "sade": "^1.7.4",
15
16
  "vite": "^2.9.0"
16
17
  },
package/types/index.d.ts CHANGED
@@ -38,7 +38,7 @@ export interface Builder {
38
38
  * Create entry points that map to individual functions
39
39
  * @param fn A function that groups a set of routes into an entry point
40
40
  */
41
- createEntries(fn: (route: RouteDefinition) => AdapterEntry): void;
41
+ createEntries(fn: (route: RouteDefinition) => AdapterEntry): Promise<void>;
42
42
 
43
43
  generateManifest: (opts: { relativePath: string; format?: 'esm' | 'cjs' }) => string;
44
44
 
@@ -23,7 +23,7 @@ export interface AdapterEntry {
23
23
  */
24
24
  complete: (entry: {
25
25
  generateManifest: (opts: { relativePath: string; format?: 'esm' | 'cjs' }) => string;
26
- }) => void;
26
+ }) => MaybePromise<void>;
27
27
  }
28
28
 
29
29
  // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts
@@ -222,6 +222,7 @@ export interface ResolveOptions {
222
222
  export type ResponseHeaders = Record<string, string | number | string[]>;
223
223
 
224
224
  export interface RouteDefinition {
225
+ id: string;
225
226
  type: 'page' | 'endpoint';
226
227
  pattern: RegExp;
227
228
  segments: RouteSegment[];