@sveltejs/kit 1.0.0-next.31 → 1.0.0-next.310

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.
Files changed (74) hide show
  1. package/README.md +12 -9
  2. package/assets/app/env.js +20 -0
  3. package/assets/app/navigation.js +24 -0
  4. package/assets/app/paths.js +1 -0
  5. package/assets/app/stores.js +97 -0
  6. package/assets/client/singletons.js +13 -0
  7. package/assets/client/start.js +1655 -0
  8. package/assets/components/error.svelte +18 -2
  9. package/assets/env.js +8 -0
  10. package/assets/paths.js +13 -0
  11. package/assets/server/index.js +2862 -0
  12. package/dist/chunks/amp_hook.js +56 -0
  13. package/dist/chunks/cert.js +28154 -0
  14. package/dist/chunks/constants.js +663 -0
  15. package/dist/chunks/filesystem.js +110 -0
  16. package/dist/chunks/index.js +515 -0
  17. package/dist/chunks/index2.js +1326 -0
  18. package/dist/chunks/index3.js +118 -0
  19. package/dist/chunks/index4.js +185 -0
  20. package/dist/chunks/index5.js +251 -0
  21. package/dist/chunks/index6.js +15585 -0
  22. package/dist/chunks/index7.js +4207 -0
  23. package/dist/chunks/misc.js +78 -0
  24. package/dist/chunks/multipart-parser.js +449 -0
  25. package/dist/chunks/object.js +83 -0
  26. package/dist/chunks/sync.js +983 -0
  27. package/dist/chunks/url.js +56 -0
  28. package/dist/cli.js +1023 -91
  29. package/dist/hooks.js +28 -0
  30. package/dist/install-fetch.js +6518 -0
  31. package/dist/node.js +94 -0
  32. package/package.json +92 -54
  33. package/svelte-kit.js +2 -0
  34. package/types/ambient.d.ts +298 -0
  35. package/types/index.d.ts +258 -0
  36. package/types/internal.d.ts +314 -0
  37. package/types/private.d.ts +269 -0
  38. package/CHANGELOG.md +0 -344
  39. package/assets/runtime/app/navigation.js +0 -23
  40. package/assets/runtime/app/navigation.js.map +0 -1
  41. package/assets/runtime/app/paths.js +0 -2
  42. package/assets/runtime/app/paths.js.map +0 -1
  43. package/assets/runtime/app/stores.js +0 -78
  44. package/assets/runtime/app/stores.js.map +0 -1
  45. package/assets/runtime/internal/singletons.js +0 -15
  46. package/assets/runtime/internal/singletons.js.map +0 -1
  47. package/assets/runtime/internal/start.js +0 -591
  48. package/assets/runtime/internal/start.js.map +0 -1
  49. package/assets/runtime/utils-85ebcc60.js +0 -18
  50. package/assets/runtime/utils-85ebcc60.js.map +0 -1
  51. package/dist/api.js +0 -44
  52. package/dist/api.js.map +0 -1
  53. package/dist/cli.js.map +0 -1
  54. package/dist/create_app.js +0 -580
  55. package/dist/create_app.js.map +0 -1
  56. package/dist/index.js +0 -375
  57. package/dist/index.js.map +0 -1
  58. package/dist/index2.js +0 -12205
  59. package/dist/index2.js.map +0 -1
  60. package/dist/index3.js +0 -549
  61. package/dist/index3.js.map +0 -1
  62. package/dist/index4.js +0 -74
  63. package/dist/index4.js.map +0 -1
  64. package/dist/index5.js +0 -468
  65. package/dist/index5.js.map +0 -1
  66. package/dist/index6.js +0 -735
  67. package/dist/index6.js.map +0 -1
  68. package/dist/renderer.js +0 -2425
  69. package/dist/renderer.js.map +0 -1
  70. package/dist/standard.js +0 -103
  71. package/dist/standard.js.map +0 -1
  72. package/dist/utils.js +0 -58
  73. package/dist/utils.js.map +0 -1
  74. package/svelte-kit +0 -3
package/dist/renderer.js DELETED
@@ -1,2425 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var crypto = require('crypto');
6
- var Stream = require('stream');
7
- var http = require('http');
8
- var Url = require('url');
9
- var https = require('https');
10
- var zlib = require('zlib');
11
-
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
-
14
- var Stream__default = /*#__PURE__*/_interopDefaultLegacy(Stream);
15
- var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
16
- var Url__default = /*#__PURE__*/_interopDefaultLegacy(Url);
17
- var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
18
- var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
19
-
20
- var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
21
- var unsafeChars = /[<>\b\f\n\r\t\0\u2028\u2029]/g;
22
- var reserved = /^(?:do|if|in|for|int|let|new|try|var|byte|case|char|else|enum|goto|long|this|void|with|await|break|catch|class|const|final|float|short|super|throw|while|yield|delete|double|export|import|native|return|switch|throws|typeof|boolean|default|extends|finally|package|private|abstract|continue|debugger|function|volatile|interface|protected|transient|implements|instanceof|synchronized)$/;
23
- var escaped = {
24
- '<': '\\u003C',
25
- '>': '\\u003E',
26
- '/': '\\u002F',
27
- '\\': '\\\\',
28
- '\b': '\\b',
29
- '\f': '\\f',
30
- '\n': '\\n',
31
- '\r': '\\r',
32
- '\t': '\\t',
33
- '\0': '\\0',
34
- '\u2028': '\\u2028',
35
- '\u2029': '\\u2029'
36
- };
37
- var objectProtoOwnPropertyNames = Object.getOwnPropertyNames(Object.prototype).sort().join('\0');
38
- function devalue(value) {
39
- var counts = new Map();
40
- function walk(thing) {
41
- if (typeof thing === 'function') {
42
- throw new Error("Cannot stringify a function");
43
- }
44
- if (counts.has(thing)) {
45
- counts.set(thing, counts.get(thing) + 1);
46
- return;
47
- }
48
- counts.set(thing, 1);
49
- if (!isPrimitive(thing)) {
50
- var type = getType(thing);
51
- switch (type) {
52
- case 'Number':
53
- case 'String':
54
- case 'Boolean':
55
- case 'Date':
56
- case 'RegExp':
57
- return;
58
- case 'Array':
59
- thing.forEach(walk);
60
- break;
61
- case 'Set':
62
- case 'Map':
63
- Array.from(thing).forEach(walk);
64
- break;
65
- default:
66
- var proto = Object.getPrototypeOf(thing);
67
- if (proto !== Object.prototype &&
68
- proto !== null &&
69
- Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames) {
70
- throw new Error("Cannot stringify arbitrary non-POJOs");
71
- }
72
- if (Object.getOwnPropertySymbols(thing).length > 0) {
73
- throw new Error("Cannot stringify POJOs with symbolic keys");
74
- }
75
- Object.keys(thing).forEach(function (key) { return walk(thing[key]); });
76
- }
77
- }
78
- }
79
- walk(value);
80
- var names = new Map();
81
- Array.from(counts)
82
- .filter(function (entry) { return entry[1] > 1; })
83
- .sort(function (a, b) { return b[1] - a[1]; })
84
- .forEach(function (entry, i) {
85
- names.set(entry[0], getName(i));
86
- });
87
- function stringify(thing) {
88
- if (names.has(thing)) {
89
- return names.get(thing);
90
- }
91
- if (isPrimitive(thing)) {
92
- return stringifyPrimitive(thing);
93
- }
94
- var type = getType(thing);
95
- switch (type) {
96
- case 'Number':
97
- case 'String':
98
- case 'Boolean':
99
- return "Object(" + stringify(thing.valueOf()) + ")";
100
- case 'RegExp':
101
- return "new RegExp(" + stringifyString(thing.source) + ", \"" + thing.flags + "\")";
102
- case 'Date':
103
- return "new Date(" + thing.getTime() + ")";
104
- case 'Array':
105
- var members = thing.map(function (v, i) { return i in thing ? stringify(v) : ''; });
106
- var tail = thing.length === 0 || (thing.length - 1 in thing) ? '' : ',';
107
- return "[" + members.join(',') + tail + "]";
108
- case 'Set':
109
- case 'Map':
110
- return "new " + type + "([" + Array.from(thing).map(stringify).join(',') + "])";
111
- default:
112
- var obj = "{" + Object.keys(thing).map(function (key) { return safeKey(key) + ":" + stringify(thing[key]); }).join(',') + "}";
113
- var proto = Object.getPrototypeOf(thing);
114
- if (proto === null) {
115
- return Object.keys(thing).length > 0
116
- ? "Object.assign(Object.create(null)," + obj + ")"
117
- : "Object.create(null)";
118
- }
119
- return obj;
120
- }
121
- }
122
- var str = stringify(value);
123
- if (names.size) {
124
- var params_1 = [];
125
- var statements_1 = [];
126
- var values_1 = [];
127
- names.forEach(function (name, thing) {
128
- params_1.push(name);
129
- if (isPrimitive(thing)) {
130
- values_1.push(stringifyPrimitive(thing));
131
- return;
132
- }
133
- var type = getType(thing);
134
- switch (type) {
135
- case 'Number':
136
- case 'String':
137
- case 'Boolean':
138
- values_1.push("Object(" + stringify(thing.valueOf()) + ")");
139
- break;
140
- case 'RegExp':
141
- values_1.push(thing.toString());
142
- break;
143
- case 'Date':
144
- values_1.push("new Date(" + thing.getTime() + ")");
145
- break;
146
- case 'Array':
147
- values_1.push("Array(" + thing.length + ")");
148
- thing.forEach(function (v, i) {
149
- statements_1.push(name + "[" + i + "]=" + stringify(v));
150
- });
151
- break;
152
- case 'Set':
153
- values_1.push("new Set");
154
- statements_1.push(name + "." + Array.from(thing).map(function (v) { return "add(" + stringify(v) + ")"; }).join('.'));
155
- break;
156
- case 'Map':
157
- values_1.push("new Map");
158
- statements_1.push(name + "." + Array.from(thing).map(function (_a) {
159
- var k = _a[0], v = _a[1];
160
- return "set(" + stringify(k) + ", " + stringify(v) + ")";
161
- }).join('.'));
162
- break;
163
- default:
164
- values_1.push(Object.getPrototypeOf(thing) === null ? 'Object.create(null)' : '{}');
165
- Object.keys(thing).forEach(function (key) {
166
- statements_1.push("" + name + safeProp(key) + "=" + stringify(thing[key]));
167
- });
168
- }
169
- });
170
- statements_1.push("return " + str);
171
- return "(function(" + params_1.join(',') + "){" + statements_1.join(';') + "}(" + values_1.join(',') + "))";
172
- }
173
- else {
174
- return str;
175
- }
176
- }
177
- function getName(num) {
178
- var name = '';
179
- do {
180
- name = chars[num % chars.length] + name;
181
- num = ~~(num / chars.length) - 1;
182
- } while (num >= 0);
183
- return reserved.test(name) ? name + "_" : name;
184
- }
185
- function isPrimitive(thing) {
186
- return Object(thing) !== thing;
187
- }
188
- function stringifyPrimitive(thing) {
189
- if (typeof thing === 'string')
190
- return stringifyString(thing);
191
- if (thing === void 0)
192
- return 'void 0';
193
- if (thing === 0 && 1 / thing < 0)
194
- return '-0';
195
- var str = String(thing);
196
- if (typeof thing === 'number')
197
- return str.replace(/^(-)?0\./, '$1.');
198
- return str;
199
- }
200
- function getType(thing) {
201
- return Object.prototype.toString.call(thing).slice(8, -1);
202
- }
203
- function escapeUnsafeChar(c) {
204
- return escaped[c] || c;
205
- }
206
- function escapeUnsafeChars(str) {
207
- return str.replace(unsafeChars, escapeUnsafeChar);
208
- }
209
- function safeKey(key) {
210
- return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? key : escapeUnsafeChars(JSON.stringify(key));
211
- }
212
- function safeProp(key) {
213
- return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? "." + key : "[" + escapeUnsafeChars(JSON.stringify(key)) + "]";
214
- }
215
- function stringifyString(str) {
216
- var result = '"';
217
- for (var i = 0; i < str.length; i += 1) {
218
- var char = str.charAt(i);
219
- var code = char.charCodeAt(0);
220
- if (char === '"') {
221
- result += '\\"';
222
- }
223
- else if (char in escaped) {
224
- result += escaped[char];
225
- }
226
- else if (code >= 0xd800 && code <= 0xdfff) {
227
- var next = str.charCodeAt(i + 1);
228
- // If this is the beginning of a [high, low] surrogate pair,
229
- // add the next two characters, otherwise escape
230
- if (code <= 0xdbff && (next >= 0xdc00 && next <= 0xdfff)) {
231
- result += char + str[++i];
232
- }
233
- else {
234
- result += "\\u" + code.toString(16).toUpperCase();
235
- }
236
- }
237
- else {
238
- result += char;
239
- }
240
- }
241
- result += '"';
242
- return result;
243
- }
244
-
245
- // Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
246
-
247
- // fix for "Readable" isn't a named export issue
248
- const Readable = Stream__default['default'].Readable;
249
-
250
- const BUFFER = Symbol('buffer');
251
- const TYPE = Symbol('type');
252
-
253
- class Blob {
254
- constructor() {
255
- this[TYPE] = '';
256
-
257
- const blobParts = arguments[0];
258
- const options = arguments[1];
259
-
260
- const buffers = [];
261
- let size = 0;
262
-
263
- if (blobParts) {
264
- const a = blobParts;
265
- const length = Number(a.length);
266
- for (let i = 0; i < length; i++) {
267
- const element = a[i];
268
- let buffer;
269
- if (element instanceof Buffer) {
270
- buffer = element;
271
- } else if (ArrayBuffer.isView(element)) {
272
- buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
273
- } else if (element instanceof ArrayBuffer) {
274
- buffer = Buffer.from(element);
275
- } else if (element instanceof Blob) {
276
- buffer = element[BUFFER];
277
- } else {
278
- buffer = Buffer.from(typeof element === 'string' ? element : String(element));
279
- }
280
- size += buffer.length;
281
- buffers.push(buffer);
282
- }
283
- }
284
-
285
- this[BUFFER] = Buffer.concat(buffers);
286
-
287
- let type = options && options.type !== undefined && String(options.type).toLowerCase();
288
- if (type && !/[^\u0020-\u007E]/.test(type)) {
289
- this[TYPE] = type;
290
- }
291
- }
292
- get size() {
293
- return this[BUFFER].length;
294
- }
295
- get type() {
296
- return this[TYPE];
297
- }
298
- text() {
299
- return Promise.resolve(this[BUFFER].toString());
300
- }
301
- arrayBuffer() {
302
- const buf = this[BUFFER];
303
- const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
304
- return Promise.resolve(ab);
305
- }
306
- stream() {
307
- const readable = new Readable();
308
- readable._read = function () {};
309
- readable.push(this[BUFFER]);
310
- readable.push(null);
311
- return readable;
312
- }
313
- toString() {
314
- return '[object Blob]';
315
- }
316
- slice() {
317
- const size = this.size;
318
-
319
- const start = arguments[0];
320
- const end = arguments[1];
321
- let relativeStart, relativeEnd;
322
- if (start === undefined) {
323
- relativeStart = 0;
324
- } else if (start < 0) {
325
- relativeStart = Math.max(size + start, 0);
326
- } else {
327
- relativeStart = Math.min(start, size);
328
- }
329
- if (end === undefined) {
330
- relativeEnd = size;
331
- } else if (end < 0) {
332
- relativeEnd = Math.max(size + end, 0);
333
- } else {
334
- relativeEnd = Math.min(end, size);
335
- }
336
- const span = Math.max(relativeEnd - relativeStart, 0);
337
-
338
- const buffer = this[BUFFER];
339
- const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
340
- const blob = new Blob([], { type: arguments[2] });
341
- blob[BUFFER] = slicedBuffer;
342
- return blob;
343
- }
344
- }
345
-
346
- Object.defineProperties(Blob.prototype, {
347
- size: { enumerable: true },
348
- type: { enumerable: true },
349
- slice: { enumerable: true }
350
- });
351
-
352
- Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
353
- value: 'Blob',
354
- writable: false,
355
- enumerable: false,
356
- configurable: true
357
- });
358
-
359
- /**
360
- * fetch-error.js
361
- *
362
- * FetchError interface for operational errors
363
- */
364
-
365
- /**
366
- * Create FetchError instance
367
- *
368
- * @param String message Error message for human
369
- * @param String type Error type for machine
370
- * @param String systemError For Node.js system error
371
- * @return FetchError
372
- */
373
- function FetchError(message, type, systemError) {
374
- Error.call(this, message);
375
-
376
- this.message = message;
377
- this.type = type;
378
-
379
- // when err.type is `system`, err.code contains system error code
380
- if (systemError) {
381
- this.code = this.errno = systemError.code;
382
- }
383
-
384
- // hide custom error implementation details from end-users
385
- Error.captureStackTrace(this, this.constructor);
386
- }
387
-
388
- FetchError.prototype = Object.create(Error.prototype);
389
- FetchError.prototype.constructor = FetchError;
390
- FetchError.prototype.name = 'FetchError';
391
-
392
- let convert;
393
- try {
394
- convert = require('encoding').convert;
395
- } catch (e) {}
396
-
397
- const INTERNALS = Symbol('Body internals');
398
-
399
- // fix an issue where "PassThrough" isn't a named export for node <10
400
- const PassThrough = Stream__default['default'].PassThrough;
401
-
402
- /**
403
- * Body mixin
404
- *
405
- * Ref: https://fetch.spec.whatwg.org/#body
406
- *
407
- * @param Stream body Readable stream
408
- * @param Object opts Response options
409
- * @return Void
410
- */
411
- function Body(body) {
412
- var _this = this;
413
-
414
- var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
415
- _ref$size = _ref.size;
416
-
417
- let size = _ref$size === undefined ? 0 : _ref$size;
418
- var _ref$timeout = _ref.timeout;
419
- let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
420
-
421
- if (body == null) {
422
- // body is undefined or null
423
- body = null;
424
- } else if (isURLSearchParams(body)) {
425
- // body is a URLSearchParams
426
- body = Buffer.from(body.toString());
427
- } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
428
- // body is ArrayBuffer
429
- body = Buffer.from(body);
430
- } else if (ArrayBuffer.isView(body)) {
431
- // body is ArrayBufferView
432
- body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
433
- } else if (body instanceof Stream__default['default']) ; else {
434
- // none of the above
435
- // coerce to string then buffer
436
- body = Buffer.from(String(body));
437
- }
438
- this[INTERNALS] = {
439
- body,
440
- disturbed: false,
441
- error: null
442
- };
443
- this.size = size;
444
- this.timeout = timeout;
445
-
446
- if (body instanceof Stream__default['default']) {
447
- body.on('error', function (err) {
448
- const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);
449
- _this[INTERNALS].error = error;
450
- });
451
- }
452
- }
453
-
454
- Body.prototype = {
455
- get body() {
456
- return this[INTERNALS].body;
457
- },
458
-
459
- get bodyUsed() {
460
- return this[INTERNALS].disturbed;
461
- },
462
-
463
- /**
464
- * Decode response as ArrayBuffer
465
- *
466
- * @return Promise
467
- */
468
- arrayBuffer() {
469
- return consumeBody.call(this).then(function (buf) {
470
- return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
471
- });
472
- },
473
-
474
- /**
475
- * Return raw response as Blob
476
- *
477
- * @return Promise
478
- */
479
- blob() {
480
- let ct = this.headers && this.headers.get('content-type') || '';
481
- return consumeBody.call(this).then(function (buf) {
482
- return Object.assign(
483
- // Prevent copying
484
- new Blob([], {
485
- type: ct.toLowerCase()
486
- }), {
487
- [BUFFER]: buf
488
- });
489
- });
490
- },
491
-
492
- /**
493
- * Decode response as json
494
- *
495
- * @return Promise
496
- */
497
- json() {
498
- var _this2 = this;
499
-
500
- return consumeBody.call(this).then(function (buffer) {
501
- try {
502
- return JSON.parse(buffer.toString());
503
- } catch (err) {
504
- return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));
505
- }
506
- });
507
- },
508
-
509
- /**
510
- * Decode response as text
511
- *
512
- * @return Promise
513
- */
514
- text() {
515
- return consumeBody.call(this).then(function (buffer) {
516
- return buffer.toString();
517
- });
518
- },
519
-
520
- /**
521
- * Decode response as buffer (non-spec api)
522
- *
523
- * @return Promise
524
- */
525
- buffer() {
526
- return consumeBody.call(this);
527
- },
528
-
529
- /**
530
- * Decode response as text, while automatically detecting the encoding and
531
- * trying to decode to UTF-8 (non-spec api)
532
- *
533
- * @return Promise
534
- */
535
- textConverted() {
536
- var _this3 = this;
537
-
538
- return consumeBody.call(this).then(function (buffer) {
539
- return convertBody(buffer, _this3.headers);
540
- });
541
- }
542
- };
543
-
544
- // In browsers, all properties are enumerable.
545
- Object.defineProperties(Body.prototype, {
546
- body: { enumerable: true },
547
- bodyUsed: { enumerable: true },
548
- arrayBuffer: { enumerable: true },
549
- blob: { enumerable: true },
550
- json: { enumerable: true },
551
- text: { enumerable: true }
552
- });
553
-
554
- Body.mixIn = function (proto) {
555
- for (const name of Object.getOwnPropertyNames(Body.prototype)) {
556
- // istanbul ignore else: future proof
557
- if (!(name in proto)) {
558
- const desc = Object.getOwnPropertyDescriptor(Body.prototype, name);
559
- Object.defineProperty(proto, name, desc);
560
- }
561
- }
562
- };
563
-
564
- /**
565
- * Consume and convert an entire Body to a Buffer.
566
- *
567
- * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
568
- *
569
- * @return Promise
570
- */
571
- function consumeBody() {
572
- var _this4 = this;
573
-
574
- if (this[INTERNALS].disturbed) {
575
- return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));
576
- }
577
-
578
- this[INTERNALS].disturbed = true;
579
-
580
- if (this[INTERNALS].error) {
581
- return Body.Promise.reject(this[INTERNALS].error);
582
- }
583
-
584
- let body = this.body;
585
-
586
- // body is null
587
- if (body === null) {
588
- return Body.Promise.resolve(Buffer.alloc(0));
589
- }
590
-
591
- // body is blob
592
- if (isBlob(body)) {
593
- body = body.stream();
594
- }
595
-
596
- // body is buffer
597
- if (Buffer.isBuffer(body)) {
598
- return Body.Promise.resolve(body);
599
- }
600
-
601
- // istanbul ignore if: should never happen
602
- if (!(body instanceof Stream__default['default'])) {
603
- return Body.Promise.resolve(Buffer.alloc(0));
604
- }
605
-
606
- // body is stream
607
- // get ready to actually consume the body
608
- let accum = [];
609
- let accumBytes = 0;
610
- let abort = false;
611
-
612
- return new Body.Promise(function (resolve, reject) {
613
- let resTimeout;
614
-
615
- // allow timeout on slow response body
616
- if (_this4.timeout) {
617
- resTimeout = setTimeout(function () {
618
- abort = true;
619
- reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));
620
- }, _this4.timeout);
621
- }
622
-
623
- // handle stream errors
624
- body.on('error', function (err) {
625
- if (err.name === 'AbortError') {
626
- // if the request was aborted, reject with this Error
627
- abort = true;
628
- reject(err);
629
- } else {
630
- // other errors, such as incorrect content-encoding
631
- reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));
632
- }
633
- });
634
-
635
- body.on('data', function (chunk) {
636
- if (abort || chunk === null) {
637
- return;
638
- }
639
-
640
- if (_this4.size && accumBytes + chunk.length > _this4.size) {
641
- abort = true;
642
- reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));
643
- return;
644
- }
645
-
646
- accumBytes += chunk.length;
647
- accum.push(chunk);
648
- });
649
-
650
- body.on('end', function () {
651
- if (abort) {
652
- return;
653
- }
654
-
655
- clearTimeout(resTimeout);
656
-
657
- try {
658
- resolve(Buffer.concat(accum, accumBytes));
659
- } catch (err) {
660
- // handle streams that have accumulated too much data (issue #414)
661
- reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));
662
- }
663
- });
664
- });
665
- }
666
-
667
- /**
668
- * Detect buffer encoding and convert to target encoding
669
- * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
670
- *
671
- * @param Buffer buffer Incoming buffer
672
- * @param String encoding Target encoding
673
- * @return String
674
- */
675
- function convertBody(buffer, headers) {
676
- if (typeof convert !== 'function') {
677
- throw new Error('The package `encoding` must be installed to use the textConverted() function');
678
- }
679
-
680
- const ct = headers.get('content-type');
681
- let charset = 'utf-8';
682
- let res, str;
683
-
684
- // header
685
- if (ct) {
686
- res = /charset=([^;]*)/i.exec(ct);
687
- }
688
-
689
- // no charset in content type, peek at response body for at most 1024 bytes
690
- str = buffer.slice(0, 1024).toString();
691
-
692
- // html5
693
- if (!res && str) {
694
- res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
695
- }
696
-
697
- // html4
698
- if (!res && str) {
699
- res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
700
- if (!res) {
701
- res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str);
702
- if (res) {
703
- res.pop(); // drop last quote
704
- }
705
- }
706
-
707
- if (res) {
708
- res = /charset=(.*)/i.exec(res.pop());
709
- }
710
- }
711
-
712
- // xml
713
- if (!res && str) {
714
- res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
715
- }
716
-
717
- // found charset
718
- if (res) {
719
- charset = res.pop();
720
-
721
- // prevent decode issues when sites use incorrect encoding
722
- // ref: https://hsivonen.fi/encoding-menu/
723
- if (charset === 'gb2312' || charset === 'gbk') {
724
- charset = 'gb18030';
725
- }
726
- }
727
-
728
- // turn raw buffers into a single utf-8 buffer
729
- return convert(buffer, 'UTF-8', charset).toString();
730
- }
731
-
732
- /**
733
- * Detect a URLSearchParams object
734
- * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143
735
- *
736
- * @param Object obj Object to detect by type or brand
737
- * @return String
738
- */
739
- function isURLSearchParams(obj) {
740
- // Duck-typing as a necessary condition.
741
- if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {
742
- return false;
743
- }
744
-
745
- // Brand-checking and more duck-typing as optional condition.
746
- return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';
747
- }
748
-
749
- /**
750
- * Check if `obj` is a W3C `Blob` object (which `File` inherits from)
751
- * @param {*} obj
752
- * @return {boolean}
753
- */
754
- function isBlob(obj) {
755
- return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);
756
- }
757
-
758
- /**
759
- * Clone body given Res/Req instance
760
- *
761
- * @param Mixed instance Response or Request instance
762
- * @return Mixed
763
- */
764
- function clone(instance) {
765
- let p1, p2;
766
- let body = instance.body;
767
-
768
- // don't allow cloning a used body
769
- if (instance.bodyUsed) {
770
- throw new Error('cannot clone body after it is used');
771
- }
772
-
773
- // check that body is a stream and not form-data object
774
- // note: we can't clone the form-data object without having it as a dependency
775
- if (body instanceof Stream__default['default'] && typeof body.getBoundary !== 'function') {
776
- // tee instance body
777
- p1 = new PassThrough();
778
- p2 = new PassThrough();
779
- body.pipe(p1);
780
- body.pipe(p2);
781
- // set instance body to teed body and return the other teed body
782
- instance[INTERNALS].body = p1;
783
- body = p2;
784
- }
785
-
786
- return body;
787
- }
788
-
789
- /**
790
- * Performs the operation "extract a `Content-Type` value from |object|" as
791
- * specified in the specification:
792
- * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
793
- *
794
- * This function assumes that instance.body is present.
795
- *
796
- * @param Mixed instance Any options.body input
797
- */
798
- function extractContentType(body) {
799
- if (body === null) {
800
- // body is null
801
- return null;
802
- } else if (typeof body === 'string') {
803
- // body is string
804
- return 'text/plain;charset=UTF-8';
805
- } else if (isURLSearchParams(body)) {
806
- // body is a URLSearchParams
807
- return 'application/x-www-form-urlencoded;charset=UTF-8';
808
- } else if (isBlob(body)) {
809
- // body is blob
810
- return body.type || null;
811
- } else if (Buffer.isBuffer(body)) {
812
- // body is buffer
813
- return null;
814
- } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
815
- // body is ArrayBuffer
816
- return null;
817
- } else if (ArrayBuffer.isView(body)) {
818
- // body is ArrayBufferView
819
- return null;
820
- } else if (typeof body.getBoundary === 'function') {
821
- // detect form data input from form-data module
822
- return `multipart/form-data;boundary=${body.getBoundary()}`;
823
- } else if (body instanceof Stream__default['default']) {
824
- // body is stream
825
- // can't really do much about this
826
- return null;
827
- } else {
828
- // Body constructor defaults other things to string
829
- return 'text/plain;charset=UTF-8';
830
- }
831
- }
832
-
833
- /**
834
- * The Fetch Standard treats this as if "total bytes" is a property on the body.
835
- * For us, we have to explicitly get it with a function.
836
- *
837
- * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
838
- *
839
- * @param Body instance Instance of Body
840
- * @return Number? Number of bytes, or null if not possible
841
- */
842
- function getTotalBytes(instance) {
843
- const body = instance.body;
844
-
845
-
846
- if (body === null) {
847
- // body is null
848
- return 0;
849
- } else if (isBlob(body)) {
850
- return body.size;
851
- } else if (Buffer.isBuffer(body)) {
852
- // body is buffer
853
- return body.length;
854
- } else if (body && typeof body.getLengthSync === 'function') {
855
- // detect form data input from form-data module
856
- if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x
857
- body.hasKnownLength && body.hasKnownLength()) {
858
- // 2.x
859
- return body.getLengthSync();
860
- }
861
- return null;
862
- } else {
863
- // body is stream
864
- return null;
865
- }
866
- }
867
-
868
- /**
869
- * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
870
- *
871
- * @param Body instance Instance of Body
872
- * @return Void
873
- */
874
- function writeToStream(dest, instance) {
875
- const body = instance.body;
876
-
877
-
878
- if (body === null) {
879
- // body is null
880
- dest.end();
881
- } else if (isBlob(body)) {
882
- body.stream().pipe(dest);
883
- } else if (Buffer.isBuffer(body)) {
884
- // body is buffer
885
- dest.write(body);
886
- dest.end();
887
- } else {
888
- // body is stream
889
- body.pipe(dest);
890
- }
891
- }
892
-
893
- // expose Promise
894
- Body.Promise = global.Promise;
895
-
896
- /**
897
- * headers.js
898
- *
899
- * Headers class offers convenient helpers
900
- */
901
-
902
- const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
903
- const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
904
-
905
- function validateName(name) {
906
- name = `${name}`;
907
- if (invalidTokenRegex.test(name) || name === '') {
908
- throw new TypeError(`${name} is not a legal HTTP header name`);
909
- }
910
- }
911
-
912
- function validateValue(value) {
913
- value = `${value}`;
914
- if (invalidHeaderCharRegex.test(value)) {
915
- throw new TypeError(`${value} is not a legal HTTP header value`);
916
- }
917
- }
918
-
919
- /**
920
- * Find the key in the map object given a header name.
921
- *
922
- * Returns undefined if not found.
923
- *
924
- * @param String name Header name
925
- * @return String|Undefined
926
- */
927
- function find(map, name) {
928
- name = name.toLowerCase();
929
- for (const key in map) {
930
- if (key.toLowerCase() === name) {
931
- return key;
932
- }
933
- }
934
- return undefined;
935
- }
936
-
937
- const MAP = Symbol('map');
938
- class Headers {
939
- /**
940
- * Headers class
941
- *
942
- * @param Object headers Response headers
943
- * @return Void
944
- */
945
- constructor() {
946
- let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
947
-
948
- this[MAP] = Object.create(null);
949
-
950
- if (init instanceof Headers) {
951
- const rawHeaders = init.raw();
952
- const headerNames = Object.keys(rawHeaders);
953
-
954
- for (const headerName of headerNames) {
955
- for (const value of rawHeaders[headerName]) {
956
- this.append(headerName, value);
957
- }
958
- }
959
-
960
- return;
961
- }
962
-
963
- // We don't worry about converting prop to ByteString here as append()
964
- // will handle it.
965
- if (init == null) ; else if (typeof init === 'object') {
966
- const method = init[Symbol.iterator];
967
- if (method != null) {
968
- if (typeof method !== 'function') {
969
- throw new TypeError('Header pairs must be iterable');
970
- }
971
-
972
- // sequence<sequence<ByteString>>
973
- // Note: per spec we have to first exhaust the lists then process them
974
- const pairs = [];
975
- for (const pair of init) {
976
- if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
977
- throw new TypeError('Each header pair must be iterable');
978
- }
979
- pairs.push(Array.from(pair));
980
- }
981
-
982
- for (const pair of pairs) {
983
- if (pair.length !== 2) {
984
- throw new TypeError('Each header pair must be a name/value tuple');
985
- }
986
- this.append(pair[0], pair[1]);
987
- }
988
- } else {
989
- // record<ByteString, ByteString>
990
- for (const key of Object.keys(init)) {
991
- const value = init[key];
992
- this.append(key, value);
993
- }
994
- }
995
- } else {
996
- throw new TypeError('Provided initializer must be an object');
997
- }
998
- }
999
-
1000
- /**
1001
- * Return combined header value given name
1002
- *
1003
- * @param String name Header name
1004
- * @return Mixed
1005
- */
1006
- get(name) {
1007
- name = `${name}`;
1008
- validateName(name);
1009
- const key = find(this[MAP], name);
1010
- if (key === undefined) {
1011
- return null;
1012
- }
1013
-
1014
- return this[MAP][key].join(', ');
1015
- }
1016
-
1017
- /**
1018
- * Iterate over all headers
1019
- *
1020
- * @param Function callback Executed for each item with parameters (value, name, thisArg)
1021
- * @param Boolean thisArg `this` context for callback function
1022
- * @return Void
1023
- */
1024
- forEach(callback) {
1025
- let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
1026
-
1027
- let pairs = getHeaders(this);
1028
- let i = 0;
1029
- while (i < pairs.length) {
1030
- var _pairs$i = pairs[i];
1031
- const name = _pairs$i[0],
1032
- value = _pairs$i[1];
1033
-
1034
- callback.call(thisArg, value, name, this);
1035
- pairs = getHeaders(this);
1036
- i++;
1037
- }
1038
- }
1039
-
1040
- /**
1041
- * Overwrite header values given name
1042
- *
1043
- * @param String name Header name
1044
- * @param String value Header value
1045
- * @return Void
1046
- */
1047
- set(name, value) {
1048
- name = `${name}`;
1049
- value = `${value}`;
1050
- validateName(name);
1051
- validateValue(value);
1052
- const key = find(this[MAP], name);
1053
- this[MAP][key !== undefined ? key : name] = [value];
1054
- }
1055
-
1056
- /**
1057
- * Append a value onto existing header
1058
- *
1059
- * @param String name Header name
1060
- * @param String value Header value
1061
- * @return Void
1062
- */
1063
- append(name, value) {
1064
- name = `${name}`;
1065
- value = `${value}`;
1066
- validateName(name);
1067
- validateValue(value);
1068
- const key = find(this[MAP], name);
1069
- if (key !== undefined) {
1070
- this[MAP][key].push(value);
1071
- } else {
1072
- this[MAP][name] = [value];
1073
- }
1074
- }
1075
-
1076
- /**
1077
- * Check for header name existence
1078
- *
1079
- * @param String name Header name
1080
- * @return Boolean
1081
- */
1082
- has(name) {
1083
- name = `${name}`;
1084
- validateName(name);
1085
- return find(this[MAP], name) !== undefined;
1086
- }
1087
-
1088
- /**
1089
- * Delete all header values given name
1090
- *
1091
- * @param String name Header name
1092
- * @return Void
1093
- */
1094
- delete(name) {
1095
- name = `${name}`;
1096
- validateName(name);
1097
- const key = find(this[MAP], name);
1098
- if (key !== undefined) {
1099
- delete this[MAP][key];
1100
- }
1101
- }
1102
-
1103
- /**
1104
- * Return raw headers (non-spec api)
1105
- *
1106
- * @return Object
1107
- */
1108
- raw() {
1109
- return this[MAP];
1110
- }
1111
-
1112
- /**
1113
- * Get an iterator on keys.
1114
- *
1115
- * @return Iterator
1116
- */
1117
- keys() {
1118
- return createHeadersIterator(this, 'key');
1119
- }
1120
-
1121
- /**
1122
- * Get an iterator on values.
1123
- *
1124
- * @return Iterator
1125
- */
1126
- values() {
1127
- return createHeadersIterator(this, 'value');
1128
- }
1129
-
1130
- /**
1131
- * Get an iterator on entries.
1132
- *
1133
- * This is the default iterator of the Headers object.
1134
- *
1135
- * @return Iterator
1136
- */
1137
- [Symbol.iterator]() {
1138
- return createHeadersIterator(this, 'key+value');
1139
- }
1140
- }
1141
- Headers.prototype.entries = Headers.prototype[Symbol.iterator];
1142
-
1143
- Object.defineProperty(Headers.prototype, Symbol.toStringTag, {
1144
- value: 'Headers',
1145
- writable: false,
1146
- enumerable: false,
1147
- configurable: true
1148
- });
1149
-
1150
- Object.defineProperties(Headers.prototype, {
1151
- get: { enumerable: true },
1152
- forEach: { enumerable: true },
1153
- set: { enumerable: true },
1154
- append: { enumerable: true },
1155
- has: { enumerable: true },
1156
- delete: { enumerable: true },
1157
- keys: { enumerable: true },
1158
- values: { enumerable: true },
1159
- entries: { enumerable: true }
1160
- });
1161
-
1162
- function getHeaders(headers) {
1163
- let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';
1164
-
1165
- const keys = Object.keys(headers[MAP]).sort();
1166
- return keys.map(kind === 'key' ? function (k) {
1167
- return k.toLowerCase();
1168
- } : kind === 'value' ? function (k) {
1169
- return headers[MAP][k].join(', ');
1170
- } : function (k) {
1171
- return [k.toLowerCase(), headers[MAP][k].join(', ')];
1172
- });
1173
- }
1174
-
1175
- const INTERNAL = Symbol('internal');
1176
-
1177
- function createHeadersIterator(target, kind) {
1178
- const iterator = Object.create(HeadersIteratorPrototype);
1179
- iterator[INTERNAL] = {
1180
- target,
1181
- kind,
1182
- index: 0
1183
- };
1184
- return iterator;
1185
- }
1186
-
1187
- const HeadersIteratorPrototype = Object.setPrototypeOf({
1188
- next() {
1189
- // istanbul ignore if
1190
- if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
1191
- throw new TypeError('Value of `this` is not a HeadersIterator');
1192
- }
1193
-
1194
- var _INTERNAL = this[INTERNAL];
1195
- const target = _INTERNAL.target,
1196
- kind = _INTERNAL.kind,
1197
- index = _INTERNAL.index;
1198
-
1199
- const values = getHeaders(target, kind);
1200
- const len = values.length;
1201
- if (index >= len) {
1202
- return {
1203
- value: undefined,
1204
- done: true
1205
- };
1206
- }
1207
-
1208
- this[INTERNAL].index = index + 1;
1209
-
1210
- return {
1211
- value: values[index],
1212
- done: false
1213
- };
1214
- }
1215
- }, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
1216
-
1217
- Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {
1218
- value: 'HeadersIterator',
1219
- writable: false,
1220
- enumerable: false,
1221
- configurable: true
1222
- });
1223
-
1224
- /**
1225
- * Export the Headers object in a form that Node.js can consume.
1226
- *
1227
- * @param Headers headers
1228
- * @return Object
1229
- */
1230
- function exportNodeCompatibleHeaders(headers) {
1231
- const obj = Object.assign({ __proto__: null }, headers[MAP]);
1232
-
1233
- // http.request() only supports string as Host header. This hack makes
1234
- // specifying custom Host header possible.
1235
- const hostHeaderKey = find(headers[MAP], 'Host');
1236
- if (hostHeaderKey !== undefined) {
1237
- obj[hostHeaderKey] = obj[hostHeaderKey][0];
1238
- }
1239
-
1240
- return obj;
1241
- }
1242
-
1243
- /**
1244
- * Create a Headers object from an object of headers, ignoring those that do
1245
- * not conform to HTTP grammar productions.
1246
- *
1247
- * @param Object obj Object of headers
1248
- * @return Headers
1249
- */
1250
- function createHeadersLenient(obj) {
1251
- const headers = new Headers();
1252
- for (const name of Object.keys(obj)) {
1253
- if (invalidTokenRegex.test(name)) {
1254
- continue;
1255
- }
1256
- if (Array.isArray(obj[name])) {
1257
- for (const val of obj[name]) {
1258
- if (invalidHeaderCharRegex.test(val)) {
1259
- continue;
1260
- }
1261
- if (headers[MAP][name] === undefined) {
1262
- headers[MAP][name] = [val];
1263
- } else {
1264
- headers[MAP][name].push(val);
1265
- }
1266
- }
1267
- } else if (!invalidHeaderCharRegex.test(obj[name])) {
1268
- headers[MAP][name] = [obj[name]];
1269
- }
1270
- }
1271
- return headers;
1272
- }
1273
-
1274
- const INTERNALS$1 = Symbol('Response internals');
1275
-
1276
- // fix an issue where "STATUS_CODES" aren't a named export for node <10
1277
- const STATUS_CODES = http__default['default'].STATUS_CODES;
1278
-
1279
- /**
1280
- * Response class
1281
- *
1282
- * @param Stream body Readable stream
1283
- * @param Object opts Response options
1284
- * @return Void
1285
- */
1286
- class Response {
1287
- constructor() {
1288
- let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1289
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1290
-
1291
- Body.call(this, body, opts);
1292
-
1293
- const status = opts.status || 200;
1294
- const headers = new Headers(opts.headers);
1295
-
1296
- if (body != null && !headers.has('Content-Type')) {
1297
- const contentType = extractContentType(body);
1298
- if (contentType) {
1299
- headers.append('Content-Type', contentType);
1300
- }
1301
- }
1302
-
1303
- this[INTERNALS$1] = {
1304
- url: opts.url,
1305
- status,
1306
- statusText: opts.statusText || STATUS_CODES[status],
1307
- headers,
1308
- counter: opts.counter
1309
- };
1310
- }
1311
-
1312
- get url() {
1313
- return this[INTERNALS$1].url || '';
1314
- }
1315
-
1316
- get status() {
1317
- return this[INTERNALS$1].status;
1318
- }
1319
-
1320
- /**
1321
- * Convenience property representing if the request ended normally
1322
- */
1323
- get ok() {
1324
- return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;
1325
- }
1326
-
1327
- get redirected() {
1328
- return this[INTERNALS$1].counter > 0;
1329
- }
1330
-
1331
- get statusText() {
1332
- return this[INTERNALS$1].statusText;
1333
- }
1334
-
1335
- get headers() {
1336
- return this[INTERNALS$1].headers;
1337
- }
1338
-
1339
- /**
1340
- * Clone this response
1341
- *
1342
- * @return Response
1343
- */
1344
- clone() {
1345
- return new Response(clone(this), {
1346
- url: this.url,
1347
- status: this.status,
1348
- statusText: this.statusText,
1349
- headers: this.headers,
1350
- ok: this.ok,
1351
- redirected: this.redirected
1352
- });
1353
- }
1354
- }
1355
-
1356
- Body.mixIn(Response.prototype);
1357
-
1358
- Object.defineProperties(Response.prototype, {
1359
- url: { enumerable: true },
1360
- status: { enumerable: true },
1361
- ok: { enumerable: true },
1362
- redirected: { enumerable: true },
1363
- statusText: { enumerable: true },
1364
- headers: { enumerable: true },
1365
- clone: { enumerable: true }
1366
- });
1367
-
1368
- Object.defineProperty(Response.prototype, Symbol.toStringTag, {
1369
- value: 'Response',
1370
- writable: false,
1371
- enumerable: false,
1372
- configurable: true
1373
- });
1374
-
1375
- const INTERNALS$2 = Symbol('Request internals');
1376
-
1377
- // fix an issue where "format", "parse" aren't a named export for node <10
1378
- const parse_url = Url__default['default'].parse;
1379
- const format_url = Url__default['default'].format;
1380
-
1381
- const streamDestructionSupported = 'destroy' in Stream__default['default'].Readable.prototype;
1382
-
1383
- /**
1384
- * Check if a value is an instance of Request.
1385
- *
1386
- * @param Mixed input
1387
- * @return Boolean
1388
- */
1389
- function isRequest(input) {
1390
- return typeof input === 'object' && typeof input[INTERNALS$2] === 'object';
1391
- }
1392
-
1393
- function isAbortSignal(signal) {
1394
- const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);
1395
- return !!(proto && proto.constructor.name === 'AbortSignal');
1396
- }
1397
-
1398
- /**
1399
- * Request class
1400
- *
1401
- * @param Mixed input Url or Request instance
1402
- * @param Object init Custom options
1403
- * @return Void
1404
- */
1405
- class Request {
1406
- constructor(input) {
1407
- let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1408
-
1409
- let parsedURL;
1410
-
1411
- // normalize input
1412
- if (!isRequest(input)) {
1413
- if (input && input.href) {
1414
- // in order to support Node.js' Url objects; though WHATWG's URL objects
1415
- // will fall into this branch also (since their `toString()` will return
1416
- // `href` property anyway)
1417
- parsedURL = parse_url(input.href);
1418
- } else {
1419
- // coerce input to a string before attempting to parse
1420
- parsedURL = parse_url(`${input}`);
1421
- }
1422
- input = {};
1423
- } else {
1424
- parsedURL = parse_url(input.url);
1425
- }
1426
-
1427
- let method = init.method || input.method || 'GET';
1428
- method = method.toUpperCase();
1429
-
1430
- if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {
1431
- throw new TypeError('Request with GET/HEAD method cannot have body');
1432
- }
1433
-
1434
- let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;
1435
-
1436
- Body.call(this, inputBody, {
1437
- timeout: init.timeout || input.timeout || 0,
1438
- size: init.size || input.size || 0
1439
- });
1440
-
1441
- const headers = new Headers(init.headers || input.headers || {});
1442
-
1443
- if (inputBody != null && !headers.has('Content-Type')) {
1444
- const contentType = extractContentType(inputBody);
1445
- if (contentType) {
1446
- headers.append('Content-Type', contentType);
1447
- }
1448
- }
1449
-
1450
- let signal = isRequest(input) ? input.signal : null;
1451
- if ('signal' in init) signal = init.signal;
1452
-
1453
- if (signal != null && !isAbortSignal(signal)) {
1454
- throw new TypeError('Expected signal to be an instanceof AbortSignal');
1455
- }
1456
-
1457
- this[INTERNALS$2] = {
1458
- method,
1459
- redirect: init.redirect || input.redirect || 'follow',
1460
- headers,
1461
- parsedURL,
1462
- signal
1463
- };
1464
-
1465
- // node-fetch-only options
1466
- this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
1467
- this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
1468
- this.counter = init.counter || input.counter || 0;
1469
- this.agent = init.agent || input.agent;
1470
- }
1471
-
1472
- get method() {
1473
- return this[INTERNALS$2].method;
1474
- }
1475
-
1476
- get url() {
1477
- return format_url(this[INTERNALS$2].parsedURL);
1478
- }
1479
-
1480
- get headers() {
1481
- return this[INTERNALS$2].headers;
1482
- }
1483
-
1484
- get redirect() {
1485
- return this[INTERNALS$2].redirect;
1486
- }
1487
-
1488
- get signal() {
1489
- return this[INTERNALS$2].signal;
1490
- }
1491
-
1492
- /**
1493
- * Clone this request
1494
- *
1495
- * @return Request
1496
- */
1497
- clone() {
1498
- return new Request(this);
1499
- }
1500
- }
1501
-
1502
- Body.mixIn(Request.prototype);
1503
-
1504
- Object.defineProperty(Request.prototype, Symbol.toStringTag, {
1505
- value: 'Request',
1506
- writable: false,
1507
- enumerable: false,
1508
- configurable: true
1509
- });
1510
-
1511
- Object.defineProperties(Request.prototype, {
1512
- method: { enumerable: true },
1513
- url: { enumerable: true },
1514
- headers: { enumerable: true },
1515
- redirect: { enumerable: true },
1516
- clone: { enumerable: true },
1517
- signal: { enumerable: true }
1518
- });
1519
-
1520
- /**
1521
- * Convert a Request to Node.js http request options.
1522
- *
1523
- * @param Request A Request instance
1524
- * @return Object The options object to be passed to http.request
1525
- */
1526
- function getNodeRequestOptions(request) {
1527
- const parsedURL = request[INTERNALS$2].parsedURL;
1528
- const headers = new Headers(request[INTERNALS$2].headers);
1529
-
1530
- // fetch step 1.3
1531
- if (!headers.has('Accept')) {
1532
- headers.set('Accept', '*/*');
1533
- }
1534
-
1535
- // Basic fetch
1536
- if (!parsedURL.protocol || !parsedURL.hostname) {
1537
- throw new TypeError('Only absolute URLs are supported');
1538
- }
1539
-
1540
- if (!/^https?:$/.test(parsedURL.protocol)) {
1541
- throw new TypeError('Only HTTP(S) protocols are supported');
1542
- }
1543
-
1544
- if (request.signal && request.body instanceof Stream__default['default'].Readable && !streamDestructionSupported) {
1545
- throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');
1546
- }
1547
-
1548
- // HTTP-network-or-cache fetch steps 2.4-2.7
1549
- let contentLengthValue = null;
1550
- if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
1551
- contentLengthValue = '0';
1552
- }
1553
- if (request.body != null) {
1554
- const totalBytes = getTotalBytes(request);
1555
- if (typeof totalBytes === 'number') {
1556
- contentLengthValue = String(totalBytes);
1557
- }
1558
- }
1559
- if (contentLengthValue) {
1560
- headers.set('Content-Length', contentLengthValue);
1561
- }
1562
-
1563
- // HTTP-network-or-cache fetch step 2.11
1564
- if (!headers.has('User-Agent')) {
1565
- headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');
1566
- }
1567
-
1568
- // HTTP-network-or-cache fetch step 2.15
1569
- if (request.compress && !headers.has('Accept-Encoding')) {
1570
- headers.set('Accept-Encoding', 'gzip,deflate');
1571
- }
1572
-
1573
- let agent = request.agent;
1574
- if (typeof agent === 'function') {
1575
- agent = agent(parsedURL);
1576
- }
1577
-
1578
- if (!headers.has('Connection') && !agent) {
1579
- headers.set('Connection', 'close');
1580
- }
1581
-
1582
- // HTTP-network fetch step 4.2
1583
- // chunked encoding is handled by Node.js
1584
-
1585
- return Object.assign({}, parsedURL, {
1586
- method: request.method,
1587
- headers: exportNodeCompatibleHeaders(headers),
1588
- agent
1589
- });
1590
- }
1591
-
1592
- /**
1593
- * abort-error.js
1594
- *
1595
- * AbortError interface for cancelled requests
1596
- */
1597
-
1598
- /**
1599
- * Create AbortError instance
1600
- *
1601
- * @param String message Error message for human
1602
- * @return AbortError
1603
- */
1604
- function AbortError(message) {
1605
- Error.call(this, message);
1606
-
1607
- this.type = 'aborted';
1608
- this.message = message;
1609
-
1610
- // hide custom error implementation details from end-users
1611
- Error.captureStackTrace(this, this.constructor);
1612
- }
1613
-
1614
- AbortError.prototype = Object.create(Error.prototype);
1615
- AbortError.prototype.constructor = AbortError;
1616
- AbortError.prototype.name = 'AbortError';
1617
-
1618
- // fix an issue where "PassThrough", "resolve" aren't a named export for node <10
1619
- const PassThrough$1 = Stream__default['default'].PassThrough;
1620
- const resolve_url = Url__default['default'].resolve;
1621
-
1622
- /**
1623
- * Fetch function
1624
- *
1625
- * @param Mixed url Absolute url or Request instance
1626
- * @param Object opts Fetch options
1627
- * @return Promise
1628
- */
1629
- function fetch(url, opts) {
1630
-
1631
- // allow custom promise
1632
- if (!fetch.Promise) {
1633
- throw new Error('native promise missing, set fetch.Promise to your favorite alternative');
1634
- }
1635
-
1636
- Body.Promise = fetch.Promise;
1637
-
1638
- // wrap http.request into fetch
1639
- return new fetch.Promise(function (resolve, reject) {
1640
- // build request object
1641
- const request = new Request(url, opts);
1642
- const options = getNodeRequestOptions(request);
1643
-
1644
- const send = (options.protocol === 'https:' ? https__default['default'] : http__default['default']).request;
1645
- const signal = request.signal;
1646
-
1647
- let response = null;
1648
-
1649
- const abort = function abort() {
1650
- let error = new AbortError('The user aborted a request.');
1651
- reject(error);
1652
- if (request.body && request.body instanceof Stream__default['default'].Readable) {
1653
- request.body.destroy(error);
1654
- }
1655
- if (!response || !response.body) return;
1656
- response.body.emit('error', error);
1657
- };
1658
-
1659
- if (signal && signal.aborted) {
1660
- abort();
1661
- return;
1662
- }
1663
-
1664
- const abortAndFinalize = function abortAndFinalize() {
1665
- abort();
1666
- finalize();
1667
- };
1668
-
1669
- // send request
1670
- const req = send(options);
1671
- let reqTimeout;
1672
-
1673
- if (signal) {
1674
- signal.addEventListener('abort', abortAndFinalize);
1675
- }
1676
-
1677
- function finalize() {
1678
- req.abort();
1679
- if (signal) signal.removeEventListener('abort', abortAndFinalize);
1680
- clearTimeout(reqTimeout);
1681
- }
1682
-
1683
- if (request.timeout) {
1684
- req.once('socket', function (socket) {
1685
- reqTimeout = setTimeout(function () {
1686
- reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
1687
- finalize();
1688
- }, request.timeout);
1689
- });
1690
- }
1691
-
1692
- req.on('error', function (err) {
1693
- reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
1694
- finalize();
1695
- });
1696
-
1697
- req.on('response', function (res) {
1698
- clearTimeout(reqTimeout);
1699
-
1700
- const headers = createHeadersLenient(res.headers);
1701
-
1702
- // HTTP fetch step 5
1703
- if (fetch.isRedirect(res.statusCode)) {
1704
- // HTTP fetch step 5.2
1705
- const location = headers.get('Location');
1706
-
1707
- // HTTP fetch step 5.3
1708
- const locationURL = location === null ? null : resolve_url(request.url, location);
1709
-
1710
- // HTTP fetch step 5.5
1711
- switch (request.redirect) {
1712
- case 'error':
1713
- reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
1714
- finalize();
1715
- return;
1716
- case 'manual':
1717
- // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
1718
- if (locationURL !== null) {
1719
- // handle corrupted header
1720
- try {
1721
- headers.set('Location', locationURL);
1722
- } catch (err) {
1723
- // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request
1724
- reject(err);
1725
- }
1726
- }
1727
- break;
1728
- case 'follow':
1729
- // HTTP-redirect fetch step 2
1730
- if (locationURL === null) {
1731
- break;
1732
- }
1733
-
1734
- // HTTP-redirect fetch step 5
1735
- if (request.counter >= request.follow) {
1736
- reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
1737
- finalize();
1738
- return;
1739
- }
1740
-
1741
- // HTTP-redirect fetch step 6 (counter increment)
1742
- // Create a new Request object.
1743
- const requestOpts = {
1744
- headers: new Headers(request.headers),
1745
- follow: request.follow,
1746
- counter: request.counter + 1,
1747
- agent: request.agent,
1748
- compress: request.compress,
1749
- method: request.method,
1750
- body: request.body,
1751
- signal: request.signal,
1752
- timeout: request.timeout,
1753
- size: request.size
1754
- };
1755
-
1756
- // HTTP-redirect fetch step 9
1757
- if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
1758
- reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
1759
- finalize();
1760
- return;
1761
- }
1762
-
1763
- // HTTP-redirect fetch step 11
1764
- if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
1765
- requestOpts.method = 'GET';
1766
- requestOpts.body = undefined;
1767
- requestOpts.headers.delete('content-length');
1768
- }
1769
-
1770
- // HTTP-redirect fetch step 15
1771
- resolve(fetch(new Request(locationURL, requestOpts)));
1772
- finalize();
1773
- return;
1774
- }
1775
- }
1776
-
1777
- // prepare response
1778
- res.once('end', function () {
1779
- if (signal) signal.removeEventListener('abort', abortAndFinalize);
1780
- });
1781
- let body = res.pipe(new PassThrough$1());
1782
-
1783
- const response_options = {
1784
- url: request.url,
1785
- status: res.statusCode,
1786
- statusText: res.statusMessage,
1787
- headers: headers,
1788
- size: request.size,
1789
- timeout: request.timeout,
1790
- counter: request.counter
1791
- };
1792
-
1793
- // HTTP-network fetch step 12.1.1.3
1794
- const codings = headers.get('Content-Encoding');
1795
-
1796
- // HTTP-network fetch step 12.1.1.4: handle content codings
1797
-
1798
- // in following scenarios we ignore compression support
1799
- // 1. compression support is disabled
1800
- // 2. HEAD request
1801
- // 3. no Content-Encoding header
1802
- // 4. no content response (204)
1803
- // 5. content not modified response (304)
1804
- if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {
1805
- response = new Response(body, response_options);
1806
- resolve(response);
1807
- return;
1808
- }
1809
-
1810
- // For Node v6+
1811
- // Be less strict when decoding compressed responses, since sometimes
1812
- // servers send slightly invalid responses that are still accepted
1813
- // by common browsers.
1814
- // Always using Z_SYNC_FLUSH is what cURL does.
1815
- const zlibOptions = {
1816
- flush: zlib__default['default'].Z_SYNC_FLUSH,
1817
- finishFlush: zlib__default['default'].Z_SYNC_FLUSH
1818
- };
1819
-
1820
- // for gzip
1821
- if (codings == 'gzip' || codings == 'x-gzip') {
1822
- body = body.pipe(zlib__default['default'].createGunzip(zlibOptions));
1823
- response = new Response(body, response_options);
1824
- resolve(response);
1825
- return;
1826
- }
1827
-
1828
- // for deflate
1829
- if (codings == 'deflate' || codings == 'x-deflate') {
1830
- // handle the infamous raw deflate response from old servers
1831
- // a hack for old IIS and Apache servers
1832
- const raw = res.pipe(new PassThrough$1());
1833
- raw.once('data', function (chunk) {
1834
- // see http://stackoverflow.com/questions/37519828
1835
- if ((chunk[0] & 0x0F) === 0x08) {
1836
- body = body.pipe(zlib__default['default'].createInflate());
1837
- } else {
1838
- body = body.pipe(zlib__default['default'].createInflateRaw());
1839
- }
1840
- response = new Response(body, response_options);
1841
- resolve(response);
1842
- });
1843
- return;
1844
- }
1845
-
1846
- // for br
1847
- if (codings == 'br' && typeof zlib__default['default'].createBrotliDecompress === 'function') {
1848
- body = body.pipe(zlib__default['default'].createBrotliDecompress());
1849
- response = new Response(body, response_options);
1850
- resolve(response);
1851
- return;
1852
- }
1853
-
1854
- // otherwise, use response as-is
1855
- response = new Response(body, response_options);
1856
- resolve(response);
1857
- });
1858
-
1859
- writeToStream(req, request);
1860
- });
1861
- }
1862
- /**
1863
- * Redirect code matching
1864
- *
1865
- * @param Number code Status code
1866
- * @return Boolean
1867
- */
1868
- fetch.isRedirect = function (code) {
1869
- return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
1870
- };
1871
-
1872
- // expose Promise
1873
- fetch.Promise = global.Promise;
1874
-
1875
- function noop() { }
1876
- function safe_not_equal(a, b) {
1877
- return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
1878
- }
1879
-
1880
- const subscriber_queue = [];
1881
- /**
1882
- * Create a `Writable` store that allows both updating and reading by subscription.
1883
- * @param {*=}value initial value
1884
- * @param {StartStopNotifier=}start start and stop notifications for subscriptions
1885
- */
1886
- function writable(value, start = noop) {
1887
- let stop;
1888
- const subscribers = [];
1889
- function set(new_value) {
1890
- if (safe_not_equal(value, new_value)) {
1891
- value = new_value;
1892
- if (stop) { // store is ready
1893
- const run_queue = !subscriber_queue.length;
1894
- for (let i = 0; i < subscribers.length; i += 1) {
1895
- const s = subscribers[i];
1896
- s[1]();
1897
- subscriber_queue.push(s, value);
1898
- }
1899
- if (run_queue) {
1900
- for (let i = 0; i < subscriber_queue.length; i += 2) {
1901
- subscriber_queue[i][0](subscriber_queue[i + 1]);
1902
- }
1903
- subscriber_queue.length = 0;
1904
- }
1905
- }
1906
- }
1907
- }
1908
- function update(fn) {
1909
- set(fn(value));
1910
- }
1911
- function subscribe(run, invalidate = noop) {
1912
- const subscriber = [run, invalidate];
1913
- subscribers.push(subscriber);
1914
- if (subscribers.length === 1) {
1915
- stop = start(set) || noop;
1916
- }
1917
- run(value);
1918
- return () => {
1919
- const index = subscribers.indexOf(subscriber);
1920
- if (index !== -1) {
1921
- subscribers.splice(index, 1);
1922
- }
1923
- if (subscribers.length === 0) {
1924
- stop();
1925
- stop = null;
1926
- }
1927
- };
1928
- }
1929
- return { set, update, subscribe };
1930
- }
1931
-
1932
- async function get_response({ request, options, $session, route, status = 200, error }) {
1933
- const host = options.host || request.headers[options.host_header];
1934
-
1935
- const dependencies = {};
1936
-
1937
- const serialized_session = try_serialize($session, (err) => {
1938
- throw new Error(`Failed to serialize session data: ${err.message}`);
1939
- });
1940
-
1941
- const serialized_data = [];
1942
-
1943
- const match = route && route.pattern.exec(request.path);
1944
- const params = route && route.params(match);
1945
-
1946
- const page = {
1947
- host,
1948
- path: request.path,
1949
- query: request.query,
1950
- params
1951
- };
1952
-
1953
- let uses_credentials = false;
1954
-
1955
- const fetcher = async (url, opts = {}) => {
1956
- if (options.local && url.startsWith(options.paths.assets)) {
1957
- // when running `start`, or prerendering, `assets` should be
1958
- // config.paths.assets, but we should still be able to fetch
1959
- // assets directly from `static`
1960
- url = url.replace(options.paths.assets, '');
1961
- }
1962
-
1963
- const parsed = Url.parse(url);
1964
-
1965
- if (opts.credentials !== 'omit') {
1966
- uses_credentials = true;
1967
- }
1968
-
1969
- let response;
1970
-
1971
- if (parsed.protocol) {
1972
- // external fetch
1973
- response = await fetch(parsed.href, opts);
1974
- } else {
1975
- // otherwise we're dealing with an internal fetch
1976
- const resolved = Url.resolve(request.path, parsed.pathname);
1977
-
1978
- // is this a request for a static asset?
1979
- const filename = resolved.slice(1);
1980
- const filename_html = `${filename}/index.html`;
1981
- const asset = options.manifest.assets.find(
1982
- (d) => d.file === filename || d.file === filename_html
1983
- );
1984
-
1985
- if (asset) {
1986
- if (options.get_static_file) {
1987
- response = new Response(options.get_static_file(asset.file), {
1988
- headers: {
1989
- 'content-type': asset.type
1990
- }
1991
- });
1992
- } else {
1993
- // TODO we need to know what protocol to use
1994
- response = await fetch(`http://${page.host}/${asset.file}`, opts);
1995
- }
1996
- }
1997
-
1998
- if (!response) {
1999
- const rendered = await render(
2000
- {
2001
- host: request.host,
2002
- method: opts.method || 'GET',
2003
- headers: opts.headers || {}, // TODO inject credentials...
2004
- path: resolved,
2005
- body: opts.body,
2006
- query: new Url.URLSearchParams(parsed.query || '')
2007
- },
2008
- {
2009
- ...options,
2010
- fetched: true
2011
- }
2012
- );
2013
-
2014
- if (rendered) {
2015
- // TODO this is primarily for the benefit of the static case,
2016
- // but could it be used elsewhere?
2017
- dependencies[resolved] = rendered;
2018
-
2019
- response = new Response(rendered.body, {
2020
- status: rendered.status,
2021
- headers: rendered.headers
2022
- });
2023
- }
2024
- }
2025
- }
2026
-
2027
- if (response) {
2028
- const clone = response.clone();
2029
-
2030
- const headers = {};
2031
- clone.headers.forEach((value, key) => {
2032
- if (key !== 'etag') headers[key] = value;
2033
- });
2034
-
2035
- const payload = JSON.stringify({
2036
- status: clone.status,
2037
- statusText: clone.statusText,
2038
- headers,
2039
- body: await clone.text() // TODO handle binary data
2040
- });
2041
-
2042
- // TODO i guess we need to sanitize/escape this... somehow?
2043
- serialized_data.push({ url, payload });
2044
-
2045
- return response;
2046
- }
2047
-
2048
- return new Response('Not found', {
2049
- status: 404
2050
- });
2051
- };
2052
-
2053
- const parts = error ? [options.manifest.layout] : [options.manifest.layout, ...route.parts];
2054
-
2055
- const component_promises = parts.map((loader) => loader());
2056
- const components = [];
2057
- const props_promises = [];
2058
-
2059
- let context = {};
2060
- let maxage;
2061
-
2062
- for (let i = 0; i < component_promises.length; i += 1) {
2063
- let loaded;
2064
-
2065
- try {
2066
- const mod = await component_promises[i];
2067
- components[i] = mod.default;
2068
-
2069
- if (options.only_prerender && !mod.prerender) {
2070
- return;
2071
- }
2072
-
2073
- loaded =
2074
- mod.load &&
2075
- (await mod.load.call(null, {
2076
- page,
2077
- get session() {
2078
- uses_credentials = true;
2079
- return $session;
2080
- },
2081
- fetch: fetcher,
2082
- context: { ...context }
2083
- }));
2084
- } catch (e) {
2085
- // if load fails when we're already rendering the
2086
- // error page, there's not a lot we can do
2087
- if (error) throw e;
2088
-
2089
- loaded = { error: e };
2090
- }
2091
-
2092
- if (loaded) {
2093
- if (loaded.error) {
2094
- return await get_response({
2095
- request,
2096
- options,
2097
- $session,
2098
- route,
2099
- status: loaded.status || 500,
2100
- error: loaded.error
2101
- });
2102
- }
2103
-
2104
- if (loaded.redirect) {
2105
- return {
2106
- status: loaded.redirect.status,
2107
- headers: {
2108
- location: loaded.redirect.to
2109
- }
2110
- };
2111
- }
2112
-
2113
- if (loaded.context) {
2114
- context = {
2115
- ...context,
2116
- ...loaded.context
2117
- };
2118
- }
2119
-
2120
- maxage = loaded.maxage || 0;
2121
-
2122
- props_promises[i] = loaded.props;
2123
- }
2124
- }
2125
-
2126
- const session = writable($session);
2127
- let session_tracking_active = false;
2128
- const unsubscribe = session.subscribe(() => {
2129
- if (session_tracking_active) uses_credentials = true;
2130
- });
2131
- session_tracking_active = true;
2132
-
2133
- if (error) {
2134
- if (options.dev) {
2135
- error.stack = await options.get_stack(error);
2136
- } else {
2137
- // remove error.stack in production
2138
- error.stack = String(error);
2139
- }
2140
- }
2141
-
2142
- const props = {
2143
- status,
2144
- error,
2145
- stores: {
2146
- page: writable(null),
2147
- navigating: writable(null),
2148
- session
2149
- },
2150
- page,
2151
- components
2152
- };
2153
-
2154
- // leveln (instead of levels[n]) makes it easy to avoid
2155
- // unnecessary updates for layout components
2156
- for (let i = 0; i < props_promises.length; i += 1) {
2157
- props[`props_${i}`] = await props_promises[i];
2158
- }
2159
-
2160
- let rendered;
2161
-
2162
- try {
2163
- rendered = options.root.render(props);
2164
- } catch (e) {
2165
- if (error) throw e;
2166
-
2167
- return await get_response({
2168
- request,
2169
- options,
2170
- $session,
2171
- route,
2172
- status: 500,
2173
- error: e
2174
- });
2175
- }
2176
-
2177
- unsubscribe();
2178
-
2179
- // TODO all the `route &&` stuff is messy
2180
- const js_deps = route ? route.js : [];
2181
- const css_deps = route ? route.css : [];
2182
-
2183
- const s = JSON.stringify;
2184
-
2185
- // TODO strip the AMP stuff out of the build if not relevant
2186
- const links = options.amp
2187
- ? `<style amp-custom>${(
2188
- await Promise.all(css_deps.map((dep) => options.get_amp_css(dep)))
2189
- ).join('\n')}</style>`
2190
- : [
2191
- ...js_deps.map((dep) => `<link rel="modulepreload" href="${dep}">`),
2192
- ...css_deps.map((dep) => `<link rel="stylesheet" href="${dep}">`)
2193
- ].join('\n\t\t\t');
2194
-
2195
- const init = options.amp
2196
- ? `
2197
- <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
2198
- <noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
2199
- <script async src="https://cdn.ampproject.org/v0.js"></script>`
2200
- : `
2201
- <script type="module">
2202
- import { start } from '${options.paths.assets}/${options.app_dir}/${options.entry}';
2203
- ${options.start_global ? `window.${options.start_global} = () => ` : ''}start({
2204
- target: ${options.target ? `document.querySelector(${s(options.target)})` : 'document.body'},
2205
- host: ${host ? s(host) : 'location.host'},
2206
- paths: ${s(options.paths)},
2207
- status: ${status},
2208
- error: ${serialize_error(error)},
2209
- session: ${serialized_session}
2210
- });
2211
- </script>`;
2212
-
2213
- const head = [rendered.head, links, init].join('\n\n');
2214
-
2215
- const body = options.amp
2216
- ? rendered.html
2217
- : `${rendered.html}
2218
-
2219
- ${serialized_data
2220
- .map(({ url, payload }) => `<script type="svelte-data" url="${url}">${payload}</script>`)
2221
- .join('\n\n\t\t\t')}
2222
- `.replace(/^\t{2}/gm, '');
2223
-
2224
- const headers = {
2225
- 'content-type': 'text/html'
2226
- };
2227
-
2228
- if (maxage) {
2229
- headers['cache-control'] = `${uses_credentials ? 'private' : 'public'}, max-age=${maxage}`;
2230
- }
2231
-
2232
- return {
2233
- status,
2234
- headers,
2235
- body: options.template({ head, body }),
2236
- dependencies
2237
- };
2238
- }
2239
-
2240
- async function render_page(request, context, options) {
2241
- const route = options.manifest.pages.find((route) => route.pattern.test(request.path));
2242
-
2243
- const $session = await (options.setup.getSession && options.setup.getSession(context));
2244
-
2245
- if (!route) {
2246
- if (options.fetched) {
2247
- // we came here because of a bad request in a `load` function.
2248
- // rather than render the error page — which could lead to an
2249
- // infinite loop, if the `load` belonged to the root layout,
2250
- // we respond with a bare-bones 500
2251
- throw new Error('Bad request in load function');
2252
- }
2253
-
2254
- return await get_response({
2255
- request,
2256
- options,
2257
- $session,
2258
- route,
2259
- status: 404,
2260
- error: new Error(`Not found: ${request.path}`)
2261
- });
2262
- }
2263
-
2264
- return await get_response({
2265
- request,
2266
- options,
2267
- $session,
2268
- route,
2269
- status: 200,
2270
- error: null
2271
- });
2272
- }
2273
-
2274
- function try_serialize(data, fail) {
2275
- try {
2276
- return devalue(data);
2277
- } catch (err) {
2278
- if (fail) fail(err);
2279
- return null;
2280
- }
2281
- }
2282
-
2283
- // Ensure we return something truthy so the client will not re-render the page over the error
2284
- function serialize_error(error) {
2285
- if (!error) return null;
2286
- let serialized = try_serialize(error);
2287
- if (!serialized) {
2288
- const { name, message, stack } = error;
2289
- serialized = try_serialize({ name, message, stack });
2290
- }
2291
- if (!serialized) {
2292
- serialized = '{}';
2293
- }
2294
- return serialized;
2295
- }
2296
-
2297
- function render_route(request, context, options) {
2298
- const route = options.manifest.endpoints.find((route) => route.pattern.test(request.path));
2299
- if (!route) return null;
2300
-
2301
- return route.load().then(async (mod) => {
2302
- const handler = mod[request.method.toLowerCase().replace('delete', 'del')]; // 'delete' is a reserved word
2303
-
2304
- if (handler) {
2305
- const match = route.pattern.exec(request.path);
2306
- const params = route.params(match);
2307
-
2308
- const response = await handler(
2309
- {
2310
- host: options.host || request.headers[options.host_header || 'host'],
2311
- path: request.path,
2312
- headers: request.headers,
2313
- query: request.query,
2314
- body: request.body,
2315
- params
2316
- },
2317
- context
2318
- );
2319
-
2320
- if (typeof response !== 'object' || response.body == null) {
2321
- return {
2322
- status: 500,
2323
- body: `Invalid response from route ${request.path}; ${
2324
- response.body == null ? 'body is missing' : `expected an object, got ${typeof response}`
2325
- }`,
2326
- headers: {}
2327
- };
2328
- }
2329
-
2330
- let { status = 200, body, headers = {} } = response;
2331
-
2332
- headers = lowercase_keys(headers);
2333
-
2334
- if (
2335
- (typeof body === 'object' && !('content-type' in headers)) ||
2336
- headers['content-type'] === 'application/json'
2337
- ) {
2338
- headers = { ...headers, 'content-type': 'application/json' };
2339
- body = JSON.stringify(body);
2340
- }
2341
-
2342
- return { status, body, headers };
2343
- } else {
2344
- return {
2345
- status: 501,
2346
- body: `${request.method} is not implemented for ${request.path}`,
2347
- headers: {}
2348
- };
2349
- }
2350
- });
2351
- }
2352
-
2353
- function lowercase_keys(obj) {
2354
- const clone = {};
2355
- for (const key in obj) {
2356
- clone[key.toLowerCase()] = obj[key];
2357
- }
2358
- return clone;
2359
- }
2360
-
2361
- function md5(body) {
2362
- return crypto.createHash('md5').update(body).digest('hex');
2363
- }
2364
-
2365
- async function render(request, options) {
2366
- if (request.path.endsWith('/') && request.path !== '/') {
2367
- const q = request.query.toString();
2368
-
2369
- return {
2370
- status: 301,
2371
- headers: {
2372
- location: request.path.slice(0, -1) + (q ? `?${q}` : '')
2373
- }
2374
- };
2375
- }
2376
-
2377
- const { context, headers = {} } =
2378
- (await (options.setup.prepare && options.setup.prepare(request.headers))) || {};
2379
-
2380
- try {
2381
- const response = await (render_route(request, context, options) ||
2382
- render_page(request, context, options));
2383
-
2384
- if (response) {
2385
- // inject ETags for 200 responses
2386
- if (response.status === 200) {
2387
- if (!/(no-store|immutable)/.test(response.headers['cache-control'])) {
2388
- const etag = `"${md5(response.body)}"`;
2389
-
2390
- if (request.headers['if-none-match'] === etag) {
2391
- return {
2392
- status: 304,
2393
- headers: {},
2394
- body: null
2395
- };
2396
- }
2397
-
2398
- response.headers['etag'] = etag;
2399
- }
2400
- }
2401
-
2402
- return {
2403
- status: response.status,
2404
- headers: { ...headers, ...response.headers },
2405
- body: response.body,
2406
- dependencies: response.dependencies
2407
- };
2408
- }
2409
- } catch (e) {
2410
- if (e && e.stack) {
2411
- e.stack = await options.get_stack(e);
2412
- }
2413
-
2414
- console.error((e && e.stack) || e);
2415
-
2416
- return {
2417
- status: 500,
2418
- headers,
2419
- body: options.dev ? e.stack : e.message
2420
- };
2421
- }
2422
- }
2423
-
2424
- exports.render = render;
2425
- //# sourceMappingURL=renderer.js.map