@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/assets/client/start.js +9 -2
- package/assets/env/dynamic/private.js +1 -0
- package/assets/env/dynamic/public.js +1 -0
- package/assets/env-private.js +9 -0
- package/assets/env-public.js +9 -0
- package/assets/server/index.js +4 -1
- package/dist/chunks/error.js +1 -671
- package/dist/chunks/filesystem.js +110 -0
- package/dist/chunks/index.js +574 -15643
- package/dist/chunks/index2.js +15705 -177
- package/dist/chunks/index3.js +218 -0
- package/dist/chunks/sync.js +377 -70
- package/dist/chunks/utils.js +66 -0
- package/dist/chunks/write_tsconfig.js +64 -121
- package/dist/cli.js +8 -6
- package/dist/prerender.js +788 -0
- package/dist/vite.js +194 -971
- package/package.json +1 -1
- package/types/ambient.d.ts +58 -12
- package/types/index.d.ts +8 -0
- package/types/internal.d.ts +8 -0
package/dist/vite.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { a as load_template, $,
|
|
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 {
|
|
8
|
-
import { p as posixify, m as mkdirp,
|
|
9
|
-
import { g as
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
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
|
-
|
|
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
|
|
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
|
-
'&': '&',
|
|
1055
|
-
'"': '"'
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
2475
|
-
|
|
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
|
|
2478
|
-
if (
|
|
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('
|
|
2674
|
-
* @param {'
|
|
1851
|
+
* @param {import('vite').ResolvedConfig} vite_config
|
|
1852
|
+
* @param {import('types').ValidatedConfig} svelte_config
|
|
2675
1853
|
*/
|
|
2676
|
-
async function preview(vite,
|
|
1854
|
+
async function preview(vite, vite_config, svelte_config) {
|
|
2677
1855
|
installPolyfills();
|
|
2678
1856
|
|
|
2679
|
-
const { paths } =
|
|
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(
|
|
2686
|
-
const manifest_file = join(
|
|
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(
|
|
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
|
-
//
|
|
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(
|
|
1889
|
+
sirv(join(svelte_config.kit.outDir, 'output/client'), {
|
|
2710
1890
|
setHeaders: (res, pathname) => {
|
|
2711
|
-
// only apply to
|
|
2712
|
-
if (pathname.startsWith(`/${
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
2951
|
-
const relative = decodeURIComponent(
|
|
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
|
-
?
|
|
2955
|
-
: posixify(
|
|
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
|
-
|
|
2157
|
+
fs$1.readFileSync(`${paths.client_out_dir}/manifest.json`, 'utf-8')
|
|
2975
2158
|
);
|
|
2976
2159
|
|
|
2977
2160
|
const entry_id = posixify(
|
|
2978
|
-
|
|
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
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
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
|
|
2301
|
+
verbose
|
|
3098
2302
|
});
|
|
3099
2303
|
|
|
3100
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
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/
|
|
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,
|
|
2440
|
+
return preview(vite, vite_config, svelte_config);
|
|
3218
2441
|
}
|
|
3219
2442
|
};
|
|
3220
2443
|
}
|