@sveltejs/kit 1.0.0-next.264 → 1.0.0-next.265

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.
@@ -391,21 +391,21 @@ function escape_html_attr(str) {
391
391
  * @typedef {import('types/internal').Logger} Logger
392
392
  */
393
393
 
394
- /** @type {(errorDetails: Parameters<PrerenderErrorHandler>[0] ) => string} */
395
- function errorDetailsToString({ status, path, referrer, referenceType }) {
394
+ /** @type {(details: Parameters<PrerenderErrorHandler>[0] ) => string} */
395
+ function format_error({ status, path, referrer, referenceType }) {
396
396
  return `${status} ${path}${referrer ? ` (${referenceType} from ${referrer})` : ''}`;
397
397
  }
398
398
 
399
399
  /** @type {(log: Logger, onError: OnError) => PrerenderErrorHandler} */
400
- function chooseErrorHandler(log, onError) {
400
+ function normalise_error_handler(log, onError) {
401
401
  switch (onError) {
402
402
  case 'continue':
403
- return (errorDetails) => {
404
- log.error(errorDetailsToString(errorDetails));
403
+ return (details) => {
404
+ log.error(format_error(details));
405
405
  };
406
406
  case 'fail':
407
- return (errorDetails) => {
408
- throw new Error(errorDetailsToString(errorDetails));
407
+ return (details) => {
408
+ throw new Error(format_error(details));
409
409
  };
410
410
  default:
411
411
  return onError;
@@ -455,7 +455,7 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
455
455
 
456
456
  const app = new App(manifest);
457
457
 
458
- const error = chooseErrorHandler(log, config.kit.prerender.onError);
458
+ const error = normalise_error_handler(log, config.kit.prerender.onError);
459
459
 
460
460
  const files = new Set([
461
461
  ...build_data.static,
@@ -492,12 +492,15 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
492
492
  * @param {boolean} is_html
493
493
  */
494
494
  function output_filename(path, is_html) {
495
+ path = path.slice(config.kit.paths.base.length) || '/';
496
+
495
497
  if (path === '/') {
496
498
  return '/index.html';
497
499
  }
500
+
498
501
  const parts = path.split('/');
499
502
  if (is_html && parts[parts.length - 1] !== 'index.html') {
500
- if (config.kit.prerender.createIndexFiles) {
503
+ if (config.kit.trailingSlash === 'always') {
501
504
  parts.push('index.html');
502
505
  } else {
503
506
  parts[parts.length - 1] += '.html';
@@ -525,114 +528,113 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
525
528
  * @param {string?} referrer
526
529
  */
527
530
  async function visit(path, decoded_path, referrer) {
531
+ if (!path.startsWith(config.kit.paths.base)) {
532
+ error({ status: 404, path, referrer, referenceType: 'linked' });
533
+ return;
534
+ }
535
+
528
536
  /** @type {Map<string, import('types/internal').PrerenderDependency>} */
529
537
  const dependencies = new Map();
530
538
 
531
- const render_path = config.kit.paths?.base
532
- ? `http://sveltekit-prerender${config.kit.paths.base}${path === '/' ? '' : path}`
533
- : `http://sveltekit-prerender${path}`;
534
-
535
- const rendered = await app.render(new Request(render_path), {
539
+ const rendered = await app.render(new Request(`http://sveltekit-prerender${path}`), {
536
540
  prerender: {
537
541
  all,
538
542
  dependencies
539
543
  }
540
544
  });
541
545
 
542
- if (rendered) {
543
- const response_type = Math.floor(rendered.status / 100);
544
- const type = rendered.headers.get('content-type');
545
- const is_html = response_type === REDIRECT || type === 'text/html';
546
+ const response_type = Math.floor(rendered.status / 100);
547
+ const type = rendered.headers.get('content-type');
548
+ const is_html = response_type === REDIRECT || type === 'text/html';
546
549
 
547
- const file = `${out}${output_filename(decoded_path, is_html)}`;
550
+ const file = `${out}${output_filename(decoded_path, is_html)}`;
548
551
 
549
- if (response_type === REDIRECT) {
550
- const location = rendered.headers.get('location');
552
+ if (response_type === REDIRECT) {
553
+ const location = rendered.headers.get('location');
551
554
 
552
- if (location) {
553
- mkdirp(dirname(file));
555
+ if (location) {
556
+ mkdirp(dirname(file));
554
557
 
555
- log.warn(`${rendered.status} ${decoded_path} -> ${location}`);
558
+ log.warn(`${rendered.status} ${decoded_path} -> ${location}`);
556
559
 
557
- writeFileSync(
558
- file,
559
- `<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
560
- );
560
+ writeFileSync(
561
+ file,
562
+ `<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
563
+ );
561
564
 
562
- const resolved = resolve(path, location);
563
- if (is_root_relative(resolved)) {
564
- enqueue(resolved, path);
565
- }
566
- } else {
567
- log.warn(`location header missing on redirect received from ${decoded_path}`);
565
+ const resolved = resolve(path, location);
566
+ if (is_root_relative(resolved)) {
567
+ enqueue(resolved, path);
568
568
  }
569
-
570
- return;
569
+ } else {
570
+ log.warn(`location header missing on redirect received from ${decoded_path}`);
571
571
  }
572
572
 
573
- const text = await rendered.text();
573
+ return;
574
+ }
574
575
 
575
- if (rendered.status === 200) {
576
- mkdirp(dirname(file));
576
+ const text = await rendered.text();
577
577
 
578
- log.info(`${rendered.status} ${decoded_path}`);
579
- writeFileSync(file, text);
580
- paths.push(normalize(decoded_path));
581
- } else if (response_type !== OK) {
582
- error({ status: rendered.status, path, referrer, referenceType: 'linked' });
583
- }
578
+ if (rendered.status === 200) {
579
+ mkdirp(dirname(file));
584
580
 
585
- for (const [dependency_path, result] of dependencies) {
586
- const { status, headers } = result.response;
581
+ log.info(`${rendered.status} ${decoded_path}`);
582
+ writeFileSync(file, text);
583
+ paths.push(normalize(decoded_path));
584
+ } else if (response_type !== OK) {
585
+ error({ status: rendered.status, path, referrer, referenceType: 'linked' });
586
+ }
587
587
 
588
- const response_type = Math.floor(status / 100);
588
+ for (const [dependency_path, result] of dependencies) {
589
+ const { status, headers } = result.response;
589
590
 
590
- const is_html = headers.get('content-type') === 'text/html';
591
+ const response_type = Math.floor(status / 100);
591
592
 
592
- const file = `${out}${output_filename(dependency_path, is_html)}`;
593
- mkdirp(dirname(file));
593
+ const is_html = headers.get('content-type') === 'text/html';
594
594
 
595
- writeFileSync(
596
- file,
597
- result.body === null ? new Uint8Array(await result.response.arrayBuffer()) : result.body
598
- );
599
- paths.push(dependency_path);
600
-
601
- if (response_type === OK) {
602
- log.info(`${status} ${dependency_path}`);
603
- } else {
604
- error({
605
- status,
606
- path: dependency_path,
607
- referrer: path,
608
- referenceType: 'fetched'
609
- });
610
- }
595
+ const file = `${out}${output_filename(dependency_path, is_html)}`;
596
+ mkdirp(dirname(file));
597
+
598
+ writeFileSync(
599
+ file,
600
+ result.body === null ? new Uint8Array(await result.response.arrayBuffer()) : result.body
601
+ );
602
+ paths.push(dependency_path);
603
+
604
+ if (response_type === OK) {
605
+ log.info(`${status} ${dependency_path}`);
606
+ } else {
607
+ error({
608
+ status,
609
+ path: dependency_path,
610
+ referrer: path,
611
+ referenceType: 'fetched'
612
+ });
611
613
  }
614
+ }
612
615
 
613
- if (is_html && config.kit.prerender.crawl) {
614
- for (const href of crawl(text)) {
615
- if (href.startsWith('data:') || href.startsWith('#')) continue;
616
+ if (is_html && config.kit.prerender.crawl) {
617
+ for (const href of crawl(text)) {
618
+ if (href.startsWith('data:') || href.startsWith('#')) continue;
616
619
 
617
- const resolved = resolve(path, href);
618
- if (!is_root_relative(resolved)) continue;
620
+ const resolved = resolve(path, href);
621
+ if (!is_root_relative(resolved)) continue;
619
622
 
620
- const parsed = new URL(resolved, 'http://localhost');
623
+ const parsed = new URL(resolved, 'http://localhost');
621
624
 
622
- let pathname = decodeURI(parsed.pathname);
625
+ let pathname = decodeURI(parsed.pathname);
623
626
 
624
- if (config.kit.paths.base) {
625
- if (!pathname.startsWith(config.kit.paths.base)) continue;
626
- pathname = pathname.slice(config.kit.paths.base.length) || '/';
627
- }
627
+ if (config.kit.paths.base) {
628
+ if (!pathname.startsWith(config.kit.paths.base)) continue;
629
+ pathname = pathname.slice(config.kit.paths.base.length) || '/';
630
+ }
628
631
 
629
- const file = pathname.slice(1);
630
- if (files.has(file)) continue;
632
+ const file = pathname.slice(1);
633
+ if (files.has(file)) continue;
631
634
 
632
- if (parsed.search) ;
635
+ if (parsed.search) ;
633
636
 
634
- enqueue(pathname, path);
635
- }
637
+ enqueue(pathname, path);
636
638
  }
637
639
  }
638
640
  }
@@ -641,10 +643,10 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
641
643
  for (const entry of config.kit.prerender.entries) {
642
644
  if (entry === '*') {
643
645
  for (const entry of build_data.entries) {
644
- enqueue(entry, null);
646
+ enqueue(config.kit.paths.base + entry, null);
645
647
  }
646
648
  } else {
647
- enqueue(entry, null);
649
+ enqueue(config.kit.paths.base + entry, null);
648
650
  }
649
651
  }
650
652
 
@@ -700,6 +702,7 @@ function create_builder({ cwd, config, build_data, log }) {
700
702
  copy,
701
703
 
702
704
  appDir: config.kit.appDir,
705
+ trailingSlash: config.kit.trailingSlash,
703
706
 
704
707
  createEntries(fn) {
705
708
  generated_manifest = true;
package/dist/cli.js CHANGED
@@ -619,7 +619,9 @@ const options = object(
619
619
  prerender: object({
620
620
  concurrency: number(1),
621
621
  crawl: boolean(true),
622
- createIndexFiles: boolean(true),
622
+ createIndexFiles: error(
623
+ (keypath) => `${keypath} has been removed — it is now controlled by the trailingSlash option. See https://kit.svelte.dev/docs/configuration#trailingslash`
624
+ ),
623
625
  enabled: boolean(true),
624
626
  entries: validate(['*'], (input, keypath) => {
625
627
  if (!Array.isArray(input) || !input.every((page) => typeof page === 'string')) {
@@ -995,7 +997,7 @@ async function launch(port, https) {
995
997
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
996
998
  }
997
999
 
998
- const prog = sade('svelte-kit').version('1.0.0-next.264');
1000
+ const prog = sade('svelte-kit').version('1.0.0-next.265');
999
1001
 
1000
1002
  prog
1001
1003
  .command('dev')
@@ -1153,7 +1155,7 @@ async function check_port(port) {
1153
1155
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1154
1156
  if (open) launch(port, https);
1155
1157
 
1156
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.264'}\n`));
1158
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.265'}\n`));
1157
1159
 
1158
1160
  const protocol = https ? 'https:' : 'http:';
1159
1161
  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.264",
3
+ "version": "1.0.0-next.265",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -84,8 +84,9 @@
84
84
  "check-format": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore",
85
85
  "test": "npm run test:unit && npm run test:packaging && npm run test:prerendering && npm run test:integration",
86
86
  "test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\" -i packaging",
87
- "test:prerendering": "pnpm test:prerendering:basics",
87
+ "test:prerendering": "pnpm test:prerendering:basics && pnpm test:prerendering:options",
88
88
  "test:prerendering:basics": "cd test/prerendering/basics && pnpm test",
89
+ "test:prerendering:options": "cd test/prerendering/options && pnpm test",
89
90
  "test:packaging": "uvu src/packaging \"(spec\\.js|test[\\\\/]index\\.js)\"",
90
91
  "test:integration": "pnpm test:integration:amp && pnpm test:integration:basics && pnpm test:integration:options && pnpm test:integration:options-2",
91
92
  "test:integration:amp": "cd test/apps/amp && pnpm test",
package/types/config.d.ts CHANGED
@@ -41,6 +41,7 @@ export interface Builder {
41
41
  mkdirp(dir: string): void;
42
42
 
43
43
  appDir: string;
44
+ trailingSlash: 'always' | 'never' | 'ignore';
44
45
 
45
46
  /**
46
47
  * Create entry points that map to individual functions
@@ -153,7 +154,6 @@ export interface Config {
153
154
  prerender?: {
154
155
  concurrency?: number;
155
156
  crawl?: boolean;
156
- createIndexFiles?: boolean;
157
157
  enabled?: boolean;
158
158
  entries?: string[];
159
159
  onError?: PrerenderOnErrorValue;