@geek-fun/serverless-adapter
Version:
Adapter for web frame work express, koa, springboot to run in serverless function as backend of apigateway cross multi cloud provider like aliyun, huawei
118 lines (117 loc) • 3.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const http_1 = require("http");
const common_1 = require("./common");
const headerEnd = '\r\n\r\n';
const BODY = Symbol('Response body');
const HEADERS = Symbol('Response headers');
const getString = (data) => {
if (Buffer.isBuffer(data)) {
return data.toString('utf8');
}
else if (typeof data === 'string') {
return data;
}
else if (data instanceof Uint8Array) {
return new TextDecoder().decode(data);
}
else {
throw new Error(`response.write() of unexpected type: ${typeof data}`);
}
};
const addData = (stream, data) => {
try {
stream[BODY].push(Buffer.from(data));
}
catch (err) {
(0, common_1.debug)(`Error adding data to response: ${err}`);
throw new Error(`response.write() of unexpected type: ${typeof data}`);
}
};
class ServerlessResponse extends http_1.ServerResponse {
static from(res) {
const response = new ServerlessResponse(res);
const { statusCode = 0, headers, body } = res;
response.statusCode = statusCode;
response[HEADERS] = headers;
response[BODY] = body ? [Buffer.from(body)] : [];
response.end();
return response;
}
static body(res) {
return Buffer.concat(res[BODY]);
}
static headers(res) {
const headers = typeof res.getHeaders === 'function' ? res.getHeaders() : res.headers;
return Object.assign(headers, res[HEADERS]);
}
get headers() {
return this[HEADERS];
}
setHeader(name, value) {
if (this._wroteHeader) {
this[HEADERS][name] = value;
}
else {
super.setHeader(name, value);
}
return this;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
writeHead(statusCode, reason, obj) {
const headers = typeof reason === 'string' ? obj : reason;
for (const name in headers) {
this.setHeader(name, headers[name]);
if (!this._wroteHeader) {
// we only need to initiate super.headers once
// writeHead will add the other headers itself
break;
}
}
super.writeHead(statusCode, reason, obj);
return this;
}
constructor(request) {
super(request);
this._wroteHeader = false;
this[BODY] = [];
this[HEADERS] = {};
this.useChunkedEncodingByDefault = false;
this.chunkedEncoding = false;
this._header = '';
this.assignSocket({
_writableState: {},
writable: true,
on: Function.prototype,
removeListener: Function.prototype,
destroy: Function.prototype,
cork: Function.prototype,
uncork: Function.prototype,
write: (data, encoding, cb) => {
if (typeof encoding === 'function') {
cb = encoding;
encoding = null;
}
if (this._header === '' || this._wroteHeader) {
addData(this, data);
}
else {
const string = getString(data);
const index = string.indexOf(headerEnd);
if (index !== -1) {
const remainder = string.slice(index + headerEnd.length);
if (remainder) {
addData(this, remainder);
}
this._wroteHeader = true;
}
}
if (typeof cb === 'function') {
cb();
}
},
});
}
}
exports.default = ServerlessResponse;