@sveltejs/kit 1.0.0-next.392 → 1.0.0-next.395

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/dist/vite.js CHANGED
@@ -1,16 +1,23 @@
1
- import * as fs from 'fs';
2
- import fs__default, { readFileSync, existsSync, writeFileSync, readdirSync, statSync } from 'fs';
3
- import path__default, { join, dirname, resolve as resolve$1, normalize } from 'path';
4
- import { a as load_template, $, c as coalesce_to_error, l as load_config } from './chunks/error.js';
1
+ import { fork } from 'node:child_process';
2
+ import fs$1 from 'node:fs';
3
+ import path from 'node:path';
4
+ import { a as load_template, $, l as load_config } from './chunks/index.js';
5
5
  import { svelte } from '@sveltejs/vite-plugin-svelte';
6
6
  import * as vite from 'vite';
7
- import { loadConfigFromFile } from 'vite';
8
- import { p as posixify, m as mkdirp, w as walk, r as rimraf } from './chunks/write_tsconfig.js';
9
- import { g as get_runtime_directory, s, i as init, a as get_runtime_prefix, u as update, b as get_mime_lookup, p as parse_route_id, c as all, l as logger } from './chunks/sync.js';
10
- import { URL as URL$1, pathToFileURL } from 'url';
11
- import { installPolyfills } from './node/polyfills.js';
7
+ import { loadEnv } from 'vite';
8
+ import { p as posixify, m as mkdirp, r as rimraf } from './chunks/filesystem.js';
9
+ import { g as get_aliases, r as resolve_entry, s, m as merge_vite_configs, a as get_vite_config, i as init, b as get_env, u as update, p as prevent_illegal_vite_imports, c as parse_route_id, d as all, e as prevent_illegal_rollup_imports } from './chunks/sync.js';
10
+ import * as fs from 'fs';
11
+ import fs__default, { readdirSync, statSync } from 'fs';
12
+ import path__default, { resolve, join, normalize } from 'path';
13
+ import { g as get_runtime_directory, a as get_runtime_prefix, b as get_mime_lookup, l as logger } from './chunks/utils.js';
12
14
  import * as qs from 'querystring';
15
+ import { URL as URL$1, pathToFileURL } from 'url';
13
16
  import { getRequest, setResponse } from './node.js';
17
+ import { installPolyfills } from './node/polyfills.js';
18
+ import { c as coalesce_to_error } from './chunks/error.js';
19
+ import { fileURLToPath } from 'node:url';
20
+ import './chunks/write_tsconfig.js';
14
21
  import 'assert';
15
22
  import 'net';
16
23
  import 'http';
@@ -31,144 +38,9 @@ import 'node:zlib';
31
38
  import 'node:stream';
32
39
  import 'node:buffer';
33
40
  import 'node:util';
34
- import 'node:url';
35
41
  import 'node:net';
36
- import 'node:fs';
37
- import 'node:path';
38
42
  import 'crypto';
39
43
 
40
- /**
41
- * @param {import('vite').ConfigEnv} config_env
42
- * @return {Promise<import('vite').UserConfig>}
43
- */
44
- async function get_vite_config(config_env) {
45
- const config = (await loadConfigFromFile(config_env))?.config;
46
- if (!config) {
47
- throw new Error('Could not load Vite config');
48
- }
49
- return { ...config, mode: config_env.mode };
50
- }
51
-
52
- /**
53
- * @param {...import('vite').UserConfig} configs
54
- * @returns {import('vite').UserConfig}
55
- */
56
- function merge_vite_configs(...configs) {
57
- return deep_merge(
58
- ...configs.map((config) => ({
59
- ...config,
60
- resolve: {
61
- ...config.resolve,
62
- alias: normalize_alias(config.resolve?.alias || {})
63
- }
64
- }))
65
- );
66
- }
67
-
68
- /**
69
- * Takes zero or more objects and returns a new object that has all the values
70
- * deeply merged together. None of the original objects will be mutated at any
71
- * level, and the returned object will have no references to the original
72
- * objects at any depth. If there's a conflict the last one wins, except for
73
- * arrays which will be combined.
74
- * @param {...Object} objects
75
- * @returns {Record<string, any>} the merged object
76
- */
77
- function deep_merge(...objects) {
78
- const result = {};
79
- /** @type {string[]} */
80
- objects.forEach((o) => merge_into(result, o));
81
- return result;
82
- }
83
-
84
- /**
85
- * normalize kit.vite.resolve.alias as an array
86
- * @param {import('vite').AliasOptions} o
87
- * @returns {import('vite').Alias[]}
88
- */
89
- function normalize_alias(o) {
90
- if (Array.isArray(o)) return o;
91
- return Object.entries(o).map(([find, replacement]) => ({ find, replacement }));
92
- }
93
-
94
- /**
95
- * Merges b into a, recursively, mutating a.
96
- * @param {Record<string, any>} a
97
- * @param {Record<string, any>} b
98
- */
99
- function merge_into(a, b) {
100
- /**
101
- * Checks for "plain old Javascript object", typically made as an object
102
- * literal. Excludes Arrays and built-in types like Buffer.
103
- * @param {any} x
104
- */
105
- const is_plain_object = (x) => typeof x === 'object' && x.constructor === Object;
106
-
107
- for (const prop in b) {
108
- if (is_plain_object(b[prop])) {
109
- if (!is_plain_object(a[prop])) {
110
- a[prop] = {};
111
- }
112
- merge_into(a[prop], b[prop]);
113
- } else if (Array.isArray(b[prop])) {
114
- if (!Array.isArray(a[prop])) {
115
- a[prop] = [];
116
- }
117
- a[prop].push(...b[prop]);
118
- } else {
119
- a[prop] = b[prop];
120
- }
121
- }
122
- }
123
-
124
- /** @param {import('types').ValidatedKitConfig} config */
125
- function get_aliases(config) {
126
- /** @type {Record<string, string>} */
127
- const alias = {
128
- __GENERATED__: path__default.posix.join(config.outDir, 'generated'),
129
- $app: `${get_runtime_directory(config)}/app`,
130
-
131
- // For now, we handle `$lib` specially here rather than make it a default value for
132
- // `config.kit.alias` since it has special meaning for packaging, etc.
133
- $lib: config.files.lib
134
- };
135
-
136
- for (const [key, value] of Object.entries(config.alias)) {
137
- alias[key] = path__default.resolve(value);
138
- }
139
-
140
- return alias;
141
- }
142
-
143
- /**
144
- * Given an entry point like [cwd]/src/hooks, returns a filename like [cwd]/src/hooks.js or [cwd]/src/hooks/index.js
145
- * @param {string} entry
146
- * @returns {string|null}
147
- */
148
- function resolve_entry(entry) {
149
- if (fs__default.existsSync(entry)) {
150
- const stats = fs__default.statSync(entry);
151
- if (stats.isDirectory()) {
152
- return resolve_entry(path__default.join(entry, 'index'));
153
- }
154
-
155
- return entry;
156
- } else {
157
- const dir = path__default.dirname(entry);
158
-
159
- if (fs__default.existsSync(dir)) {
160
- const base = path__default.basename(entry);
161
- const files = fs__default.readdirSync(dir);
162
-
163
- const found = files.find((file) => file.replace(/\.[^.]+$/, '') === base);
164
-
165
- if (found) return path__default.join(dir, found);
166
- }
167
- }
168
-
169
- return null;
170
- }
171
-
172
44
  /**
173
45
  * @typedef {import('rollup').RollupOutput} RollupOutput
174
46
  * @typedef {import('rollup').OutputChunk} OutputChunk
@@ -284,9 +156,7 @@ const get_default_config = function ({ config, input, ssr, outDir }) {
284
156
  __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: JSON.stringify(config.kit.version.pollInterval),
285
157
  __SVELTEKIT_DEV__: 'false'
286
158
  },
287
- // prevent Vite copying the contents of `config.kit.files.assets`,
288
- // if it happens to be 'public' instead of 'static'
289
- publicDir: false,
159
+ publicDir: ssr ? false : config.kit.files.assets,
290
160
  resolve: {
291
161
  alias: get_aliases(config.kit)
292
162
  },
@@ -351,6 +221,8 @@ import root from '__GENERATED__/root.svelte';
351
221
  import { respond } from '${runtime}/server/index.js';
352
222
  import { set_paths, assets, base } from '${runtime}/paths.js';
353
223
  import { set_prerendering } from '${runtime}/env.js';
224
+ import { set_private_env } from '${runtime}/env-private.js';
225
+ import { set_public_env } from '${runtime}/env-public.js';
354
226
 
355
227
  const template = ({ head, body, assets, nonce }) => ${s(template)
356
228
  .replace('%sveltekit.head%', '" + head + "')
@@ -402,6 +274,7 @@ export class Server {
402
274
  default: ${config.kit.prerender.default},
403
275
  enabled: ${config.kit.prerender.enabled}
404
276
  },
277
+ public_env: {},
405
278
  read,
406
279
  root,
407
280
  service_worker: ${has_service_worker ? "base + '/service-worker.js'" : 'null'},
@@ -412,6 +285,23 @@ export class Server {
412
285
  };
413
286
  }
414
287
 
288
+ init({ env }) {
289
+ const entries = Object.entries(env);
290
+
291
+ const prv = Object.fromEntries(Object.entries(env).filter(([k]) => !k.startsWith('${
292
+ config.kit.env.publicPrefix
293
+ }')));
294
+
295
+ const pub = Object.fromEntries(Object.entries(env).filter(([k]) => k.startsWith('${
296
+ config.kit.env.publicPrefix
297
+ }')));
298
+
299
+ set_private_env(prv);
300
+ set_public_env(pub);
301
+
302
+ this.options.public_env = pub;
303
+ }
304
+
415
305
  async respond(request, options = {}) {
416
306
  if (!(request instanceof Request)) {
417
307
  throw new Error('The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
@@ -436,6 +326,7 @@ export class Server {
436
326
  * @param {{
437
327
  * cwd: string;
438
328
  * config: import('types').ValidatedConfig;
329
+ * vite_config: import('vite').ResolvedConfig;
439
330
  * vite_config_env: import('vite').ConfigEnv;
440
331
  * manifest_data: import('types').ManifestData;
441
332
  * build_dir: string;
@@ -448,6 +339,7 @@ async function build_server(options, client) {
448
339
  const {
449
340
  cwd,
450
341
  config,
342
+ vite_config,
451
343
  vite_config_env,
452
344
  manifest_data,
453
345
  build_dir,
@@ -512,11 +404,9 @@ async function build_server(options, client) {
512
404
  })
513
405
  );
514
406
 
515
- const vite_config = await get_vite_config(vite_config_env);
516
-
517
407
  const merged_config = merge_vite_configs(
518
408
  get_default_config({ config, input, ssr: true, outDir: `${output_dir}/server` }),
519
- vite_config
409
+ await get_vite_config(vite_config, vite_config_env)
520
410
  );
521
411
 
522
412
  remove_svelte_kit(merged_config);
@@ -613,6 +503,7 @@ function get_methods(cwd, output, manifest_data) {
613
503
  /**
614
504
  * @param {{
615
505
  * config: import('types').ValidatedConfig;
506
+ * vite_config: import('vite').ResolvedConfig;
616
507
  * vite_config_env: import('vite').ConfigEnv;
617
508
  * manifest_data: import('types').ManifestData;
618
509
  * output_dir: string;
@@ -622,7 +513,7 @@ function get_methods(cwd, output, manifest_data) {
622
513
  * @param {import('vite').Manifest} client_manifest
623
514
  */
624
515
  async function build_service_worker(
625
- { config, vite_config_env, manifest_data, output_dir, service_worker_entry_file },
516
+ { config, vite_config, vite_config_env, manifest_data, output_dir, service_worker_entry_file },
626
517
  prerendered,
627
518
  client_manifest
628
519
  ) {
@@ -669,8 +560,7 @@ async function build_service_worker(
669
560
  .trim()
670
561
  );
671
562
 
672
- const vite_config = await get_vite_config(vite_config_env);
673
- const merged_config = merge_vite_configs(vite_config, {
563
+ const merged_config = merge_vite_configs(await get_vite_config(vite_config, vite_config_env), {
674
564
  base: assets_base(config.kit),
675
565
  build: {
676
566
  lib: {
@@ -701,747 +591,8 @@ async function build_service_worker(
701
591
  await vite.build(merged_config);
702
592
  }
703
593
 
704
- const absolute = /^([a-z]+:)?\/?\//;
705
- const scheme = /^[a-z]+:/;
706
-
707
- /**
708
- * @param {string} base
709
- * @param {string} path
710
- */
711
- function resolve(base, path) {
712
- if (scheme.test(path)) return path;
713
-
714
- const base_match = absolute.exec(base);
715
- const path_match = absolute.exec(path);
716
-
717
- if (!base_match) {
718
- throw new Error(`bad base path: "${base}"`);
719
- }
720
-
721
- const baseparts = path_match ? [] : base.slice(base_match[0].length).split('/');
722
- const pathparts = path_match ? path.slice(path_match[0].length).split('/') : path.split('/');
723
-
724
- baseparts.pop();
725
-
726
- for (let i = 0; i < pathparts.length; i += 1) {
727
- const part = pathparts[i];
728
- if (part === '.') continue;
729
- else if (part === '..') baseparts.pop();
730
- else baseparts.push(part);
731
- }
732
-
733
- const prefix = (path_match && path_match[0]) || (base_match && base_match[0]) || '';
734
-
735
- return `${prefix}${baseparts.join('/')}`;
736
- }
737
-
738
- /** @param {string} path */
739
- function is_root_relative(path) {
740
- return path[0] === '/' && path[1] !== '/';
741
- }
742
-
743
- /**
744
- * @typedef {{
745
- * fn: () => Promise<any>,
746
- * fulfil: (value: any) => void,
747
- * reject: (error: Error) => void
748
- * }} Task
749
- */
750
-
751
- /** @param {number} concurrency */
752
- function queue(concurrency) {
753
- /** @type {Task[]} */
754
- const tasks = [];
755
-
756
- let current = 0;
757
-
758
- /** @type {(value?: any) => void} */
759
- let fulfil;
760
-
761
- /** @type {(error: Error) => void} */
762
- let reject;
763
-
764
- let closed = false;
765
-
766
- const done = new Promise((f, r) => {
767
- fulfil = f;
768
- reject = r;
769
- });
770
-
771
- done.catch(() => {
772
- // this is necessary in case a catch handler is never added
773
- // to the done promise by the user
774
- });
775
-
776
- function dequeue() {
777
- if (current < concurrency) {
778
- const task = tasks.shift();
779
-
780
- if (task) {
781
- current += 1;
782
- const promise = Promise.resolve(task.fn());
783
-
784
- promise
785
- .then(task.fulfil, (err) => {
786
- task.reject(err);
787
- reject(err);
788
- })
789
- .then(() => {
790
- current -= 1;
791
- dequeue();
792
- });
793
- } else if (current === 0) {
794
- closed = true;
795
- fulfil();
796
- }
797
- }
798
- }
799
-
800
- return {
801
- /** @param {() => any} fn */
802
- add: (fn) => {
803
- if (closed) throw new Error('Cannot add tasks to a queue that has ended');
804
-
805
- const promise = new Promise((fulfil, reject) => {
806
- tasks.push({ fn, fulfil, reject });
807
- });
808
-
809
- dequeue();
810
- return promise;
811
- },
812
-
813
- done: () => {
814
- if (current === 0) {
815
- closed = true;
816
- fulfil();
817
- }
818
-
819
- return done;
820
- }
821
- };
822
- }
823
-
824
- const DOCTYPE = 'DOCTYPE';
825
- const CDATA_OPEN = '[CDATA[';
826
- const CDATA_CLOSE = ']]>';
827
- const COMMENT_OPEN = '--';
828
- const COMMENT_CLOSE = '-->';
829
-
830
- const TAG_OPEN = /[a-zA-Z]/;
831
- const TAG_CHAR = /[a-zA-Z0-9]/;
832
- const ATTRIBUTE_NAME = /[^\t\n\f />"'=]/;
833
-
834
- const WHITESPACE = /[\s\n\r]/;
835
-
836
- /** @param {string} html */
837
- function crawl(html) {
838
- /** @type {string[]} */
839
- const hrefs = [];
840
-
841
- let i = 0;
842
- main: while (i < html.length) {
843
- const char = html[i];
844
-
845
- if (char === '<') {
846
- if (html[i + 1] === '!') {
847
- i += 2;
848
-
849
- if (html.slice(i, i + DOCTYPE.length).toUpperCase() === DOCTYPE) {
850
- i += DOCTYPE.length;
851
- while (i < html.length) {
852
- if (html[i++] === '>') {
853
- continue main;
854
- }
855
- }
856
- }
857
-
858
- // skip cdata
859
- if (html.slice(i, i + CDATA_OPEN.length) === CDATA_OPEN) {
860
- i += CDATA_OPEN.length;
861
- while (i < html.length) {
862
- if (html.slice(i, i + CDATA_CLOSE.length) === CDATA_CLOSE) {
863
- i += CDATA_CLOSE.length;
864
- continue main;
865
- }
866
-
867
- i += 1;
868
- }
869
- }
870
-
871
- // skip comments
872
- if (html.slice(i, i + COMMENT_OPEN.length) === COMMENT_OPEN) {
873
- i += COMMENT_OPEN.length;
874
- while (i < html.length) {
875
- if (html.slice(i, i + COMMENT_CLOSE.length) === COMMENT_CLOSE) {
876
- i += COMMENT_CLOSE.length;
877
- continue main;
878
- }
879
-
880
- i += 1;
881
- }
882
- }
883
- }
884
-
885
- // parse opening tags
886
- const start = ++i;
887
- if (TAG_OPEN.test(html[start])) {
888
- while (i < html.length) {
889
- if (!TAG_CHAR.test(html[i])) {
890
- break;
891
- }
892
-
893
- i += 1;
894
- }
895
-
896
- const tag = html.slice(start, i).toUpperCase();
897
-
898
- if (tag === 'SCRIPT' || tag === 'STYLE') {
899
- while (i < html.length) {
900
- if (
901
- html[i] === '<' &&
902
- html[i + 1] === '/' &&
903
- html.slice(i + 2, i + 2 + tag.length).toUpperCase() === tag
904
- ) {
905
- continue main;
906
- }
907
-
908
- i += 1;
909
- }
910
- }
911
-
912
- let href = '';
913
- let rel = '';
914
-
915
- while (i < html.length) {
916
- const start = i;
917
-
918
- const char = html[start];
919
- if (char === '>') break;
920
-
921
- if (ATTRIBUTE_NAME.test(char)) {
922
- i += 1;
923
-
924
- while (i < html.length) {
925
- if (!ATTRIBUTE_NAME.test(html[i])) {
926
- break;
927
- }
928
-
929
- i += 1;
930
- }
931
-
932
- const name = html.slice(start, i).toLowerCase();
933
-
934
- while (WHITESPACE.test(html[i])) i += 1;
935
-
936
- if (html[i] === '=') {
937
- i += 1;
938
- while (WHITESPACE.test(html[i])) i += 1;
939
-
940
- let value;
941
-
942
- if (html[i] === "'" || html[i] === '"') {
943
- const quote = html[i++];
944
-
945
- const start = i;
946
- let escaped = false;
947
-
948
- while (i < html.length) {
949
- if (!escaped) {
950
- const char = html[i];
951
-
952
- if (html[i] === quote) {
953
- break;
954
- }
955
-
956
- if (char === '\\') {
957
- escaped = true;
958
- }
959
- }
960
-
961
- i += 1;
962
- }
963
-
964
- value = html.slice(start, i);
965
- } else {
966
- const start = i;
967
- while (html[i] !== '>' && !WHITESPACE.test(html[i])) i += 1;
968
- value = html.slice(start, i);
969
-
970
- i -= 1;
971
- }
972
-
973
- if (name === 'href') {
974
- href = value;
975
- } else if (name === 'rel') {
976
- rel = value;
977
- } else if (name === 'src') {
978
- hrefs.push(value);
979
- } else if (name === 'srcset') {
980
- const candidates = [];
981
- let insideURL = true;
982
- value = value.trim();
983
- for (let i = 0; i < value.length; i++) {
984
- if (value[i] === ',' && (!insideURL || (insideURL && value[i + 1] === ' '))) {
985
- candidates.push(value.slice(0, i));
986
- value = value.substring(i + 1).trim();
987
- i = 0;
988
- insideURL = true;
989
- } else if (value[i] === ' ') {
990
- insideURL = false;
991
- }
992
- }
993
- candidates.push(value);
994
- for (const candidate of candidates) {
995
- const src = candidate.split(WHITESPACE)[0];
996
- hrefs.push(src);
997
- }
998
- }
999
- } else {
1000
- i -= 1;
1001
- }
1002
- }
1003
-
1004
- i += 1;
1005
- }
1006
-
1007
- if (href && !/\bexternal\b/i.test(rel)) {
1008
- hrefs.push(href);
1009
- }
1010
- }
1011
- }
1012
-
1013
- i += 1;
1014
- }
1015
-
1016
- return hrefs;
1017
- }
1018
-
1019
- /**
1020
- * Inside a script element, only `</script` and `<!--` hold special meaning to the HTML parser.
1021
- *
1022
- * The first closes the script element, so everything after is treated as raw HTML.
1023
- * The second disables further parsing until `-->`, so the script element might be unexpectedly
1024
- * kept open until until an unrelated HTML comment in the page.
1025
- *
1026
- * U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR are escaped for the sake of pre-2018
1027
- * browsers.
1028
- *
1029
- * @see tests for unsafe parsing examples.
1030
- * @see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
1031
- * @see https://html.spec.whatwg.org/multipage/syntax.html#cdata-rcdata-restrictions
1032
- * @see https://html.spec.whatwg.org/multipage/parsing.html#script-data-state
1033
- * @see https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escaped-state
1034
- * @see https://github.com/tc39/proposal-json-superset
1035
- * @type {Record<string, string>}
1036
- */
1037
- const render_json_payload_script_dict = {
1038
- '<': '\\u003C',
1039
- '\u2028': '\\u2028',
1040
- '\u2029': '\\u2029'
1041
- };
1042
-
1043
- new RegExp(
1044
- `[${Object.keys(render_json_payload_script_dict).join('')}]`,
1045
- 'g'
1046
- );
1047
-
1048
- /**
1049
- * When inside a double-quoted attribute value, only `&` and `"` hold special meaning.
1050
- * @see https://html.spec.whatwg.org/multipage/parsing.html#attribute-value-(double-quoted)-state
1051
- * @type {Record<string, string>}
1052
- */
1053
- const escape_html_attr_dict = {
1054
- '&': '&amp;',
1055
- '"': '&quot;'
1056
- };
1057
-
1058
- const escape_html_attr_regex = new RegExp(
1059
- // special characters
1060
- `[${Object.keys(escape_html_attr_dict).join('')}]|` +
1061
- // high surrogate without paired low surrogate
1062
- '[\\ud800-\\udbff](?![\\udc00-\\udfff])|' +
1063
- // a valid surrogate pair, the only match with 2 code units
1064
- // we match it so that we can match unpaired low surrogates in the same pass
1065
- // TODO: use lookbehind assertions once they are widely supported: (?<![\ud800-udbff])[\udc00-\udfff]
1066
- '[\\ud800-\\udbff][\\udc00-\\udfff]|' +
1067
- // unpaired low surrogate (see previous match)
1068
- '[\\udc00-\\udfff]',
1069
- 'g'
1070
- );
1071
-
1072
- /**
1073
- * Formats a string to be used as an attribute's value in raw HTML.
1074
- *
1075
- * It escapes unpaired surrogates (which are allowed in js strings but invalid in HTML), escapes
1076
- * characters that are special in attributes, and surrounds the whole string in double-quotes.
1077
- *
1078
- * @param {string} str
1079
- * @returns {string} Escaped string surrounded by double-quotes.
1080
- * @example const html = `<tag data-value=${escape_html_attr('value')}>...</tag>`;
1081
- */
1082
- function escape_html_attr(str) {
1083
- const escaped_str = str.replace(escape_html_attr_regex, (match) => {
1084
- if (match.length === 2) {
1085
- // valid surrogate pair
1086
- return match;
1087
- }
1088
-
1089
- return escape_html_attr_dict[match] ?? `&#${match.charCodeAt(0)};`;
1090
- });
1091
-
1092
- return `"${escaped_str}"`;
1093
- }
1094
-
1095
- /**
1096
- * @typedef {import('types').PrerenderErrorHandler} PrerenderErrorHandler
1097
- * @typedef {import('types').Logger} Logger
1098
- */
1099
-
1100
- /**
1101
- * @param {Parameters<PrerenderErrorHandler>[0]} details
1102
- * @param {import('types').ValidatedKitConfig} config
1103
- */
1104
- function format_error({ status, path, referrer, referenceType }, config) {
1105
- const message =
1106
- status === 404 && !path.startsWith(config.paths.base)
1107
- ? `${path} does not begin with \`base\`, which is configured in \`paths.base\` and can be imported from \`$app/paths\``
1108
- : path;
1109
-
1110
- return `${status} ${message}${referrer ? ` (${referenceType} from ${referrer})` : ''}`;
1111
- }
1112
-
1113
- /**
1114
- * @param {Logger} log
1115
- * @param {import('types').ValidatedKitConfig} config
1116
- * @returns {PrerenderErrorHandler}
1117
- */
1118
- function normalise_error_handler(log, config) {
1119
- switch (config.prerender.onError) {
1120
- case 'continue':
1121
- return (details) => {
1122
- log.error(format_error(details, config));
1123
- };
1124
- case 'fail':
1125
- return (details) => {
1126
- throw new Error(format_error(details, config));
1127
- };
1128
- default:
1129
- return config.prerender.onError;
1130
- }
1131
- }
1132
-
1133
- const OK = 2;
1134
- const REDIRECT = 3;
1135
-
1136
- /**
1137
- * @param {{
1138
- * config: import('types').ValidatedKitConfig;
1139
- * client_out_dir: string;
1140
- * manifest_path: string;
1141
- * log: Logger;
1142
- * }} opts
1143
- */
1144
- async function prerender({ config, client_out_dir, manifest_path, log }) {
1145
- /** @type {import('types').Prerendered} */
1146
- const prerendered = {
1147
- pages: new Map(),
1148
- assets: new Map(),
1149
- redirects: new Map(),
1150
- paths: []
1151
- };
1152
-
1153
- if (!config.prerender.enabled) {
1154
- return prerendered;
1155
- }
1156
-
1157
- installPolyfills();
1158
- const { fetch } = globalThis;
1159
- globalThis.fetch = async (info, init) => {
1160
- /** @type {string} */
1161
- let url;
1162
-
1163
- /** @type {RequestInit} */
1164
- let opts = {};
1165
-
1166
- if (info instanceof Request) {
1167
- url = info.url;
1168
-
1169
- opts = {
1170
- method: info.method,
1171
- headers: info.headers,
1172
- body: info.body,
1173
- mode: info.mode,
1174
- credentials: info.credentials,
1175
- cache: info.cache,
1176
- redirect: info.redirect,
1177
- referrer: info.referrer,
1178
- integrity: info.integrity
1179
- };
1180
- } else {
1181
- url = info.toString();
1182
- }
1183
-
1184
- if (url.startsWith(config.prerender.origin + '/')) {
1185
- const request = new Request(url, opts);
1186
- const response = await server.respond(request, {
1187
- getClientAddress,
1188
- prerendering: {
1189
- dependencies: new Map()
1190
- }
1191
- });
1192
-
1193
- const decoded = new URL$1(url).pathname;
1194
-
1195
- save(
1196
- 'dependencies',
1197
- response,
1198
- Buffer.from(await response.clone().arrayBuffer()),
1199
- decoded,
1200
- encodeURI(decoded),
1201
- null,
1202
- 'fetched'
1203
- );
1204
-
1205
- return response;
1206
- }
1207
-
1208
- return fetch(info, init);
1209
- };
1210
-
1211
- const server_root = join(config.outDir, 'output');
1212
-
1213
- /** @type {import('types').ServerModule} */
1214
- const { Server, override } = await import(pathToFileURL(`${server_root}/server/index.js`).href);
1215
-
1216
- /** @type {import('types').SSRManifest} */
1217
- const manifest = (await import(pathToFileURL(`${server_root}/server/manifest.js`).href)).manifest;
1218
-
1219
- override({
1220
- paths: config.paths,
1221
- prerendering: true,
1222
- read: (file) => readFileSync(join(config.files.assets, file))
1223
- });
1224
-
1225
- const server = new Server(manifest);
1226
-
1227
- const error = normalise_error_handler(log, config);
1228
-
1229
- const q = queue(config.prerender.concurrency);
1230
-
1231
- /**
1232
- * @param {string} path
1233
- * @param {boolean} is_html
1234
- */
1235
- function output_filename(path, is_html) {
1236
- const file = path.slice(config.paths.base.length + 1) || 'index.html';
1237
-
1238
- if (is_html && !file.endsWith('.html')) {
1239
- return file + (file.endsWith('/') ? 'index.html' : '.html');
1240
- }
1241
-
1242
- return file;
1243
- }
1244
-
1245
- const files = new Set([
1246
- ...walk(client_out_dir).map(posixify),
1247
- ...(existsSync(config.files.assets) ? walk(config.files.assets).map(posixify) : []) // TODO remove this if we use Vite publicDir option
1248
- ]);
1249
- const seen = new Set();
1250
- const written = new Set();
1251
-
1252
- /**
1253
- * @param {string | null} referrer
1254
- * @param {string} decoded
1255
- * @param {string} [encoded]
1256
- */
1257
- function enqueue(referrer, decoded, encoded) {
1258
- if (seen.has(decoded)) return;
1259
- seen.add(decoded);
1260
-
1261
- const file = decoded.slice(config.paths.base.length + 1);
1262
- if (files.has(file)) return;
1263
-
1264
- return q.add(() => visit(decoded, encoded || encodeURI(decoded), referrer));
1265
- }
1266
-
1267
- /**
1268
- * @param {string} decoded
1269
- * @param {string} encoded
1270
- * @param {string?} referrer
1271
- */
1272
- async function visit(decoded, encoded, referrer) {
1273
- if (!decoded.startsWith(config.paths.base)) {
1274
- error({ status: 404, path: decoded, referrer, referenceType: 'linked' });
1275
- return;
1276
- }
1277
-
1278
- /** @type {Map<string, import('types').PrerenderDependency>} */
1279
- const dependencies = new Map();
1280
-
1281
- const response = await server.respond(new Request(config.prerender.origin + encoded), {
1282
- getClientAddress,
1283
- prerendering: {
1284
- dependencies
1285
- }
1286
- });
1287
-
1288
- const body = Buffer.from(await response.arrayBuffer());
1289
-
1290
- save('pages', response, body, decoded, encoded, referrer, 'linked');
1291
-
1292
- for (const [dependency_path, result] of dependencies) {
1293
- // this seems circuitous, but using new URL allows us to not care
1294
- // whether dependency_path is encoded or not
1295
- const encoded_dependency_path = new URL$1(dependency_path, 'http://localhost').pathname;
1296
- const decoded_dependency_path = decodeURI(encoded_dependency_path);
1297
-
1298
- const body = result.body ?? new Uint8Array(await result.response.arrayBuffer());
1299
- save(
1300
- 'dependencies',
1301
- result.response,
1302
- body,
1303
- decoded_dependency_path,
1304
- encoded_dependency_path,
1305
- decoded,
1306
- 'fetched'
1307
- );
1308
- }
1309
-
1310
- if (config.prerender.crawl && response.headers.get('content-type') === 'text/html') {
1311
- for (const href of crawl(body.toString())) {
1312
- if (href.startsWith('data:') || href.startsWith('#')) continue;
1313
-
1314
- const resolved = resolve(encoded, href);
1315
- if (!is_root_relative(resolved)) continue;
1316
-
1317
- const { pathname, search } = new URL$1(resolved, 'http://localhost');
1318
-
1319
- enqueue(decoded, decodeURI(pathname), pathname);
1320
- }
1321
- }
1322
- }
1323
-
1324
- /**
1325
- * @param {'pages' | 'dependencies'} category
1326
- * @param {Response} response
1327
- * @param {string | Uint8Array} body
1328
- * @param {string} decoded
1329
- * @param {string} encoded
1330
- * @param {string | null} referrer
1331
- * @param {'linked' | 'fetched'} referenceType
1332
- */
1333
- function save(category, response, body, decoded, encoded, referrer, referenceType) {
1334
- const response_type = Math.floor(response.status / 100);
1335
- const type = /** @type {string} */ (response.headers.get('content-type'));
1336
- const is_html = response_type === REDIRECT || type === 'text/html';
1337
-
1338
- const file = output_filename(decoded, is_html);
1339
- const dest = `${config.outDir}/output/prerendered/${category}/${file}`;
1340
-
1341
- if (written.has(file)) return;
1342
-
1343
- if (response_type === REDIRECT) {
1344
- const location = response.headers.get('location');
1345
-
1346
- if (location) {
1347
- const resolved = resolve(encoded, location);
1348
- if (is_root_relative(resolved)) {
1349
- enqueue(decoded, decodeURI(resolved), resolved);
1350
- }
1351
-
1352
- if (!response.headers.get('x-sveltekit-normalize')) {
1353
- mkdirp(dirname(dest));
1354
-
1355
- log.warn(`${response.status} ${decoded} -> ${location}`);
1356
-
1357
- writeFileSync(
1358
- dest,
1359
- `<meta http-equiv="refresh" content=${escape_html_attr(`0;url=${location}`)}>`
1360
- );
1361
-
1362
- written.add(file);
1363
-
1364
- if (!prerendered.redirects.has(decoded)) {
1365
- prerendered.redirects.set(decoded, {
1366
- status: response.status,
1367
- location: resolved
1368
- });
1369
-
1370
- prerendered.paths.push(decoded);
1371
- }
1372
- }
1373
- } else {
1374
- log.warn(`location header missing on redirect received from ${decoded}`);
1375
- }
1376
-
1377
- return;
1378
- }
1379
-
1380
- if (response.status === 200) {
1381
- mkdirp(dirname(dest));
1382
-
1383
- log.info(`${response.status} ${decoded}`);
1384
- writeFileSync(dest, body);
1385
- written.add(file);
1386
-
1387
- if (is_html) {
1388
- prerendered.pages.set(decoded, {
1389
- file
1390
- });
1391
- } else {
1392
- prerendered.assets.set(decoded, {
1393
- type
1394
- });
1395
- }
1396
-
1397
- prerendered.paths.push(decoded);
1398
- } else if (response_type !== OK) {
1399
- error({ status: response.status, path: decoded, referrer, referenceType });
1400
- }
1401
- }
1402
-
1403
- if (config.prerender.enabled) {
1404
- for (const entry of config.prerender.entries) {
1405
- if (entry === '*') {
1406
- /** @type {import('types').ManifestData} */
1407
- const { routes } = (await import(pathToFileURL(manifest_path).href)).manifest._;
1408
- const entries = routes
1409
- .map((route) => (route.type === 'page' ? route.path : ''))
1410
- .filter(Boolean);
1411
-
1412
- for (const entry of entries) {
1413
- enqueue(null, config.paths.base + entry); // TODO can we pre-normalize these?
1414
- }
1415
- } else {
1416
- enqueue(null, config.paths.base + entry);
1417
- }
1418
- }
1419
-
1420
- await q.done();
1421
- }
1422
-
1423
- const rendered = await server.respond(new Request(config.prerender.origin + '/[fallback]'), {
1424
- getClientAddress,
1425
- prerendering: {
1426
- fallback: true,
1427
- dependencies: new Map()
1428
- }
1429
- });
1430
-
1431
- const file = `${config.outDir}/output/prerendered/fallback.html`;
1432
- mkdirp(dirname(file));
1433
- writeFileSync(file, await rendered.text());
1434
-
1435
- return prerendered;
1436
- }
1437
-
1438
- /** @return {string} */
1439
- function getClientAddress() {
1440
- throw new Error('Cannot read clientAddress during prerendering');
1441
- }
1442
-
1443
594
  function totalist(dir, callback, pre='') {
1444
- dir = resolve$1('.', dir);
595
+ dir = resolve('.', dir);
1445
596
  let arr = readdirSync(dir);
1446
597
  let i=0, abs, stats;
1447
598
  for (; i < arr.length; i++) {
@@ -2015,7 +1166,7 @@ function toHeaders(name, stats, isEtag) {
2015
1166
  }
2016
1167
 
2017
1168
  function sirv (dir, opts={}) {
2018
- dir = resolve$1(dir || '.');
1169
+ dir = resolve(dir || '.');
2019
1170
 
2020
1171
  let isNotFound = opts.onNoMatch || is404;
2021
1172
  let setHeaders = opts.setHeaders || noop;
@@ -2106,12 +1257,13 @@ const cwd$1 = process.cwd();
2106
1257
  * @param {import('vite').ViteDevServer} vite
2107
1258
  * @param {import('vite').ResolvedConfig} vite_config
2108
1259
  * @param {import('types').ValidatedConfig} svelte_config
1260
+ * @param {Set<string>} illegal_imports
2109
1261
  * @return {Promise<Promise<() => void>>}
2110
1262
  */
2111
- async function dev(vite, vite_config, svelte_config) {
1263
+ async function dev(vite, vite_config, svelte_config, illegal_imports) {
2112
1264
  installPolyfills();
2113
1265
 
2114
- init(svelte_config);
1266
+ init(svelte_config, vite_config.mode);
2115
1267
 
2116
1268
  const runtime = get_runtime_prefix(svelte_config.kit);
2117
1269
 
@@ -2142,6 +1294,11 @@ async function dev(vite, vite_config, svelte_config) {
2142
1294
  await vite.ssrLoadModule(url)
2143
1295
  );
2144
1296
 
1297
+ const node = await vite.moduleGraph.getModuleByUrl(url);
1298
+ if (!node) throw new Error(`Could not find node for ${url}`);
1299
+
1300
+ prevent_illegal_vite_imports(node, illegal_imports, svelte_config.kit.outDir);
1301
+
2145
1302
  return {
2146
1303
  module,
2147
1304
  index,
@@ -2150,10 +1307,6 @@ async function dev(vite, vite_config, svelte_config) {
2150
1307
  stylesheets: [],
2151
1308
  // in dev we inline all styles to avoid FOUC
2152
1309
  inline_styles: async () => {
2153
- const node = await vite.moduleGraph.getModuleByUrl(url);
2154
-
2155
- if (!node) throw new Error(`Could not find node for ${url}`);
2156
-
2157
1310
  const deps = new Set();
2158
1311
  await find_deps(vite, node, deps);
2159
1312
 
@@ -2262,37 +1415,50 @@ async function dev(vite, vite_config, svelte_config) {
2262
1415
  extensions: []
2263
1416
  });
2264
1417
 
1418
+ vite.middlewares.use(async (req, res, next) => {
1419
+ try {
1420
+ const base = `${vite.config.server.https ? 'https' : 'http'}://${
1421
+ req.headers[':authority'] || req.headers.host
1422
+ }`;
1423
+
1424
+ const decoded = decodeURI(new URL$1(base + req.url).pathname);
1425
+
1426
+ if (decoded.startsWith(assets)) {
1427
+ const pathname = decoded.slice(assets.length);
1428
+ const file = svelte_config.kit.files.assets + pathname;
1429
+
1430
+ if (fs__default.existsSync(file) && !fs__default.statSync(file).isDirectory()) {
1431
+ if (has_correct_case(file, svelte_config.kit.files.assets)) {
1432
+ req.url = encodeURI(pathname); // don't need query/hash
1433
+ asset_server(req, res);
1434
+ return;
1435
+ }
1436
+ }
1437
+ }
1438
+
1439
+ next();
1440
+ } catch (e) {
1441
+ const error = coalesce_to_error(e);
1442
+ res.statusCode = 500;
1443
+ res.end(fix_stack_trace(error));
1444
+ }
1445
+ });
1446
+
2265
1447
  return () => {
2266
1448
  const serve_static_middleware = vite.middlewares.stack.find(
2267
1449
  (middleware) =>
2268
1450
  /** @type {function} */ (middleware.handle).name === 'viteServeStaticMiddleware'
2269
1451
  );
2270
1452
 
2271
- remove_html_middlewares(vite.middlewares);
1453
+ remove_static_middlewares(vite.middlewares);
2272
1454
 
2273
1455
  vite.middlewares.use(async (req, res) => {
2274
1456
  try {
2275
- if (!req.url || !req.method) throw new Error('Incomplete request');
2276
-
2277
1457
  const base = `${vite.config.server.https ? 'https' : 'http'}://${
2278
1458
  req.headers[':authority'] || req.headers.host
2279
1459
  }`;
2280
1460
 
2281
1461
  const decoded = decodeURI(new URL$1(base + req.url).pathname);
2282
-
2283
- if (decoded.startsWith(assets)) {
2284
- const pathname = decoded.slice(assets.length);
2285
- const file = svelte_config.kit.files.assets + pathname;
2286
-
2287
- if (fs__default.existsSync(file) && !fs__default.statSync(file).isDirectory()) {
2288
- if (has_correct_case(file, svelte_config.kit.files.assets)) {
2289
- req.url = encodeURI(pathname); // don't need query/hash
2290
- asset_server(req, res);
2291
- return;
2292
- }
2293
- }
2294
- }
2295
-
2296
1462
  const file = posixify(path__default.resolve(decoded.slice(1)));
2297
1463
  const is_file = fs__default.existsSync(file) && !fs__default.statSync(file).isDirectory();
2298
1464
  const allowed =
@@ -2317,6 +1483,17 @@ async function dev(vite, vite_config, svelte_config) {
2317
1483
  ? await vite.ssrLoadModule(`/${svelte_config.kit.files.hooks}`)
2318
1484
  : {};
2319
1485
 
1486
+ const runtime_base = true
1487
+ ? `/${posixify(path__default.relative(cwd$1, `${svelte_config.kit.outDir}/runtime`))}`
1488
+ : `/@fs${runtime}`;
1489
+
1490
+ const { set_private_env } = await vite.ssrLoadModule(`${runtime_base}/env-private.js`);
1491
+ const { set_public_env } = await vite.ssrLoadModule(`${runtime_base}/env-public.js`);
1492
+
1493
+ const env = get_env(vite_config.mode, svelte_config.kit.env.publicPrefix);
1494
+ set_private_env(env.private);
1495
+ set_public_env(env.public);
1496
+
2320
1497
  const handle = user_hooks.handle || (({ event, resolve }) => resolve(event));
2321
1498
 
2322
1499
  /** @type {import('types').Hooks} */
@@ -2357,11 +1534,7 @@ async function dev(vite, vite_config, svelte_config) {
2357
1534
  `/${posixify(path__default.relative(cwd$1, `${svelte_config.kit.outDir}/generated/root.svelte`))}`
2358
1535
  );
2359
1536
 
2360
- const paths = await vite.ssrLoadModule(
2361
- true
2362
- ? `/${posixify(path__default.relative(cwd$1, `${svelte_config.kit.outDir}/runtime/paths.js`))}`
2363
- : `/@fs${runtime}/paths.js`
2364
- );
1537
+ const paths = await vite.ssrLoadModule(`${runtime_base}/paths.js`);
2365
1538
 
2366
1539
  paths.set_paths({
2367
1540
  base: svelte_config.kit.paths.base,
@@ -2420,6 +1593,7 @@ async function dev(vite, vite_config, svelte_config) {
2420
1593
  default: svelte_config.kit.prerender.default,
2421
1594
  enabled: svelte_config.kit.prerender.enabled
2422
1595
  },
1596
+ public_env: env.public,
2423
1597
  read: (file) => fs__default.readFileSync(path__default.join(svelte_config.kit.files.assets, file)),
2424
1598
  root,
2425
1599
  router: svelte_config.kit.browser.router,
@@ -2471,11 +1645,15 @@ function not_found(res, message = 'Not found') {
2471
1645
  /**
2472
1646
  * @param {import('connect').Server} server
2473
1647
  */
2474
- function remove_html_middlewares(server) {
2475
- const html_middlewares = ['viteServeStaticMiddleware'];
1648
+ function remove_static_middlewares(server) {
1649
+ // We don't use viteServePublicMiddleware because of the following issues:
1650
+ // https://github.com/vitejs/vite/issues/9260
1651
+ // https://github.com/vitejs/vite/issues/9236
1652
+ // https://github.com/vitejs/vite/issues/9234
1653
+ const static_middlewares = ['viteServePublicMiddleware', 'viteServeStaticMiddleware'];
2476
1654
  for (let i = server.stack.length - 1; i > 0; i--) {
2477
- // @ts-expect-error using internals until https://github.com/vitejs/vite/pull/4640 is merged
2478
- if (html_middlewares.includes(server.stack[i].handle.name)) {
1655
+ // @ts-expect-error using internals
1656
+ if (static_middlewares.includes(server.stack[i].handle.name)) {
2479
1657
  server.stack.splice(i, 1);
2480
1658
  }
2481
1659
  }
@@ -2670,20 +1848,22 @@ function generate_manifest({ build_data, relative_path, routes, format = 'esm' }
2670
1848
  * middlewares: import('connect').Server;
2671
1849
  * httpServer: import('http').Server;
2672
1850
  * }} vite
2673
- * @param {import('types').ValidatedConfig} config
2674
- * @param {'http' | 'https'} protocol
1851
+ * @param {import('vite').ResolvedConfig} vite_config
1852
+ * @param {import('types').ValidatedConfig} svelte_config
2675
1853
  */
2676
- async function preview(vite, config, protocol) {
1854
+ async function preview(vite, vite_config, svelte_config) {
2677
1855
  installPolyfills();
2678
1856
 
2679
- const { paths } = config.kit;
1857
+ const { paths } = svelte_config.kit;
2680
1858
  const base = paths.base;
2681
1859
  const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;
2682
1860
 
1861
+ const protocol = vite_config.preview.https ? 'https' : 'http';
1862
+
2683
1863
  const etag = `"${Date.now()}"`;
2684
1864
 
2685
- const index_file = join(config.kit.outDir, 'output/server/index.js');
2686
- const manifest_file = join(config.kit.outDir, 'output/server/manifest.js');
1865
+ const index_file = join(svelte_config.kit.outDir, 'output/server/index.js');
1866
+ const manifest_file = join(svelte_config.kit.outDir, 'output/server/manifest.js');
2687
1867
 
2688
1868
  /** @type {import('types').ServerModule} */
2689
1869
  const { Server, override } = await import(pathToFileURL(index_file).href);
@@ -2693,23 +1873,23 @@ async function preview(vite, config, protocol) {
2693
1873
  paths: { base, assets },
2694
1874
  prerendering: false,
2695
1875
  protocol,
2696
- read: (file) => fs__default.readFileSync(join(config.kit.files.assets, file))
1876
+ read: (file) => fs__default.readFileSync(join(svelte_config.kit.files.assets, file))
2697
1877
  });
2698
1878
 
2699
1879
  const server = new Server(manifest);
1880
+ server.init({
1881
+ env: loadEnv(vite_config.mode, process.cwd(), '')
1882
+ });
2700
1883
 
2701
1884
  return () => {
2702
- // files in `static`
2703
- vite.middlewares.use(scoped(assets, mutable(config.kit.files.assets)));
2704
-
2705
- // immutable generated client assets
1885
+ // generated client assets and the contents of `static`
2706
1886
  vite.middlewares.use(
2707
1887
  scoped(
2708
1888
  assets,
2709
- sirv(join(config.kit.outDir, 'output/client'), {
1889
+ sirv(join(svelte_config.kit.outDir, 'output/client'), {
2710
1890
  setHeaders: (res, pathname) => {
2711
- // only apply to build directory, not e.g. version.json
2712
- if (pathname.startsWith(`/${config.kit.appDir}/immutable`)) {
1891
+ // only apply to immutable directory, not e.g. version.json
1892
+ if (pathname.startsWith(`/${svelte_config.kit.appDir}/immutable`)) {
2713
1893
  res.setHeader('cache-control', 'public,max-age=31536000,immutable');
2714
1894
  }
2715
1895
  }
@@ -2731,7 +1911,7 @@ async function preview(vite, config, protocol) {
2731
1911
 
2732
1912
  // prerendered dependencies
2733
1913
  vite.middlewares.use(
2734
- scoped(base, mutable(join(config.kit.outDir, 'output/prerendered/dependencies')))
1914
+ scoped(base, mutable(join(svelte_config.kit.outDir, 'output/prerendered/dependencies')))
2735
1915
  );
2736
1916
 
2737
1917
  // prerendered pages (we can't just use sirv because we need to
@@ -2755,7 +1935,7 @@ async function preview(vite, config, protocol) {
2755
1935
  // only treat this as a page if it doesn't include an extension
2756
1936
  if (pathname === '/' || /\/[^./]+\/?$/.test(pathname)) {
2757
1937
  const file = join(
2758
- config.kit.outDir,
1938
+ svelte_config.kit.outDir,
2759
1939
  'output/prerendered/pages' +
2760
1940
  pathname +
2761
1941
  (pathname.endsWith('/') ? 'index.html' : '.html')
@@ -2921,6 +2101,9 @@ function kit() {
2921
2101
  /** @type {import('types').BuildData} */
2922
2102
  let build_data;
2923
2103
 
2104
+ /** @type {Set<string>} */
2105
+ let illegal_imports;
2106
+
2924
2107
  /** @type {string | undefined} */
2925
2108
  let deferred_warning;
2926
2109
 
@@ -2947,12 +2130,12 @@ function kit() {
2947
2130
  // for everything regardless — but it means that entry chunks reflect
2948
2131
  // their location in the source code, which is helpful for debugging
2949
2132
  manifest_data.components.forEach((file) => {
2950
- const resolved = path__default.resolve(cwd, file);
2951
- const relative = decodeURIComponent(path__default.relative(svelte_config.kit.files.routes, resolved));
2133
+ const resolved = path.resolve(cwd, file);
2134
+ const relative = decodeURIComponent(path.relative(svelte_config.kit.files.routes, resolved));
2952
2135
 
2953
2136
  const name = relative.startsWith('..')
2954
- ? path__default.basename(file)
2955
- : posixify(path__default.join('pages', relative));
2137
+ ? path.basename(file)
2138
+ : posixify(path.join('pages', relative));
2956
2139
  input[name] = resolved;
2957
2140
  });
2958
2141
 
@@ -2971,11 +2154,11 @@ function kit() {
2971
2154
  function client_build_info(assets, chunks) {
2972
2155
  /** @type {import('vite').Manifest} */
2973
2156
  const vite_manifest = JSON.parse(
2974
- fs__default.readFileSync(`${paths.client_out_dir}/manifest.json`, 'utf-8')
2157
+ fs$1.readFileSync(`${paths.client_out_dir}/manifest.json`, 'utf-8')
2975
2158
  );
2976
2159
 
2977
2160
  const entry_id = posixify(
2978
- path__default.relative(cwd, `${get_runtime_directory(svelte_config.kit)}/client/start.js`)
2161
+ path.relative(cwd, `${get_runtime_directory(svelte_config.kit)}/client/start.js`)
2979
2162
  );
2980
2163
 
2981
2164
  return {
@@ -3007,8 +2190,13 @@ function kit() {
3007
2190
  client_out_dir: `${svelte_config.kit.outDir}/output/client/`
3008
2191
  };
3009
2192
 
2193
+ illegal_imports = new Set([
2194
+ `${svelte_config.kit.outDir}/runtime/env/dynamic/private.js`,
2195
+ `${svelte_config.kit.outDir}/runtime/env/static/private.js`
2196
+ ]);
2197
+
3010
2198
  if (is_build) {
3011
- manifest_data = all(svelte_config).manifest_data;
2199
+ manifest_data = all(svelte_config, config_env.mode).manifest_data;
3012
2200
 
3013
2201
  const new_config = vite_client_build_config();
3014
2202
 
@@ -3034,6 +2222,7 @@ function kit() {
3034
2222
  __SVELTEKIT_DEV__: 'true',
3035
2223
  __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: '0'
3036
2224
  },
2225
+ publicDir: svelte_config.kit.files.assets,
3037
2226
  resolve: {
3038
2227
  alias: get_aliases(svelte_config.kit)
3039
2228
  },
@@ -3045,9 +2234,9 @@ function kit() {
3045
2234
  svelte_config.kit.files.lib,
3046
2235
  svelte_config.kit.files.routes,
3047
2236
  svelte_config.kit.outDir,
3048
- path__default.resolve(cwd, 'src'),
3049
- path__default.resolve(cwd, 'node_modules'),
3050
- path__default.resolve(vite.searchForWorkspaceRoot(cwd), 'node_modules')
2237
+ path.resolve(cwd, 'src'),
2238
+ path.resolve(cwd, 'node_modules'),
2239
+ path.resolve(vite.searchForWorkspaceRoot(cwd), 'node_modules')
3051
2240
  ])
3052
2241
  ]
3053
2242
  },
@@ -3093,11 +2282,26 @@ function kit() {
3093
2282
  * then use this hook to kick off builds for the server and service worker.
3094
2283
  */
3095
2284
  async writeBundle(_options, bundle) {
2285
+ for (const file of manifest_data.components) {
2286
+ const id = path.resolve(file);
2287
+ const node = this.getModuleInfo(id);
2288
+
2289
+ if (node) {
2290
+ prevent_illegal_rollup_imports(
2291
+ this.getModuleInfo.bind(this),
2292
+ node,
2293
+ illegal_imports,
2294
+ svelte_config.kit.outDir
2295
+ );
2296
+ }
2297
+ }
2298
+
2299
+ const verbose = vite_config.logLevel === 'info';
3096
2300
  log = logger({
3097
- verbose: vite_config.logLevel === 'info'
2301
+ verbose
3098
2302
  });
3099
2303
 
3100
- fs__default.writeFileSync(
2304
+ fs$1.writeFileSync(
3101
2305
  `${paths.client_out_dir}/${svelte_config.kit.appDir}/version.json`,
3102
2306
  JSON.stringify({ version: svelte_config.kit.version.name })
3103
2307
  );
@@ -3109,6 +2313,7 @@ function kit() {
3109
2313
  const options = {
3110
2314
  cwd,
3111
2315
  config: svelte_config,
2316
+ vite_config,
3112
2317
  vite_config_env,
3113
2318
  build_dir: paths.build_dir, // TODO just pass `paths`
3114
2319
  manifest_data,
@@ -3128,7 +2333,7 @@ function kit() {
3128
2333
  };
3129
2334
 
3130
2335
  const manifest_path = `${paths.output_dir}/server/manifest.js`;
3131
- fs__default.writeFileSync(
2336
+ fs$1.writeFileSync(
3132
2337
  manifest_path,
3133
2338
  `export const manifest = ${generate_manifest({
3134
2339
  build_data,
@@ -3137,14 +2342,39 @@ function kit() {
3137
2342
  })};\n`
3138
2343
  );
3139
2344
 
3140
- process.env.SVELTEKIT_SERVER_BUILD_COMPLETED = 'true';
3141
2345
  log.info('Prerendering');
2346
+ await new Promise((fulfil, reject) => {
2347
+ const results_path = `${svelte_config.kit.outDir}/generated/prerendered.json`;
2348
+
2349
+ // do prerendering in a subprocess so any dangling stuff gets killed upon completion
2350
+ const script = fileURLToPath(
2351
+ new URL(
2352
+ './prerender.js' ,
2353
+ import.meta.url
2354
+ )
2355
+ );
3142
2356
 
3143
- prerendered = await prerender({
3144
- config: svelte_config.kit,
3145
- client_out_dir: vite_config.build.outDir,
3146
- manifest_path,
3147
- log
2357
+ const child = fork(
2358
+ script,
2359
+ [vite_config.build.outDir, results_path, manifest_path, '' + verbose],
2360
+ {
2361
+ stdio: 'inherit'
2362
+ }
2363
+ );
2364
+
2365
+ child.on('exit', (code) => {
2366
+ if (code) {
2367
+ reject(new Error(`Prerendering failed with code ${code}`));
2368
+ } else {
2369
+ prerendered = JSON.parse(fs$1.readFileSync(results_path, 'utf8'), (key, value) => {
2370
+ if (key === 'pages' || key === 'assets' || key === 'redirects') {
2371
+ return new Map(value);
2372
+ }
2373
+ return value;
2374
+ });
2375
+ fulfil(undefined);
2376
+ }
2377
+ });
3148
2378
  });
3149
2379
 
3150
2380
  if (options.service_worker_entry_file) {
@@ -3175,7 +2405,7 @@ function kit() {
3175
2405
  }
3176
2406
 
3177
2407
  if (svelte_config.kit.adapter) {
3178
- const { adapt } = await import('./chunks/index2.js');
2408
+ const { adapt } = await import('./chunks/index3.js');
3179
2409
  await adapt(svelte_config, build_data, prerendered, { log });
3180
2410
  } else {
3181
2411
  console.log($.bold().yellow('\nNo adapter specified'));
@@ -3184,13 +2414,6 @@ function kit() {
3184
2414
  `See ${$.bold().cyan('https://kit.svelte.dev/docs/adapters')} to learn how to configure your app to run on the platform of your choosing`
3185
2415
  );
3186
2416
  }
3187
-
3188
- if (svelte_config.kit.prerender.enabled) {
3189
- // this is necessary to close any open db connections, etc.
3190
- // TODO: prerender in a subprocess so we can exit in isolation and then remove this
3191
- // https://github.com/sveltejs/kit/issues/5306
3192
- process.exit(0);
3193
- }
3194
2417
  },
3195
2418
 
3196
2419
  /**
@@ -3206,7 +2429,7 @@ function kit() {
3206
2429
  if (deferred_warning) console.error('\n' + deferred_warning);
3207
2430
  };
3208
2431
 
3209
- return await dev(vite, vite_config, svelte_config);
2432
+ return await dev(vite, vite_config, svelte_config, illegal_imports);
3210
2433
  },
3211
2434
 
3212
2435
  /**
@@ -3214,7 +2437,7 @@ function kit() {
3214
2437
  * @see https://vitejs.dev/guide/api-plugin.html#configurepreviewserver
3215
2438
  */
3216
2439
  configurePreviewServer(vite) {
3217
- return preview(vite, svelte_config, vite_config.preview.https ? 'https' : 'http');
2440
+ return preview(vite, vite_config, svelte_config);
3218
2441
  }
3219
2442
  };
3220
2443
  }