@whatwg-node/node-fetch 0.3.3-rc-20230320123406-da3a60b → 0.3.3

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 (73) hide show
  1. package/cjs/AbortController.js +14 -0
  2. package/cjs/AbortError.js +20 -0
  3. package/cjs/AbortSignal.js +37 -0
  4. package/cjs/Blob.js +119 -0
  5. package/cjs/Body.js +372 -0
  6. package/cjs/File.js +13 -0
  7. package/cjs/FormData.js +134 -0
  8. package/cjs/Headers.js +127 -0
  9. package/cjs/ReadableStream.js +172 -0
  10. package/cjs/Request.js +69 -0
  11. package/cjs/Response.js +76 -0
  12. package/cjs/TextEncoderDecoder.js +39 -0
  13. package/cjs/URL.js +55 -0
  14. package/cjs/URLSearchParams.js +103 -0
  15. package/cjs/fetch.js +143 -0
  16. package/cjs/index.js +35 -0
  17. package/cjs/package.json +1 -0
  18. package/cjs/utils.js +18 -0
  19. package/esm/AbortController.js +10 -0
  20. package/esm/AbortError.js +16 -0
  21. package/esm/AbortSignal.js +33 -0
  22. package/esm/Blob.js +115 -0
  23. package/esm/Body.js +367 -0
  24. package/esm/File.js +9 -0
  25. package/esm/FormData.js +129 -0
  26. package/esm/Headers.js +123 -0
  27. package/esm/ReadableStream.js +168 -0
  28. package/esm/Request.js +65 -0
  29. package/esm/Response.js +72 -0
  30. package/esm/TextEncoderDecoder.js +33 -0
  31. package/esm/URL.js +50 -0
  32. package/esm/URLSearchParams.js +98 -0
  33. package/esm/fetch.js +139 -0
  34. package/esm/index.js +15 -0
  35. package/esm/utils.js +13 -0
  36. package/package.json +19 -12
  37. package/typings/AbortController.d.cts +5 -0
  38. package/{AbortController.d.ts → typings/AbortController.d.ts} +1 -1
  39. package/typings/AbortError.d.ts +4 -0
  40. package/typings/AbortSignal.d.ts +11 -0
  41. package/typings/Blob.d.ts +18 -0
  42. package/typings/Body.d.cts +41 -0
  43. package/{Body.d.ts → typings/Body.d.ts} +3 -3
  44. package/typings/File.d.cts +7 -0
  45. package/{File.d.ts → typings/File.d.ts} +1 -1
  46. package/typings/FormData.d.cts +17 -0
  47. package/{FormData.d.ts → typings/FormData.d.ts} +2 -2
  48. package/typings/Headers.d.ts +21 -0
  49. package/typings/ReadableStream.d.ts +20 -0
  50. package/typings/Request.d.cts +24 -0
  51. package/{Request.d.ts → typings/Request.d.ts} +2 -2
  52. package/typings/Response.d.cts +22 -0
  53. package/{Response.d.ts → typings/Response.d.ts} +2 -2
  54. package/typings/TextEncoderDecoder.d.ts +15 -0
  55. package/typings/URL.d.cts +14 -0
  56. package/{URL.d.ts → typings/URL.d.ts} +1 -1
  57. package/typings/URLSearchParams.d.ts +17 -0
  58. package/typings/fetch.d.cts +3 -0
  59. package/{fetch.d.ts → typings/fetch.d.ts} +2 -2
  60. package/typings/index.d.cts +15 -0
  61. package/typings/index.d.ts +15 -0
  62. package/typings/utils.d.ts +2 -0
  63. package/index.d.ts +0 -15
  64. package/index.js +0 -1452
  65. package/index.mjs +0 -1430
  66. /package/{AbortError.d.ts → typings/AbortError.d.cts} +0 -0
  67. /package/{AbortSignal.d.ts → typings/AbortSignal.d.cts} +0 -0
  68. /package/{Blob.d.ts → typings/Blob.d.cts} +0 -0
  69. /package/{Headers.d.ts → typings/Headers.d.cts} +0 -0
  70. /package/{ReadableStream.d.ts → typings/ReadableStream.d.cts} +0 -0
  71. /package/{TextEncoderDecoder.d.ts → typings/TextEncoderDecoder.d.cts} +0 -0
  72. /package/{URLSearchParams.d.ts → typings/URLSearchParams.d.cts} +0 -0
  73. /package/{utils.d.ts → typings/utils.d.cts} +0 -0
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PonyfillURLSearchParams = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fast_querystring_1 = tslib_1.__importDefault(require("fast-querystring"));
6
+ class PonyfillURLSearchParams {
7
+ constructor(init) {
8
+ if (init) {
9
+ if (typeof init === 'string') {
10
+ this.params = fast_querystring_1.default.parse(init);
11
+ }
12
+ else if (Array.isArray(init)) {
13
+ this.params = {};
14
+ for (const [key, value] of init) {
15
+ this.params[key] = value;
16
+ }
17
+ }
18
+ else if ('entries' in init) {
19
+ this.params = {};
20
+ for (const [key, value] of init.entries()) {
21
+ this.params[key] = value;
22
+ }
23
+ }
24
+ else {
25
+ this.params = init;
26
+ }
27
+ }
28
+ else {
29
+ this.params = {};
30
+ }
31
+ }
32
+ append(name, value) {
33
+ const existingValue = this.params[name];
34
+ const finalValue = existingValue ? `${existingValue},${value}` : value;
35
+ this.params[name] = finalValue;
36
+ }
37
+ delete(name) {
38
+ delete this.params[name];
39
+ }
40
+ get(name) {
41
+ const value = this.params[name];
42
+ if (Array.isArray(value)) {
43
+ return value[0] || null;
44
+ }
45
+ return value || null;
46
+ }
47
+ getAll(name) {
48
+ const value = this.params[name];
49
+ if (!Array.isArray(value)) {
50
+ return value ? [value] : [];
51
+ }
52
+ return value;
53
+ }
54
+ has(name) {
55
+ return name in this.params;
56
+ }
57
+ set(name, value) {
58
+ this.params[name] = value;
59
+ }
60
+ sort() {
61
+ const sortedKeys = Object.keys(this.params).sort();
62
+ const sortedParams = {};
63
+ for (const key of sortedKeys) {
64
+ sortedParams[key] = this.params[key];
65
+ }
66
+ this.params = sortedParams;
67
+ }
68
+ toString() {
69
+ return fast_querystring_1.default.stringify(this.params);
70
+ }
71
+ *keys() {
72
+ for (const key in this.params) {
73
+ yield key;
74
+ }
75
+ }
76
+ *entries() {
77
+ for (const key of this.keys()) {
78
+ const value = this.params[key];
79
+ if (Array.isArray(value)) {
80
+ for (const item of value) {
81
+ yield [key, item];
82
+ }
83
+ }
84
+ else {
85
+ yield [key, value];
86
+ }
87
+ }
88
+ }
89
+ *values() {
90
+ for (const [, value] of this) {
91
+ yield value;
92
+ }
93
+ }
94
+ [Symbol.iterator]() {
95
+ return this.entries();
96
+ }
97
+ forEach(callback) {
98
+ for (const [key, value] of this) {
99
+ callback(value, key, this);
100
+ }
101
+ }
102
+ }
103
+ exports.PonyfillURLSearchParams = PonyfillURLSearchParams;
package/cjs/fetch.js ADDED
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchPonyfill = void 0;
4
+ const fs_1 = require("fs");
5
+ const http_1 = require("http");
6
+ const https_1 = require("https");
7
+ const stream_1 = require("stream");
8
+ const url_1 = require("url");
9
+ const zlib_1 = require("zlib");
10
+ const AbortError_js_1 = require("./AbortError.js");
11
+ const Blob_js_1 = require("./Blob.js");
12
+ const Request_js_1 = require("./Request.js");
13
+ const Response_js_1 = require("./Response.js");
14
+ const URL_js_1 = require("./URL.js");
15
+ const utils_js_1 = require("./utils.js");
16
+ function getResponseForFile(url) {
17
+ const path = (0, url_1.fileURLToPath)(url);
18
+ const readable = (0, fs_1.createReadStream)(path);
19
+ return new Response_js_1.PonyfillResponse(readable);
20
+ }
21
+ function getRequestFnForProtocol(protocol) {
22
+ switch (protocol) {
23
+ case 'http:':
24
+ return http_1.request;
25
+ case 'https:':
26
+ return https_1.request;
27
+ }
28
+ throw new Error(`Unsupported protocol: ${protocol}`);
29
+ }
30
+ const BASE64_SUFFIX = ';base64';
31
+ function fetchPonyfill(info, init) {
32
+ if (typeof info === 'string' || 'href' in info) {
33
+ const ponyfillRequest = new Request_js_1.PonyfillRequest(info, init);
34
+ return fetchPonyfill(ponyfillRequest);
35
+ }
36
+ const fetchRequest = info;
37
+ return new Promise((resolve, reject) => {
38
+ try {
39
+ const url = new URL_js_1.PonyfillURL(fetchRequest.url, 'http://localhost');
40
+ if (url.protocol === 'data:') {
41
+ const [mimeType = 'text/plain', ...datas] = url.pathname.split(',');
42
+ const data = decodeURIComponent(datas.join(','));
43
+ if (mimeType.endsWith(BASE64_SUFFIX)) {
44
+ const buffer = Buffer.from(data, 'base64url');
45
+ const realMimeType = mimeType.slice(0, -BASE64_SUFFIX.length);
46
+ const file = new Blob_js_1.PonyfillBlob([buffer], { type: realMimeType });
47
+ const response = new Response_js_1.PonyfillResponse(file, {
48
+ status: 200,
49
+ statusText: 'OK',
50
+ });
51
+ resolve(response);
52
+ return;
53
+ }
54
+ const response = new Response_js_1.PonyfillResponse(data, {
55
+ status: 200,
56
+ statusText: 'OK',
57
+ headers: {
58
+ 'content-type': mimeType,
59
+ },
60
+ });
61
+ resolve(response);
62
+ return;
63
+ }
64
+ if (url.protocol === 'file:') {
65
+ const response = getResponseForFile(fetchRequest.url);
66
+ resolve(response);
67
+ return;
68
+ }
69
+ const requestFn = getRequestFnForProtocol(url.protocol);
70
+ const nodeReadable = (fetchRequest.body != null
71
+ ? 'pipe' in fetchRequest.body
72
+ ? fetchRequest.body
73
+ : stream_1.Readable.from(fetchRequest.body)
74
+ : null);
75
+ const nodeHeaders = (0, utils_js_1.getHeadersObj)(fetchRequest.headers);
76
+ const abortListener = function abortListener(event) {
77
+ nodeRequest.destroy();
78
+ const reason = event.detail;
79
+ reject(new AbortError_js_1.PonyfillAbortError(reason));
80
+ };
81
+ fetchRequest.signal.addEventListener('abort', abortListener);
82
+ const nodeRequest = requestFn(fetchRequest.url, {
83
+ // signal: fetchRequest.signal will be added when v14 reaches EOL
84
+ method: fetchRequest.method,
85
+ headers: nodeHeaders,
86
+ });
87
+ nodeRequest.once('response', nodeResponse => {
88
+ let responseBody = nodeResponse;
89
+ const contentEncoding = nodeResponse.headers['content-encoding'];
90
+ switch (contentEncoding) {
91
+ case 'x-gzip':
92
+ case 'gzip':
93
+ responseBody = nodeResponse.pipe((0, zlib_1.createGunzip)());
94
+ break;
95
+ case 'x-deflate':
96
+ case 'deflate':
97
+ responseBody = nodeResponse.pipe((0, zlib_1.createInflate)());
98
+ break;
99
+ case 'br':
100
+ responseBody = nodeResponse.pipe((0, zlib_1.createBrotliDecompress)());
101
+ break;
102
+ }
103
+ if (nodeResponse.headers.location) {
104
+ if (fetchRequest.redirect === 'error') {
105
+ const redirectError = new Error('Redirects are not allowed');
106
+ reject(redirectError);
107
+ nodeResponse.resume();
108
+ return;
109
+ }
110
+ if (fetchRequest.redirect === 'follow') {
111
+ const redirectedUrl = new URL_js_1.PonyfillURL(nodeResponse.headers.location, url);
112
+ const redirectResponse$ = fetchPonyfill(redirectedUrl, info);
113
+ resolve(redirectResponse$.then(redirectResponse => {
114
+ redirectResponse.redirected = true;
115
+ return redirectResponse;
116
+ }));
117
+ nodeResponse.resume();
118
+ return;
119
+ }
120
+ }
121
+ const responseHeaders = nodeResponse.headers;
122
+ const ponyfillResponse = new Response_js_1.PonyfillResponse(responseBody, {
123
+ status: nodeResponse.statusCode,
124
+ statusText: nodeResponse.statusMessage,
125
+ headers: responseHeaders,
126
+ url: info.url,
127
+ });
128
+ resolve(ponyfillResponse);
129
+ });
130
+ nodeRequest.once('error', reject);
131
+ if (nodeReadable) {
132
+ nodeReadable.pipe(nodeRequest);
133
+ }
134
+ else {
135
+ nodeRequest.end();
136
+ }
137
+ }
138
+ catch (e) {
139
+ reject(e);
140
+ }
141
+ });
142
+ }
143
+ exports.fetchPonyfill = fetchPonyfill;
package/cjs/index.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.URLSearchParams = exports.URL = exports.btoa = exports.TextDecoder = exports.TextEncoder = exports.Blob = exports.AbortError = exports.AbortSignal = exports.AbortController = exports.FormData = exports.File = exports.ReadableStream = exports.Response = exports.Request = exports.Body = exports.Headers = exports.fetch = void 0;
4
+ var fetch_js_1 = require("./fetch.js");
5
+ Object.defineProperty(exports, "fetch", { enumerable: true, get: function () { return fetch_js_1.fetchPonyfill; } });
6
+ var Headers_js_1 = require("./Headers.js");
7
+ Object.defineProperty(exports, "Headers", { enumerable: true, get: function () { return Headers_js_1.PonyfillHeaders; } });
8
+ var Body_js_1 = require("./Body.js");
9
+ Object.defineProperty(exports, "Body", { enumerable: true, get: function () { return Body_js_1.PonyfillBody; } });
10
+ var Request_js_1 = require("./Request.js");
11
+ Object.defineProperty(exports, "Request", { enumerable: true, get: function () { return Request_js_1.PonyfillRequest; } });
12
+ var Response_js_1 = require("./Response.js");
13
+ Object.defineProperty(exports, "Response", { enumerable: true, get: function () { return Response_js_1.PonyfillResponse; } });
14
+ var ReadableStream_js_1 = require("./ReadableStream.js");
15
+ Object.defineProperty(exports, "ReadableStream", { enumerable: true, get: function () { return ReadableStream_js_1.PonyfillReadableStream; } });
16
+ var File_js_1 = require("./File.js");
17
+ Object.defineProperty(exports, "File", { enumerable: true, get: function () { return File_js_1.PonyfillFile; } });
18
+ var FormData_js_1 = require("./FormData.js");
19
+ Object.defineProperty(exports, "FormData", { enumerable: true, get: function () { return FormData_js_1.PonyfillFormData; } });
20
+ var AbortController_js_1 = require("./AbortController.js");
21
+ Object.defineProperty(exports, "AbortController", { enumerable: true, get: function () { return AbortController_js_1.PonyfillAbortController; } });
22
+ var AbortSignal_js_1 = require("./AbortSignal.js");
23
+ Object.defineProperty(exports, "AbortSignal", { enumerable: true, get: function () { return AbortSignal_js_1.PonyfillAbortSignal; } });
24
+ var AbortError_js_1 = require("./AbortError.js");
25
+ Object.defineProperty(exports, "AbortError", { enumerable: true, get: function () { return AbortError_js_1.PonyfillAbortError; } });
26
+ var Blob_js_1 = require("./Blob.js");
27
+ Object.defineProperty(exports, "Blob", { enumerable: true, get: function () { return Blob_js_1.PonyfillBlob; } });
28
+ var TextEncoderDecoder_js_1 = require("./TextEncoderDecoder.js");
29
+ Object.defineProperty(exports, "TextEncoder", { enumerable: true, get: function () { return TextEncoderDecoder_js_1.PonyfillTextEncoder; } });
30
+ Object.defineProperty(exports, "TextDecoder", { enumerable: true, get: function () { return TextEncoderDecoder_js_1.PonyfillTextDecoder; } });
31
+ Object.defineProperty(exports, "btoa", { enumerable: true, get: function () { return TextEncoderDecoder_js_1.PonyfillBtoa; } });
32
+ var URL_js_1 = require("./URL.js");
33
+ Object.defineProperty(exports, "URL", { enumerable: true, get: function () { return URL_js_1.PonyfillURL; } });
34
+ var URLSearchParams_js_1 = require("./URLSearchParams.js");
35
+ Object.defineProperty(exports, "URLSearchParams", { enumerable: true, get: function () { return URLSearchParams_js_1.PonyfillURLSearchParams; } });
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
package/cjs/utils.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uint8ArrayToArrayBuffer = exports.getHeadersObj = void 0;
4
+ function getHeadersObj(headers) {
5
+ if (headers == null || !('forEach' in headers)) {
6
+ return headers;
7
+ }
8
+ const obj = {};
9
+ headers.forEach((value, key) => {
10
+ obj[key] = value;
11
+ });
12
+ return obj;
13
+ }
14
+ exports.getHeadersObj = getHeadersObj;
15
+ function uint8ArrayToArrayBuffer(uint8array) {
16
+ return uint8array.buffer.slice(uint8array.byteOffset, uint8array.byteOffset + uint8array.byteLength);
17
+ }
18
+ exports.uint8ArrayToArrayBuffer = uint8ArrayToArrayBuffer;
@@ -0,0 +1,10 @@
1
+ import { PonyfillAbortSignal } from './AbortSignal.js';
2
+ // Will be removed after v14 reaches EOL
3
+ export class PonyfillAbortController {
4
+ constructor() {
5
+ this.signal = new PonyfillAbortSignal();
6
+ }
7
+ abort(reason) {
8
+ this.signal.abort(reason);
9
+ }
10
+ }
@@ -0,0 +1,16 @@
1
+ // Will be removed after v14 reaches EOL
2
+ export class PonyfillAbortError extends Error {
3
+ constructor(reason) {
4
+ let message = 'The operation was aborted.';
5
+ if (reason) {
6
+ message += ` reason: ${reason}`;
7
+ }
8
+ super(message, {
9
+ cause: reason,
10
+ });
11
+ this.name = 'AbortError';
12
+ }
13
+ get reason() {
14
+ return this.cause;
15
+ }
16
+ }
@@ -0,0 +1,33 @@
1
+ // Will be removed after v14 reaches EOL
2
+ import { CustomEvent, EventTarget } from '@whatwg-node/events';
3
+ import { PonyfillAbortError } from './AbortError.js';
4
+ export class PonyfillAbortSignal extends EventTarget {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.aborted = false;
8
+ this._onabort = null;
9
+ }
10
+ throwIfAborted() {
11
+ if (this.aborted) {
12
+ throw new PonyfillAbortError();
13
+ }
14
+ }
15
+ get onabort() {
16
+ return this._onabort;
17
+ }
18
+ set onabort(value) {
19
+ if (this._onabort) {
20
+ this.removeEventListener('abort', this._onabort);
21
+ }
22
+ this.addEventListener('abort', value);
23
+ }
24
+ abort(reason) {
25
+ const abortEvent = new CustomEvent('abort', { detail: reason });
26
+ this.dispatchEvent(abortEvent);
27
+ }
28
+ static timeout(milliseconds) {
29
+ const signal = new PonyfillAbortSignal();
30
+ setTimeout(() => signal.abort(`timeout in ${milliseconds} ms`), milliseconds);
31
+ return signal;
32
+ }
33
+ }
package/esm/Blob.js ADDED
@@ -0,0 +1,115 @@
1
+ import { PonyfillReadableStream } from './ReadableStream.js';
2
+ import { uint8ArrayToArrayBuffer } from './utils.js';
3
+ function getBlobPartAsBuffer(blobPart) {
4
+ if (typeof blobPart === 'string') {
5
+ return Buffer.from(blobPart);
6
+ }
7
+ else if (Buffer.isBuffer(blobPart)) {
8
+ return blobPart;
9
+ }
10
+ else if (blobPart instanceof Uint8Array) {
11
+ return Buffer.from(blobPart);
12
+ }
13
+ else if ('buffer' in blobPart) {
14
+ return Buffer.from(blobPart.buffer, blobPart.byteOffset, blobPart.byteLength);
15
+ }
16
+ else {
17
+ return Buffer.from(blobPart);
18
+ }
19
+ }
20
+ function isBlob(obj) {
21
+ return obj != null && typeof obj === 'object' && obj.arrayBuffer != null;
22
+ }
23
+ // Will be removed after v14 reaches EOL
24
+ // Needed because v14 doesn't have .stream() implemented
25
+ export class PonyfillBlob {
26
+ constructor(blobParts, options) {
27
+ this.blobParts = blobParts;
28
+ this.type = (options === null || options === void 0 ? void 0 : options.type) || 'application/octet-stream';
29
+ this.encoding = (options === null || options === void 0 ? void 0 : options.encoding) || 'utf8';
30
+ }
31
+ async buffer() {
32
+ const bufferChunks = [];
33
+ for (const blobPart of this.blobParts) {
34
+ if (isBlob(blobPart)) {
35
+ const arrayBuf = await blobPart.arrayBuffer();
36
+ const buf = Buffer.from(arrayBuf, undefined, blobPart.size);
37
+ bufferChunks.push(buf);
38
+ }
39
+ else {
40
+ const buf = getBlobPartAsBuffer(blobPart);
41
+ bufferChunks.push(buf);
42
+ }
43
+ }
44
+ return Buffer.concat(bufferChunks);
45
+ }
46
+ async arrayBuffer() {
47
+ const buffer = await this.buffer();
48
+ return uint8ArrayToArrayBuffer(buffer);
49
+ }
50
+ async text() {
51
+ let text = '';
52
+ for (const blobPart of this.blobParts) {
53
+ if (typeof blobPart === 'string') {
54
+ text += blobPart;
55
+ }
56
+ else if ('text' in blobPart) {
57
+ text += await blobPart.text();
58
+ }
59
+ else {
60
+ const buf = getBlobPartAsBuffer(blobPart);
61
+ text += buf.toString(this.encoding);
62
+ }
63
+ }
64
+ return text;
65
+ }
66
+ get size() {
67
+ let size = 0;
68
+ for (const blobPart of this.blobParts) {
69
+ if (typeof blobPart === 'string') {
70
+ size += Buffer.byteLength(blobPart);
71
+ }
72
+ else if (isBlob(blobPart)) {
73
+ size += blobPart.size;
74
+ }
75
+ else if ('length' in blobPart) {
76
+ size += blobPart.length;
77
+ }
78
+ else if ('byteLength' in blobPart) {
79
+ size += blobPart.byteLength;
80
+ }
81
+ }
82
+ return size;
83
+ }
84
+ stream() {
85
+ let partQueue = [];
86
+ return new PonyfillReadableStream({
87
+ start: controller => {
88
+ partQueue = [...this.blobParts];
89
+ if (partQueue.length === 0) {
90
+ controller.close();
91
+ }
92
+ },
93
+ pull: async (controller) => {
94
+ const blobPart = partQueue.pop();
95
+ if (blobPart) {
96
+ if (isBlob(blobPart)) {
97
+ const arrayBuffer = await blobPart.arrayBuffer();
98
+ const buf = Buffer.from(arrayBuffer, undefined, blobPart.size);
99
+ controller.enqueue(buf);
100
+ }
101
+ else {
102
+ const buf = getBlobPartAsBuffer(blobPart);
103
+ controller.enqueue(buf);
104
+ }
105
+ }
106
+ else {
107
+ controller.close();
108
+ }
109
+ },
110
+ });
111
+ }
112
+ slice() {
113
+ throw new Error('Not implemented');
114
+ }
115
+ }