@sveltejs/kit 1.0.0-next.168 → 1.0.0-next.171
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/runtime/internal/start.js +6 -5
- package/dist/chunks/cert.js +2494 -2338
- package/dist/chunks/index.js +2348 -1273
- package/dist/chunks/index2.js +44 -23
- package/dist/chunks/index3.js +604 -23
- package/dist/chunks/index4.js +303 -522
- package/dist/chunks/index5.js +328 -303
- package/dist/chunks/index6.js +19408 -296
- package/dist/cli.js +6 -6
- package/dist/ssr.js +41 -34
- package/package.json +17 -17
- package/types/internal.d.ts +1 -3
- package/dist/chunks/_commonjsHelpers.js +0 -8
- package/dist/chunks/index7.js +0 -19368
package/dist/chunks/index5.js
CHANGED
|
@@ -1,382 +1,407 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import fs__default, { readdirSync, statSync } from 'fs';
|
|
3
|
+
import http from 'http';
|
|
4
|
+
import https from 'https';
|
|
5
|
+
import { resolve, join, normalize } from 'path';
|
|
6
|
+
import * as require$$7 from 'querystring';
|
|
7
|
+
import { s as standard, M as Mime_1 } from './standard.js';
|
|
8
|
+
import { pathToFileURL } from 'url';
|
|
9
|
+
import { getRawBody } from '../node.js';
|
|
6
10
|
import { __fetch_polyfill } from '../install-fetch.js';
|
|
7
|
-
import {
|
|
8
|
-
import 'sade';
|
|
9
|
-
import 'child_process';
|
|
10
|
-
import 'net';
|
|
11
|
-
import 'os';
|
|
12
|
-
import './error.js';
|
|
13
|
-
import 'http';
|
|
14
|
-
import 'https';
|
|
11
|
+
import { S as SVELTE_KIT, a as SVELTE_KIT_ASSETS } from './constants.js';
|
|
15
12
|
import 'zlib';
|
|
16
13
|
import 'stream';
|
|
17
14
|
import 'util';
|
|
18
15
|
import 'crypto';
|
|
19
16
|
|
|
20
17
|
/**
|
|
21
|
-
* @typedef
|
|
22
|
-
* @
|
|
23
|
-
* @typedef {import('types/internal').Logger} Logger
|
|
18
|
+
* @typedef ParsedURL
|
|
19
|
+
* @type {import('.').ParsedURL}
|
|
24
20
|
*/
|
|
25
21
|
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.replace(/(<style[\s\S]*?>)[\s\S]*?<\/style>/gm, '$1</' + 'style>')
|
|
32
|
-
.replace(/<!--[\s\S]*?-->/gm, '');
|
|
33
|
-
}
|
|
22
|
+
/**
|
|
23
|
+
* @typedef Request
|
|
24
|
+
* @property {string} url
|
|
25
|
+
* @property {ParsedURL} _parsedUrl
|
|
26
|
+
*/
|
|
34
27
|
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
/**
|
|
29
|
+
* @param {Request} req
|
|
30
|
+
* @returns {ParsedURL|void}
|
|
31
|
+
*/
|
|
32
|
+
function parse(req) {
|
|
33
|
+
let raw = req.url;
|
|
34
|
+
if (raw == null) return;
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const match = /(?:[\s'"]|^)src\s*=\s*(?:"(.*?)"|'(.*?)'|([^\s>]*))/.exec(attrs);
|
|
44
|
-
return match && (match[1] || match[2] || match[3]);
|
|
45
|
-
}
|
|
36
|
+
let prev = req._parsedUrl;
|
|
37
|
+
if (prev && prev.raw === raw) return prev;
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
39
|
+
let pathname=raw, search='', query;
|
|
40
|
+
|
|
41
|
+
if (raw.length > 1) {
|
|
42
|
+
let idx = raw.indexOf('?', 1);
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const attr_content = match[1] || match[2] || match[3];
|
|
60
|
-
// Parse the content of the srcset attribute.
|
|
61
|
-
// The regexp is modelled after the srcset specs (https://html.spec.whatwg.org/multipage/images.html#srcset-attribute)
|
|
62
|
-
// and should cover most reasonable cases.
|
|
63
|
-
const regex = /\s*([^\s,]\S+[^\s,])\s*((?:\d+w)|(?:-?\d+(?:\.\d+)?(?:[eE]-?\d+)?x))?/gm;
|
|
64
|
-
let sub_matches;
|
|
65
|
-
while ((sub_matches = regex.exec(attr_content))) {
|
|
66
|
-
results.push(sub_matches[1]);
|
|
44
|
+
if (idx !== -1) {
|
|
45
|
+
search = raw.substring(idx);
|
|
46
|
+
pathname = raw.substring(0, idx);
|
|
47
|
+
if (search.length > 1) {
|
|
48
|
+
query = require$$7.parse(search.substring(1));
|
|
49
|
+
}
|
|
67
50
|
}
|
|
68
51
|
}
|
|
69
|
-
return results;
|
|
70
|
-
}
|
|
71
52
|
|
|
72
|
-
|
|
73
|
-
function errorDetailsToString({ status, path, referrer, referenceType }) {
|
|
74
|
-
return `${status} ${path}${referrer ? ` (${referenceType} from ${referrer})` : ''}`;
|
|
53
|
+
return req._parsedUrl = { pathname, search, query, raw };
|
|
75
54
|
}
|
|
76
55
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
};
|
|
88
|
-
default:
|
|
89
|
-
return onError;
|
|
56
|
+
function list(dir, callback, pre='') {
|
|
57
|
+
dir = resolve('.', dir);
|
|
58
|
+
let arr = readdirSync(dir);
|
|
59
|
+
let i=0, abs, stats;
|
|
60
|
+
for (; i < arr.length; i++) {
|
|
61
|
+
abs = join(dir, arr[i]);
|
|
62
|
+
stats = statSync(abs);
|
|
63
|
+
stats.isDirectory()
|
|
64
|
+
? list(abs, callback, join(pre, arr[i]))
|
|
65
|
+
: callback(join(pre, arr[i]), abs, stats);
|
|
90
66
|
}
|
|
91
67
|
}
|
|
92
68
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @param {{
|
|
98
|
-
* cwd: string;
|
|
99
|
-
* out: string;
|
|
100
|
-
* log: Logger;
|
|
101
|
-
* config: import('types/config').ValidatedConfig;
|
|
102
|
-
* build_data: import('types/internal').BuildData;
|
|
103
|
-
* fallback?: string;
|
|
104
|
-
* all: boolean; // disregard `export const prerender = true`
|
|
105
|
-
* }} opts
|
|
106
|
-
*/
|
|
107
|
-
async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
|
|
108
|
-
if (!config.kit.prerender.enabled && !fallback) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
69
|
+
let Mime = Mime_1;
|
|
70
|
+
var lite = new Mime(standard);
|
|
111
71
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const dir = resolve(cwd, `${SVELTE_KIT}/output`);
|
|
115
|
-
|
|
116
|
-
const seen = new Set();
|
|
72
|
+
const noop = () => {};
|
|
117
73
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
74
|
+
function isMatch(uri, arr) {
|
|
75
|
+
for (let i=0; i < arr.length; i++) {
|
|
76
|
+
if (arr[i].test(uri)) return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
122
79
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
80
|
+
function toAssume(uri, extns) {
|
|
81
|
+
let i=0, x, len=uri.length - 1;
|
|
82
|
+
if (uri.charCodeAt(len) === 47) {
|
|
83
|
+
uri = uri.substring(0, len);
|
|
84
|
+
}
|
|
128
85
|
|
|
129
|
-
|
|
86
|
+
let arr=[], tmp=`${uri}/index`;
|
|
87
|
+
for (; i < extns.length; i++) {
|
|
88
|
+
x = extns[i] ? `.${extns[i]}` : '';
|
|
89
|
+
if (uri) arr.push(uri + x);
|
|
90
|
+
arr.push(tmp + x);
|
|
91
|
+
}
|
|
130
92
|
|
|
131
|
-
|
|
93
|
+
return arr;
|
|
94
|
+
}
|
|
132
95
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
96
|
+
function viaCache(cache, uri, extns) {
|
|
97
|
+
let i=0, data, arr=toAssume(uri, extns);
|
|
98
|
+
for (; i < arr.length; i++) {
|
|
99
|
+
if (data = cache[arr[i]]) return data;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
138
102
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
103
|
+
function viaLocal(dir, isEtag, uri, extns) {
|
|
104
|
+
let i=0, arr=toAssume(uri, extns);
|
|
105
|
+
let abs, stats, name, headers;
|
|
106
|
+
for (; i < arr.length; i++) {
|
|
107
|
+
abs = normalize(join(dir, name=arr[i]));
|
|
108
|
+
if (abs.startsWith(dir) && fs.existsSync(abs)) {
|
|
109
|
+
stats = fs.statSync(abs);
|
|
110
|
+
if (stats.isDirectory()) continue;
|
|
111
|
+
headers = toHeaders(name, stats, isEtag);
|
|
112
|
+
headers['Cache-Control'] = isEtag ? 'no-cache' : 'no-store';
|
|
113
|
+
return { abs, stats, headers };
|
|
147
114
|
}
|
|
148
|
-
|
|
149
|
-
return path;
|
|
150
115
|
}
|
|
116
|
+
}
|
|
151
117
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
*/
|
|
156
|
-
async function visit(decoded_path, referrer) {
|
|
157
|
-
const path = encodeURI(normalize(decoded_path));
|
|
158
|
-
|
|
159
|
-
if (seen.has(path)) return;
|
|
160
|
-
seen.add(path);
|
|
161
|
-
|
|
162
|
-
/** @type {Map<string, import('types/hooks').ServerResponse>} */
|
|
163
|
-
const dependencies = new Map();
|
|
164
|
-
|
|
165
|
-
const rendered = await app.render(
|
|
166
|
-
{
|
|
167
|
-
host: config.kit.host,
|
|
168
|
-
method: 'GET',
|
|
169
|
-
headers: {},
|
|
170
|
-
path,
|
|
171
|
-
rawBody: null,
|
|
172
|
-
query: new URLSearchParams()
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
prerender: {
|
|
176
|
-
all,
|
|
177
|
-
dependencies
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
if (rendered) {
|
|
183
|
-
const response_type = Math.floor(rendered.status / 100);
|
|
184
|
-
const headers = rendered.headers;
|
|
185
|
-
const type = headers && headers['content-type'];
|
|
186
|
-
const is_html = response_type === REDIRECT || type === 'text/html';
|
|
118
|
+
function is404(req, res) {
|
|
119
|
+
return (res.statusCode=404,res.end());
|
|
120
|
+
}
|
|
187
121
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
122
|
+
function send(req, res, file, stats, headers) {
|
|
123
|
+
let code=200, tmp, opts={};
|
|
124
|
+
headers = { ...headers };
|
|
192
125
|
|
|
193
|
-
|
|
194
|
-
|
|
126
|
+
for (let key in headers) {
|
|
127
|
+
tmp = res.getHeader(key);
|
|
128
|
+
if (tmp) headers[key] = tmp;
|
|
129
|
+
}
|
|
195
130
|
|
|
196
|
-
|
|
197
|
-
|
|
131
|
+
if (tmp = res.getHeader('content-type')) {
|
|
132
|
+
headers['Content-Type'] = tmp;
|
|
133
|
+
}
|
|
198
134
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
135
|
+
if (req.headers.range) {
|
|
136
|
+
code = 206;
|
|
137
|
+
let [x, y] = req.headers.range.replace('bytes=', '').split('-');
|
|
138
|
+
let end = opts.end = parseInt(y, 10) || stats.size - 1;
|
|
139
|
+
let start = opts.start = parseInt(x, 10) || 0;
|
|
205
140
|
|
|
206
|
-
|
|
207
|
-
}
|
|
141
|
+
if (start >= stats.size || end >= stats.size) {
|
|
142
|
+
res.setHeader('Content-Range', `bytes */${stats.size}`);
|
|
143
|
+
res.statusCode = 416;
|
|
144
|
+
return res.end();
|
|
145
|
+
}
|
|
208
146
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
error({ status: rendered.status, path, referrer, referenceType: 'linked' });
|
|
214
|
-
}
|
|
147
|
+
headers['Content-Range'] = `bytes ${start}-${end}/${stats.size}`;
|
|
148
|
+
headers['Content-Length'] = (end - start + 1);
|
|
149
|
+
headers['Accept-Ranges'] = 'bytes';
|
|
150
|
+
}
|
|
215
151
|
|
|
216
|
-
|
|
217
|
-
|
|
152
|
+
res.writeHead(code, headers);
|
|
153
|
+
fs.createReadStream(file, opts).pipe(res);
|
|
154
|
+
}
|
|
218
155
|
|
|
219
|
-
|
|
156
|
+
function isEncoding(name, type, headers) {
|
|
157
|
+
headers['Content-Encoding'] = type;
|
|
158
|
+
headers['Content-Type'] = lite.getType(name.replace(/\.([^.]*)$/, '')) || '';
|
|
159
|
+
}
|
|
220
160
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
161
|
+
function toHeaders(name, stats, isEtag) {
|
|
162
|
+
let headers = {
|
|
163
|
+
'Content-Length': stats.size,
|
|
164
|
+
'Content-Type': lite.getType(name) || '',
|
|
165
|
+
'Last-Modified': stats.mtime.toUTCString(),
|
|
166
|
+
};
|
|
167
|
+
if (isEtag) headers['ETag'] = `W/"${stats.size}-${stats.mtime.getTime()}"`;
|
|
168
|
+
if (/\.br$/.test(name)) isEncoding(name, 'br', headers);
|
|
169
|
+
if (/\.gz$/.test(name)) isEncoding(name, 'gzip', headers);
|
|
170
|
+
return headers;
|
|
171
|
+
}
|
|
225
172
|
|
|
226
|
-
|
|
227
|
-
|
|
173
|
+
function sirv (dir, opts={}) {
|
|
174
|
+
dir = resolve(dir || '.');
|
|
228
175
|
|
|
229
|
-
|
|
176
|
+
let isNotFound = opts.onNoMatch || is404;
|
|
177
|
+
let setHeaders = opts.setHeaders || noop;
|
|
230
178
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
error({
|
|
235
|
-
status: result.status,
|
|
236
|
-
path: dependency_path,
|
|
237
|
-
referrer: path,
|
|
238
|
-
referenceType: 'fetched'
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
});
|
|
179
|
+
let extensions = opts.extensions || ['html', 'htm'];
|
|
180
|
+
let gzips = opts.gzip && extensions.map(x => `${x}.gz`).concat('gz');
|
|
181
|
+
let brots = opts.brotli && extensions.map(x => `${x}.br`).concat('br');
|
|
242
182
|
|
|
243
|
-
|
|
244
|
-
const cleaned = clean_html(/** @type {string} */ (rendered.body));
|
|
183
|
+
const FILES = {};
|
|
245
184
|
|
|
246
|
-
|
|
247
|
-
|
|
185
|
+
let fallback = '/';
|
|
186
|
+
let isEtag = !!opts.etag;
|
|
187
|
+
let isSPA = !!opts.single;
|
|
188
|
+
if (typeof opts.single === 'string') {
|
|
189
|
+
let idx = opts.single.lastIndexOf('.');
|
|
190
|
+
fallback += !!~idx ? opts.single.substring(0, idx) : opts.single;
|
|
191
|
+
}
|
|
248
192
|
|
|
249
|
-
|
|
193
|
+
let ignores = [];
|
|
194
|
+
if (opts.ignores !== false) {
|
|
195
|
+
ignores.push(/[/]([A-Za-z\s\d~$._-]+\.\w+){1,}$/); // any extn
|
|
196
|
+
if (opts.dotfiles) ignores.push(/\/\.\w/);
|
|
197
|
+
else ignores.push(/\/\.well-known/);
|
|
198
|
+
[].concat(opts.ignores || []).forEach(x => {
|
|
199
|
+
ignores.push(new RegExp(x, 'i'));
|
|
200
|
+
});
|
|
201
|
+
}
|
|
250
202
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
203
|
+
let cc = opts.maxAge != null && `public,max-age=${opts.maxAge}`;
|
|
204
|
+
if (cc && opts.immutable) cc += ',immutable';
|
|
205
|
+
else if (cc && opts.maxAge === 0) cc += ',must-revalidate';
|
|
254
206
|
|
|
255
|
-
|
|
256
|
-
|
|
207
|
+
if (!opts.dev) {
|
|
208
|
+
list(dir, (name, abs, stats) => {
|
|
209
|
+
if (/\.well-known[\\+\/]/.test(name)) ; // keep
|
|
210
|
+
else if (!opts.dotfiles && /(^\.|[\\+|\/+]\.)/.test(name)) return;
|
|
257
211
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (element === 'img') {
|
|
261
|
-
hrefs.push(get_src(attrs));
|
|
262
|
-
}
|
|
263
|
-
hrefs.push(...get_srcset_urls(attrs));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
212
|
+
let headers = toHeaders(name, stats, isEtag);
|
|
213
|
+
if (cc) headers['Cache-Control'] = cc;
|
|
266
214
|
|
|
267
|
-
|
|
268
|
-
|
|
215
|
+
FILES['/' + name.normalize().replace(/\\+/g, '/')] = { abs, stats, headers };
|
|
216
|
+
});
|
|
217
|
+
}
|
|
269
218
|
|
|
270
|
-
|
|
271
|
-
if (!resolved.startsWith('/') || resolved.startsWith('//')) continue;
|
|
219
|
+
let lookup = opts.dev ? viaLocal.bind(0, dir, isEtag) : viaCache.bind(0, FILES);
|
|
272
220
|
|
|
273
|
-
|
|
274
|
-
|
|
221
|
+
return function (req, res, next) {
|
|
222
|
+
let extns = [''];
|
|
223
|
+
let pathname = parse(req).pathname;
|
|
224
|
+
let val = req.headers['accept-encoding'] || '';
|
|
225
|
+
if (gzips && val.includes('gzip')) extns.unshift(...gzips);
|
|
226
|
+
if (brots && /(br|brotli)/i.test(val)) extns.unshift(...brots);
|
|
227
|
+
extns.push(...extensions); // [...br, ...gz, orig, ...exts]
|
|
275
228
|
|
|
276
|
-
|
|
277
|
-
|
|
229
|
+
if (pathname.indexOf('%') !== -1) {
|
|
230
|
+
try { pathname = decodeURIComponent(pathname); }
|
|
231
|
+
catch (err) { /* malform uri */ }
|
|
232
|
+
}
|
|
278
233
|
|
|
279
|
-
|
|
234
|
+
let data = lookup(pathname, extns) || isSPA && !isMatch(pathname, ignores) && lookup(fallback, extns);
|
|
235
|
+
if (!data) return next ? next() : isNotFound(req, res);
|
|
280
236
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
237
|
+
if (isEtag && req.headers['if-none-match'] === data.headers['ETag']) {
|
|
238
|
+
res.writeHead(304);
|
|
239
|
+
return res.end();
|
|
284
240
|
}
|
|
285
|
-
}
|
|
286
241
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (entry === '*') {
|
|
290
|
-
for (const entry of build_data.entries) {
|
|
291
|
-
await visit(entry, null);
|
|
292
|
-
}
|
|
293
|
-
} else {
|
|
294
|
-
await visit(entry, null);
|
|
295
|
-
}
|
|
242
|
+
if (gzips || brots) {
|
|
243
|
+
res.setHeader('Vary', 'Accept-Encoding');
|
|
296
244
|
}
|
|
297
|
-
}
|
|
298
245
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
host: config.kit.host,
|
|
303
|
-
method: 'GET',
|
|
304
|
-
headers: {},
|
|
305
|
-
path: '[fallback]', // this doesn't matter, but it's easiest if it's a string
|
|
306
|
-
rawBody: null,
|
|
307
|
-
query: new URLSearchParams()
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
prerender: {
|
|
311
|
-
fallback,
|
|
312
|
-
all: false
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
const file = join(out, fallback);
|
|
318
|
-
mkdirp(dirname(file));
|
|
319
|
-
writeFileSync(file, rendered.body || '');
|
|
320
|
-
}
|
|
246
|
+
setHeaders(res, pathname, data.stats);
|
|
247
|
+
send(req, res, data.abs, data.stats, data.headers);
|
|
248
|
+
};
|
|
321
249
|
}
|
|
322
250
|
|
|
251
|
+
/** @param {string} dir */
|
|
252
|
+
const mutable = (dir) =>
|
|
253
|
+
sirv(dir, {
|
|
254
|
+
etag: true,
|
|
255
|
+
maxAge: 0
|
|
256
|
+
});
|
|
257
|
+
|
|
323
258
|
/**
|
|
324
259
|
* @param {{
|
|
325
|
-
*
|
|
260
|
+
* port: number;
|
|
261
|
+
* host?: string;
|
|
326
262
|
* config: import('types/config').ValidatedConfig;
|
|
327
|
-
*
|
|
328
|
-
*
|
|
263
|
+
* https?: boolean;
|
|
264
|
+
* cwd?: string;
|
|
329
265
|
* }} opts
|
|
330
|
-
* @returns {import('types/config').AdapterUtils}
|
|
331
266
|
*/
|
|
332
|
-
function
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
copy(`${cwd}/${SVELTE_KIT}/output/client`, dest, (file) => file[0] !== '.');
|
|
341
|
-
},
|
|
267
|
+
async function preview({
|
|
268
|
+
port,
|
|
269
|
+
host,
|
|
270
|
+
config,
|
|
271
|
+
https: use_https = false,
|
|
272
|
+
cwd = process.cwd()
|
|
273
|
+
}) {
|
|
274
|
+
__fetch_polyfill();
|
|
342
275
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
276
|
+
const app_file = resolve(cwd, `${SVELTE_KIT}/output/server/app.js`);
|
|
277
|
+
|
|
278
|
+
/** @type {import('types/app').App} */
|
|
279
|
+
const app = await import(pathToFileURL(app_file).href);
|
|
280
|
+
|
|
281
|
+
/** @type {import('sirv').RequestHandler} */
|
|
282
|
+
const static_handler = fs__default.existsSync(config.kit.files.assets)
|
|
283
|
+
? mutable(config.kit.files.assets)
|
|
284
|
+
: (_req, _res, next) => {
|
|
285
|
+
if (!next) throw new Error('No next() handler is available');
|
|
286
|
+
return next();
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const assets_handler = sirv(resolve(cwd, `${SVELTE_KIT}/output/client`), {
|
|
290
|
+
maxAge: 31536000,
|
|
291
|
+
immutable: true
|
|
292
|
+
});
|
|
346
293
|
|
|
347
|
-
|
|
348
|
-
|
|
294
|
+
const has_asset_path = !!config.kit.paths.assets;
|
|
295
|
+
|
|
296
|
+
app.init({
|
|
297
|
+
paths: {
|
|
298
|
+
base: config.kit.paths.base,
|
|
299
|
+
assets: has_asset_path ? SVELTE_KIT_ASSETS : config.kit.paths.base
|
|
349
300
|
},
|
|
301
|
+
prerendering: false,
|
|
302
|
+
read: (file) => fs__default.readFileSync(join(config.kit.files.assets, file))
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
/** @type {import('vite').UserConfig} */
|
|
306
|
+
const vite_config = (config.kit.vite && config.kit.vite()) || {};
|
|
307
|
+
|
|
308
|
+
const server = await get_server(use_https, vite_config, (req, res) => {
|
|
309
|
+
if (req.url == null) {
|
|
310
|
+
throw new Error('Invalid request url');
|
|
311
|
+
}
|
|
350
312
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
313
|
+
const initial_url = req.url;
|
|
314
|
+
|
|
315
|
+
const render_handler = async () => {
|
|
316
|
+
if (!req.method) throw new Error('Incomplete request');
|
|
317
|
+
|
|
318
|
+
let body;
|
|
319
|
+
|
|
320
|
+
try {
|
|
321
|
+
body = await getRawBody(req);
|
|
322
|
+
} catch (/** @type {any} */ err) {
|
|
323
|
+
res.statusCode = err.status || 400;
|
|
324
|
+
return res.end(err.reason || 'Invalid request body');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const parsed = new URL(initial_url, 'http://localhost/');
|
|
328
|
+
|
|
329
|
+
const rendered =
|
|
330
|
+
parsed.pathname.startsWith(config.kit.paths.base) &&
|
|
331
|
+
(await app.render({
|
|
332
|
+
host: /** @type {string} */ (
|
|
333
|
+
config.kit.host || req.headers[config.kit.hostHeader || 'host']
|
|
334
|
+
),
|
|
335
|
+
method: req.method,
|
|
336
|
+
headers: /** @type {import('types/helper').RequestHeaders} */ (req.headers),
|
|
337
|
+
path: parsed.pathname.replace(config.kit.paths.base, ''),
|
|
338
|
+
query: parsed.searchParams,
|
|
339
|
+
rawBody: body
|
|
340
|
+
}));
|
|
341
|
+
|
|
342
|
+
if (rendered) {
|
|
343
|
+
res.writeHead(rendered.status, rendered.headers);
|
|
344
|
+
if (rendered.body) res.write(rendered.body);
|
|
345
|
+
res.end();
|
|
346
|
+
} else {
|
|
347
|
+
res.statusCode = 404;
|
|
348
|
+
res.end('Not found');
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
if (has_asset_path) {
|
|
353
|
+
if (initial_url.startsWith(SVELTE_KIT_ASSETS)) {
|
|
354
|
+
// custom assets path
|
|
355
|
+
req.url = initial_url.slice(SVELTE_KIT_ASSETS.length);
|
|
356
|
+
assets_handler(req, res, () => {
|
|
357
|
+
static_handler(req, res, render_handler);
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
render_handler();
|
|
361
|
+
}
|
|
362
|
+
} else {
|
|
363
|
+
if (initial_url.startsWith(config.kit.paths.base)) {
|
|
364
|
+
req.url = initial_url.slice(config.kit.paths.base.length);
|
|
365
|
+
}
|
|
366
|
+
assets_handler(req, res, () => {
|
|
367
|
+
static_handler(req, res, render_handler);
|
|
360
368
|
});
|
|
361
369
|
}
|
|
362
|
-
};
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
await server.listen(port, host || '0.0.0.0');
|
|
373
|
+
|
|
374
|
+
return Promise.resolve(server);
|
|
363
375
|
}
|
|
364
376
|
|
|
365
377
|
/**
|
|
366
|
-
* @param {
|
|
367
|
-
* @param {import('
|
|
368
|
-
* @param {
|
|
378
|
+
* @param {boolean} use_https
|
|
379
|
+
* @param {import('vite').UserConfig} user_config
|
|
380
|
+
* @param {(req: http.IncomingMessage, res: http.ServerResponse) => void} handler
|
|
381
|
+
* @returns {Promise<import('net').Server>}
|
|
369
382
|
*/
|
|
370
|
-
async function
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
383
|
+
async function get_server(use_https, user_config, handler) {
|
|
384
|
+
/** @type {https.ServerOptions} */
|
|
385
|
+
const https_options = {};
|
|
386
|
+
|
|
387
|
+
if (use_https) {
|
|
388
|
+
const secure_opts = user_config.server
|
|
389
|
+
? /** @type {import('tls').SecureContextOptions} */ (user_config.server.https)
|
|
390
|
+
: {};
|
|
391
|
+
|
|
392
|
+
if (secure_opts.key && secure_opts.cert) {
|
|
393
|
+
https_options.key = secure_opts.key.toString();
|
|
394
|
+
https_options.cert = secure_opts.cert.toString();
|
|
395
|
+
} else {
|
|
396
|
+
https_options.key = https_options.cert = (await import('./cert.js')).createCertificate();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
378
399
|
|
|
379
|
-
|
|
400
|
+
return Promise.resolve(
|
|
401
|
+
use_https
|
|
402
|
+
? https.createServer(/** @type {https.ServerOptions} */ (https_options), handler)
|
|
403
|
+
: http.createServer(handler)
|
|
404
|
+
);
|
|
380
405
|
}
|
|
381
406
|
|
|
382
|
-
export {
|
|
407
|
+
export { preview };
|