@lucaapp/service-utils 1.56.2 → 1.56.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.
@@ -8,7 +8,7 @@ const zod_1 = require("zod");
8
8
  const assert_1 = __importDefault(require("assert"));
9
9
  const http_1 = require("./types/http");
10
10
  const libphonenumber_js_1 = require("libphonenumber-js");
11
- const multer_1 = __importDefault(require("multer"));
11
+ const busboy_1 = __importDefault(require("busboy"));
12
12
  const sendBadContextError = (response, error, debug) => {
13
13
  response.err = error;
14
14
  return response.status(500).send({
@@ -147,22 +147,43 @@ const validateAndSendResponse = async (expressResponse, response, validResponses
147
147
  sendErrorResponse(expressResponse, error, undefined, debug);
148
148
  }
149
149
  };
150
- const upload = (0, multer_1.default)({
151
- storage: multer_1.default.memoryStorage(),
152
- });
153
- function handleFileUpload(request, response) {
150
+ async function stream2buffer(stream) {
154
151
  return new Promise((resolve, reject) => {
155
- upload.single('file')(request, response, err => {
156
- if (err) {
157
- reject(err);
158
- }
159
- else {
160
- if (!request.file) {
161
- return resolve();
162
- }
163
- resolve(request.file);
164
- }
152
+ const buf = [];
153
+ stream.on('data', chunk => buf.push(chunk));
154
+ stream.on('end', () => resolve(Buffer.concat(buf)));
155
+ stream.on('error', error => reject(error));
156
+ });
157
+ }
158
+ function handleFileUpload(request) {
159
+ return new Promise(resolve => {
160
+ const bb = (0, busboy_1.default)({
161
+ headers: request.headers,
162
+ defCharset: 'utf8',
163
+ limits: {
164
+ fileSize: 20 * 1024 * 1024, // 20 mb
165
+ files: 1,
166
+ },
167
+ });
168
+ let file = undefined;
169
+ bb.on('file', async (fieldname, fileStream, filename) => {
170
+ const { encoding, mimetype, filename: name } = filename;
171
+ const originalName = Buffer.from(name, 'latin1').toString('utf8');
172
+ const fileBuffer = await stream2buffer(fileStream);
173
+ file = {
174
+ buffer: fileBuffer,
175
+ originalname: originalName,
176
+ encoding,
177
+ mimetype,
178
+ size: fileBuffer.length,
179
+ fieldname: fieldname,
180
+ filename: name,
181
+ };
182
+ });
183
+ bb.on('finish', () => {
184
+ resolve(file);
165
185
  });
186
+ request.pipe(bb);
166
187
  });
167
188
  }
168
189
  const handleMiddleware = async (middleware, context, request, response, debug) =>
@@ -195,9 +216,9 @@ new Promise(async (resolve) => {
195
216
  const { ip, baseUrl, originalUrl, route, method } = request;
196
217
  let file = undefined;
197
218
  if (request.headers['content-type']?.includes('multipart/form-data')) {
198
- file = await handleFileUpload(request, response);
219
+ file = await handleFileUpload(request);
199
220
  }
200
- // if the header is multipart we should use multer and return a buffer with the content
221
+ // if the header is multipart we should return a buffer with the content
201
222
  const handlerRequest = {
202
223
  body: handlerRequestBody,
203
224
  ...(file && { file }),
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { z } from 'zod';
2
3
  import { ArrayToUnion, ExtractZodOutput, ZodSchemaOuput } from './utils';
3
4
  export type EndpointResponseSchema = {
@@ -6,6 +7,15 @@ export type EndpointResponseSchema = {
6
7
  schema: z.ZodSchema<any> | z.ZodVoid;
7
8
  headers?: Record<string, string>;
8
9
  };
10
+ export type FileUpload = {
11
+ buffer: Buffer;
12
+ originalname: string;
13
+ encoding: string;
14
+ mimetype: string;
15
+ size: number;
16
+ fieldname: string;
17
+ filename: string;
18
+ };
9
19
  export type MiddlewareHandler<TResponseSchema, TRequestBodySchema, TRequestParamsSchema, TRequestQuerySchema, TRequestHeadersSchema, TContextSchema> = (request: {
10
20
  body: ZodSchemaOuput<TRequestBodySchema>;
11
21
  params: ZodSchemaOuput<TRequestParamsSchema>;
@@ -16,7 +26,7 @@ export type MiddlewareHandler<TResponseSchema, TRequestBodySchema, TRequestParam
16
26
  originalUrl: string;
17
27
  path: string;
18
28
  method: string;
19
- file?: Express.Multer.File;
29
+ file?: FileUpload;
20
30
  }, send: (response: ExtractZodOutput<ArrayToUnion<TResponseSchema>>) => void, next: (context?: ZodSchemaOuput<TContextSchema>) => void) => Promise<void>;
21
31
  export type MiddlewareOptions<TResponseSchemas extends ReadonlyArray<EndpointResponseSchema>, TRequestBodySchema, TRequestParamsSchema, TRequestQuerySchema, TRequestHeadersSchema, TContextSchema> = {
22
32
  schemas?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucaapp/service-utils",
3
- "version": "1.56.2",
3
+ "version": "1.56.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -23,11 +23,11 @@
23
23
  "@tsconfig/node18": "1.0.1",
24
24
  "@types/express": "4.17.15",
25
25
  "@types/express-serve-static-core": "^4.17.43",
26
- "@types/multer": "^1.4.11",
27
26
  "@types/node": "18.18.2",
28
27
  "@types/response-time": "^2.3.5",
29
28
  "@types/swagger-ui-express": "4.1.3",
30
29
  "axios": "^1.6.0",
30
+ "busboy": "^1.6.0",
31
31
  "cls-rtracer": "^2.6.2",
32
32
  "express": "4.19.2",
33
33
  "express-async-errors": "3.1.1",
@@ -36,7 +36,6 @@
36
36
  "libphonenumber-js": "1.9.44",
37
37
  "lodash": "^4.17.21",
38
38
  "moment-timezone": "^0.5.44",
39
- "multer": "^1.4.5-lts.1",
40
39
  "negotiator": "^0.6.3",
41
40
  "pino-http": "9.0.0",
42
41
  "prom-client": "14.1.0",
@@ -49,6 +48,7 @@
49
48
  "zod": "3.22.3"
50
49
  },
51
50
  "devDependencies": {
51
+ "@types/busboy": "^1.5.3",
52
52
  "@types/express": "4.17.15",
53
53
  "@types/lodash": "^4.14.187",
54
54
  "@types/negotiator": "^0.6.1",