Spaces:
Running
Running
{ | |
"version": 3, | |
"sources": ["../../lib/net.ts"], | |
"sourcesContent": ["/**\n * Net - abstraction layer around Node's HTTP/S request system.\n * Advantages:\n * - easier acquiring of data\n * - mass disabling of outgoing requests via Config.\n */\n\nimport * as https from 'https';\nimport * as http from 'http';\nimport * as url from 'url';\nimport * as Streams from './streams';\ndeclare const Config: any;\n\nexport interface PostData {\n\t[key: string]: string | number;\n}\nexport interface NetRequestOptions extends https.RequestOptions {\n\tbody?: string | PostData;\n\twritable?: boolean;\n\tquery?: PostData;\n}\n\nexport class HttpError extends Error {\n\tstatusCode?: number;\n\tbody: string;\n\tconstructor(message: string, statusCode: number | undefined, body: string) {\n\t\tsuper(message);\n\t\tthis.name = 'HttpError';\n\t\tthis.statusCode = statusCode;\n\t\tthis.body = body;\n\t\tError.captureStackTrace(this, HttpError);\n\t}\n}\n\nexport class NetStream extends Streams.ReadWriteStream {\n\topts: NetRequestOptions | null;\n\turi: string;\n\trequest: http.ClientRequest;\n\t/** will be a Promise before the response is received, and the response itself after */\n\tresponse: Promise<http.IncomingMessage | null> | http.IncomingMessage | null;\n\tstatusCode: number | null;\n\t/** response headers */\n\theaders: http.IncomingHttpHeaders | null;\n\tstate: 'pending' | 'open' | 'timeout' | 'success' | 'error';\n\n\tconstructor(uri: string, opts: NetRequestOptions | null = null) {\n\t\tsuper();\n\t\tthis.statusCode = null;\n\t\tthis.headers = null;\n\t\tthis.uri = uri;\n\t\tthis.opts = opts;\n\t\t// make request\n\t\tthis.response = null;\n\t\tthis.state = 'pending';\n\t\tthis.request = this.makeRequest(opts);\n\t}\n\tmakeRequest(opts: NetRequestOptions | null) {\n\t\tif (!opts) opts = {};\n\t\tlet body = opts.body;\n\t\tif (body && typeof body !== 'string') {\n\t\t\tif (!opts.headers) opts.headers = {};\n\t\t\tif (!opts.headers['Content-Type']) {\n\t\t\t\topts.headers['Content-Type'] = 'application/x-www-form-urlencoded';\n\t\t\t}\n\t\t\tbody = NetStream.encodeQuery(body);\n\t\t}\n\n\t\tif (opts.query) {\n\t\t\tthis.uri += (this.uri.includes('?') ? '&' : '?') + NetStream.encodeQuery(opts.query);\n\t\t}\n\n\t\tif (body) {\n\t\t\tif (!opts.headers) opts.headers = {};\n\t\t\tif (!opts.headers['Content-Length']) {\n\t\t\t\topts.headers['Content-Length'] = Buffer.byteLength(body);\n\t\t\t}\n\t\t}\n\n\t\tconst protocol = url.parse(this.uri).protocol;\n\t\tconst net = protocol === 'https:' ? https : http;\n\n\t\tlet resolveResponse: ((value: http.IncomingMessage | null) => void) | null;\n\t\tthis.response = new Promise(resolve => {\n\t\t\tresolveResponse = resolve;\n\t\t});\n\n\t\tconst request = net.request(this.uri, opts, response => {\n\t\t\tthis.state = 'open';\n\t\t\tthis.nodeReadableStream = response;\n\t\t\tthis.response = response;\n\t\t\tthis.statusCode = response.statusCode || null;\n\t\t\tthis.headers = response.headers;\n\n\t\t\tresponse.setEncoding('utf-8');\n\t\t\tresolveResponse!(response);\n\t\t\tresolveResponse = null;\n\n\t\t\tresponse.on('data', data => {\n\t\t\t\tthis.push(data);\n\t\t\t});\n\t\t\tresponse.on('end', () => {\n\t\t\t\tif (this.state === 'open') this.state = 'success';\n\t\t\t\tif (!this.atEOF) this.pushEnd();\n\t\t\t});\n\t\t});\n\t\trequest.on('close', () => {\n\t\t\tif (!this.atEOF) {\n\t\t\t\tthis.state = 'error';\n\t\t\t\tthis.pushError(new Error(\"Unexpected connection close\"));\n\t\t\t}\n\t\t\tif (resolveResponse) {\n\t\t\t\tthis.response = null;\n\t\t\t\tresolveResponse(null);\n\t\t\t\tresolveResponse = null;\n\t\t\t}\n\t\t});\n\t\trequest.on('error', error => {\n\t\t\tif (!this.atEOF) this.pushError(error, true);\n\t\t});\n\t\tif (opts.timeout || opts.timeout === undefined) {\n\t\t\trequest.setTimeout(opts.timeout || 5000, () => {\n\t\t\t\tthis.state = 'timeout';\n\t\t\t\tthis.pushError(new Error(\"Request timeout\"));\n\t\t\t\trequest.abort();\n\t\t\t});\n\t\t}\n\n\t\tif (body) {\n\t\t\trequest.write(body);\n\t\t\trequest.end();\n\t\t\tif (opts.writable) {\n\t\t\t\tthrow new Error(`options.body is what you would have written to a NetStream - you must choose one or the other`);\n\t\t\t}\n\t\t} else if (opts.writable) {\n\t\t\tthis.nodeWritableStream = request;\n\t\t} else {\n\t\t\trequest.end();\n\t\t}\n\n\t\treturn request;\n\t}\n\tstatic encodeQuery(data: PostData) {\n\t\tlet out = '';\n\t\tfor (const key in data) {\n\t\t\tif (out) out += `&`;\n\t\t\tout += `${key}=${encodeURIComponent(`${data[key]}`)}`;\n\t\t}\n\t\treturn out;\n\t}\n\t_write(data: string | Buffer): Promise<void> | void {\n\t\tif (!this.nodeWritableStream) {\n\t\t\tthrow new Error(\"You must specify opts.writable to write to a request.\");\n\t\t}\n\t\tconst result = this.nodeWritableStream.write(data);\n\t\tif (result !== false) return undefined;\n\t\tif (!this.drainListeners.length) {\n\t\t\tthis.nodeWritableStream.once('drain', () => {\n\t\t\t\tfor (const listener of this.drainListeners) listener();\n\t\t\t\tthis.drainListeners = [];\n\t\t\t});\n\t\t}\n\t\treturn new Promise(resolve => {\n\t\t\tthis.drainListeners.push(resolve);\n\t\t});\n\t}\n\t_read() {\n\t\tthis.nodeReadableStream?.resume();\n\t}\n\t_pause() {\n\t\tthis.nodeReadableStream?.pause();\n\t}\n}\nexport class NetRequest {\n\turi: string;\n\t/** Response from last request, made so response stuff is available without being hacky */\n\tresponse?: http.IncomingMessage;\n\tconstructor(uri: string) {\n\t\tthis.uri = uri;\n\t}\n\t/**\n\t * Makes a http/https get request to the given link and returns a stream.\n\t * The request data itself can be read with ReadStream#readAll().\n\t * The NetStream class also holds headers and statusCode as a property.\n\t *\n\t * @param opts request opts - headers, etc.\n\t * @param body POST body\n\t */\n\tgetStream(opts: NetRequestOptions = {}) {\n\t\tif (typeof Config !== 'undefined' && Config.noNetRequests) {\n\t\t\tthrow new Error(`Net requests are disabled.`);\n\t\t}\n\t\tconst stream = new NetStream(this.uri, opts);\n\t\treturn stream;\n\t}\n\n\t/**\n\t * Makes a basic http/https request to the URI.\n\t * Returns the response data.\n\t *\n\t * Will throw if the response code isn't 200 OK.\n\t *\n\t * @param opts request opts - headers, etc.\n\t */\n\tasync get(opts: NetRequestOptions = {}): Promise<string> {\n\t\tconst stream = this.getStream(opts);\n\t\tconst response = await stream.response;\n\t\tif (response) this.response = response;\n\t\tif (response && response.statusCode !== 200) {\n\t\t\tthrow new HttpError(response.statusMessage || \"Connection error\", response.statusCode, await stream.readAll());\n\t\t}\n\t\treturn stream.readAll();\n\t}\n\n\t/**\n\t * Makes a http/https POST request to the given link.\n\t * @param opts request opts - headers, etc.\n\t * @param body POST body\n\t */\n\tpost(opts: Omit<NetRequestOptions, 'body'>, body: PostData | string): Promise<string>;\n\t/**\n\t * Makes a http/https POST request to the given link.\n\t * @param opts request opts - headers, etc.\n\t */\n\tpost(opts?: NetRequestOptions): Promise<string>;\n\tpost(opts: NetRequestOptions = {}, body?: PostData | string) {\n\t\tif (!body) body = opts.body;\n\t\treturn this.get({\n\t\t\t...opts,\n\t\t\tmethod: 'POST',\n\t\t\tbody,\n\t\t});\n\t}\n}\n\nexport const Net = Object.assign((path: string) => new NetRequest(path), {\n\tNetRequest, NetStream,\n});\n"], | |
"mappings": "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", | |
"names": [] | |
} | |