New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@trayio/express

Package Overview
Dependencies
Maintainers
4
Versions
160
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@trayio/express - npm Package Compare versions

Comparing version 3.8.0 to 3.9.0

269

dist/http/ExpressHttpController.js

@@ -25,11 +25,2 @@ "use strict";

};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -47,138 +38,140 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

class ExpressHttpController {
controller;
baseTmpPathForUploadedFiles;
constructor(controller, baseTmpPathForUploadedFiles = '/tmp') {
this.controller = controller;
this.baseTmpPathForUploadedFiles = baseTmpPathForUploadedFiles;
this.addRoute = (endpoint) => {
const route = (req, res) => __awaiter(this, void 0, void 0, function* () {
const headers = Object.entries(req.headers).reduce((acc, [key, value]) => {
const newValue = typeof value === 'undefined' ? '' : value;
return Object.assign(Object.assign({}, acc), { [key]: newValue });
}, {});
const requestBody = yield this.parseRequestBody(req);
const httpResponse = yield endpoint.execute({
headers,
pathParams: req.params,
queryString: req.query,
body: requestBody,
})();
const response = Object.entries(httpResponse.headers)
.reduce((acc, [key, value]) => acc.setHeader(key, value), res)
.status(httpResponse.statusCode);
httpResponse.body.pipe(response);
});
let method;
switch (endpoint.method) {
case Http_1.HttpMethod.Get:
method = 'get';
break;
case Http_1.HttpMethod.Post:
method = 'post';
break;
case Http_1.HttpMethod.Put:
method = 'put';
break;
case Http_1.HttpMethod.Delete:
method = 'delete';
break;
case Http_1.HttpMethod.Patch:
method = 'patch';
break;
default:
method = 'get';
break;
}
return (router) => router[method](endpoint.path, route);
}
addRoute = (endpoint) => {
const route = async (req, res) => {
const headers = Object.entries(req.headers).reduce((acc, [key, value]) => {
const newValue = typeof value === 'undefined' ? '' : value;
return {
...acc,
[key]: newValue,
};
}, {});
const requestBody = await this.parseRequestBody(req);
const httpResponse = await endpoint.execute({
headers,
pathParams: req.params,
queryString: req.query,
body: requestBody,
})();
const response = Object.entries(httpResponse.headers)
.reduce((acc, [key, value]) => acc.setHeader(key, value), res)
.status(httpResponse.statusCode);
httpResponse.body.pipe(response);
};
this.addRoutes = (router) => {
this.controller
.getEndpoints()
.forEach((endpoint) => this.addRoute(endpoint)(router));
return router;
};
this.parseRequestBody = (req) => __awaiter(this, void 0, void 0, function* () {
const contentType = req.headers['content-type'];
if (contentType && contentType.startsWith('multipart/form-data')) {
const multiPartResponse = yield this.parseMultipartFormData(req)();
const multiPartBody = E.getOrElse((error) => {
throw new Error(error.message);
})(multiPartResponse);
return multiPartBody;
let method;
switch (endpoint.method) {
case Http_1.HttpMethod.Get:
method = 'get';
break;
case Http_1.HttpMethod.Post:
method = 'post';
break;
case Http_1.HttpMethod.Put:
method = 'put';
break;
case Http_1.HttpMethod.Delete:
method = 'delete';
break;
case Http_1.HttpMethod.Patch:
method = 'patch';
break;
default:
method = 'get';
break;
}
return (router) => router[method](endpoint.path, route);
};
addRoutes = (router) => {
this.controller
.getEndpoints()
.forEach((endpoint) => this.addRoute(endpoint)(router));
return router;
};
parseRequestBody = async (req) => {
const contentType = req.headers['content-type'];
if (contentType && contentType.startsWith('multipart/form-data')) {
const multiPartResponse = await this.parseMultipartFormData(req)();
const multiPartBody = E.getOrElse((error) => {
throw new Error(error.message);
})(multiPartResponse);
return multiPartBody;
}
return this.parseGeneralRequestBody(req);
};
// express defaults empty request body to an empty object, so we need to transform to an array buffer
parseGeneralRequestBody = (req) => {
const body = Object.keys(req.body).length === 0 ? new ArrayBuffer(0) : req.body;
return BufferExtensions_1.BufferExtensions.arrayBufferToReadable(body);
};
parseMultipartFormData = (req) => TE.tryCatch(() => new Promise((resolve, reject) => {
/*
* NOTE: inorder to use any other underlying file storage other than node fs, we would have to use
* formidable's fileWriteStreamHandler option that enables formidable to write a file to a stream.
* When used the fileWriteStreamHandler option with passThrough stream, we ran into errors that we didn't have
* time to solve, but ideally, we would be using the FileStorage interface instead of letting formidable
* write to the file system directly.
*/
const form = (0, formidable_1.default)({
maxFiles: 1,
maxFileSize: 50 * 1024 * 1024,
uploadDir: this.baseTmpPathForUploadedFiles,
});
form.parse(req, (err, fields, files) => {
if (err) {
reject(err);
}
return this.parseGeneralRequestBody(req);
else {
const body = {
fields: this.flattenFields(fields),
files: this.flattenFiles(files),
};
resolve(body);
}
});
// express defaults empty request body to an empty object, so we need to transform to an array buffer
this.parseGeneralRequestBody = (req) => {
const body = Object.keys(req.body).length === 0 ? new ArrayBuffer(0) : req.body;
return BufferExtensions_1.BufferExtensions.arrayBufferToReadable(body);
};
this.parseMultipartFormData = (req) => TE.tryCatch(() => new Promise((resolve, reject) => {
/*
* NOTE: inorder to use any other underlying file storage other than node fs, we would have to use
* formidable's fileWriteStreamHandler option that enables formidable to write a file to a stream.
* When used the fileWriteStreamHandler option with passThrough stream, we ran into errors that we didn't have
* time to solve, but ideally, we would be using the FileStorage interface instead of letting formidable
* write to the file system directly.
*/
const form = (0, formidable_1.default)({
maxFiles: 1,
maxFileSize: 50 * 1024 * 1024,
uploadDir: this.baseTmpPathForUploadedFiles,
});
form.parse(req, (err, fields, files) => {
if (err) {
reject(err);
}
else {
const body = {
fields: this.flattenFields(fields),
files: this.flattenFiles(files),
};
resolve(body);
}
});
}), (error) => new Error(error.message));
this.flattenFields = (fields) => {
const flattenedFields = {};
Object.entries(fields).forEach(([key, value]) => {
if (Array.isArray(value) && value.length > 1) {
throw new Error(`Field ${key} has more than one value and is current not supported`);
}
if (Array.isArray(value)) {
flattenedFields[key] = value.join(',');
}
else {
flattenedFields[key] = value !== null && value !== void 0 ? value : '';
}
});
return flattenedFields;
};
this.flattenFiles = (files) => {
const flattenedFiles = {};
Object.entries(files)
.filter(([key, file]) => file !== null)
.forEach(([key, file]) => {
if (Array.isArray(file) && file.length > 1) {
throw new Error(`Field ${key} has more than one file and is currently not supported`);
}
if (Array.isArray(file)) {
const fileContent = this.convertFormidableFileToTrayFile(file[0]);
flattenedFiles[key] = fileContent;
}
});
return flattenedFiles;
};
this.convertFormidableFileToTrayFile = (file) => {
var _a;
return ({
key: file.newFilename,
metadata: {
name: file.newFilename,
contentType: (_a = file.mimetype) !== null && _a !== void 0 ? _a : undefined,
size: file.size,
},
content: stream_1.Readable.from('0'),
});
};
}
}), (error) => new Error(error.message));
flattenFields = (fields) => {
const flattenedFields = {};
Object.entries(fields).forEach(([key, value]) => {
if (Array.isArray(value) && value.length > 1) {
throw new Error(`Field ${key} has more than one value and is current not supported`);
}
if (Array.isArray(value)) {
flattenedFields[key] = value.join(',');
}
else {
flattenedFields[key] = value ?? '';
}
});
return flattenedFields;
};
flattenFiles = (files) => {
const flattenedFiles = {};
Object.entries(files)
.filter(([key, file]) => file !== null)
.forEach(([key, file]) => {
if (Array.isArray(file) && file.length > 1) {
throw new Error(`Field ${key} has more than one file and is currently not supported`);
}
if (Array.isArray(file)) {
const fileContent = this.convertFormidableFileToTrayFile(file[0]);
flattenedFiles[key] = fileContent;
}
});
return flattenedFiles;
};
convertFormidableFileToTrayFile = (file) => ({
key: file.newFilename,
metadata: {
name: file.newFilename,
contentType: file.mimetype ?? undefined,
size: file.size,
},
content: stream_1.Readable.from('0'),
});
}
exports.ExpressHttpController = ExpressHttpController;

@@ -7,4 +7,3 @@ "use strict";

const startServer = (controllers, options) => {
var _a;
const port = (_a = options.port) !== null && _a !== void 0 ? _a : 3000;
const port = options.port ?? 3000;
const app = express();

@@ -11,0 +10,0 @@ const router = express.Router();

{
"name": "@trayio/express",
"version": "3.8.0",
"version": "3.9.0",
"description": "Express extensions and implementations",

@@ -17,3 +17,3 @@ "exports": {

"dependencies": {
"@trayio/commons": "3.8.0",
"@trayio/commons": "3.9.0",
"cors": "2.8.5",

@@ -20,0 +20,0 @@ "express": "4.18.2",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc