@nestia/core 4.0.0-dev.20241027-2 → 4.0.0-dev.20241027-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.
@@ -1,5 +1,3 @@
1
- import type * as FastifyMulter from "fastify-multer/lib/interfaces";
2
- import ExpressMulter from "multer";
3
1
  /**
4
2
  * Type safe multipart/form-data decorator.
5
3
  *
@@ -55,7 +53,19 @@ export declare namespace TypedFormData {
55
53
  *
56
54
  * Much easier and type safer than `@nest.UploadFile()` decorator.
57
55
  *
58
- * @param options Options for the `multer` or `fastify-multer`
56
+ * @param factory Factory function ncreating the `multer` or `fastify-multer`
57
+ * instance. In the factory function, you also can specify the
58
+ * multer composition options like `storage` engine.
59
59
  */
60
- function Body(options?: ExpressMulter.Options | FastifyMulter.Options): ParameterDecorator;
60
+ function Body<Multer extends IMulterBase>(factory: () => Multer): ParameterDecorator;
61
+ /**
62
+ * Base type of the `multer` or `fastify-multer`.
63
+ */
64
+ interface IMulterBase {
65
+ single(fieldName: string): any;
66
+ array(fieldName: string, maxCount?: number): any;
67
+ fields(fields: readonly object[]): any;
68
+ any(): any;
69
+ none(): any;
70
+ }
61
71
  }
@@ -8,15 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.TypedFormData = void 0;
16
13
  const common_1 = require("@nestjs/common");
17
- const fastify_multer_1 = __importDefault(require("fastify-multer"));
18
- const multer_1 = __importDefault(require("multer"));
19
- const Singleton_1 = require("../utils/Singleton");
20
14
  const validate_request_form_data_1 = require("./internal/validate_request_form_data");
21
15
  /**
22
16
  * Type safe multipart/form-data decorator.
@@ -70,23 +64,18 @@ var TypedFormData;
70
64
  /**
71
65
  * @internal
72
66
  */
73
- function Body(options, props) {
67
+ function Body(factory, props) {
74
68
  if (typeof File === "undefined")
75
69
  throw new Error("Error on TypedFormData.Body(): 'File' class is not supported in the older version of NodeJS. Upgrade the NodeJS to the modern.");
76
70
  const checker = (0, validate_request_form_data_1.validate_request_form_data)(props);
77
- const predicator = (type) => new Singleton_1.Singleton(() => type === "express"
78
- ? decodeExpress(options, props)
79
- : decodeFastify(options, props));
71
+ const uploader = decode(factory(), props);
80
72
  return (0, common_1.createParamDecorator)(function TypedFormDataBody(_unknown, context) {
81
73
  return __awaiter(this, void 0, void 0, function* () {
82
74
  const http = context.switchToHttp();
83
75
  const request = http.getRequest();
84
76
  if (isMultipartFormData(request.headers["content-type"]) === false)
85
77
  throw new common_1.BadRequestException(`Request body type is not "multipart/form-data".`);
86
- const decoder = isExpressRequest(request)
87
- ? predicator("express").get()
88
- : predicator("fastify").get();
89
- const data = yield decoder({
78
+ const data = yield uploader({
90
79
  request: request,
91
80
  response: http.getResponse(),
92
81
  });
@@ -102,8 +91,8 @@ var TypedFormData;
102
91
  /**
103
92
  * @internal
104
93
  */
105
- const decodeExpress = (options, props) => {
106
- const upload = (0, multer_1.default)(options).fields(props.files.map((file) => (Object.assign({ name: file.name }, (file.limit === 1 ? { maxCount: 1 } : {})))));
94
+ const decode = (multer, props) => {
95
+ const upload = multer.fields(props.files.map((file) => (Object.assign({ name: file.name }, (file.limit === 1 ? { maxCount: 1 } : {})))));
107
96
  const interceptor = (request, response) => new Promise((resolve, reject) => upload(request, response, (error) => {
108
97
  if (error)
109
98
  reject(error);
@@ -124,35 +113,6 @@ const decodeExpress = (options, props) => {
124
113
  return data;
125
114
  });
126
115
  };
127
- /**
128
- * @internal
129
- */
130
- const decodeFastify = (options, props) => {
131
- const fastifyInstance = (0, fastify_multer_1.default)(options);
132
- const upload = fastifyInstance.fields(props.files.map((file) => (Object.assign({ name: file.name }, (file.limit === 1 ? { maxCount: 1 } : {})))));
133
- const interceptor = (request, response) => new Promise((resolve, reject) => upload.call(request.server, request, response, (error) => {
134
- if (error)
135
- reject(error);
136
- else
137
- resolve();
138
- }));
139
- return (socket) => __awaiter(void 0, void 0, void 0, function* () {
140
- if (socket.request.files === undefined ||
141
- (typeof socket.request).files !== "function")
142
- throw new common_1.InternalServerErrorException("Have not configured the `fastify-multer` plugin yet. Inquiry to the backend developer.");
143
- yield interceptor(socket.request, socket.response);
144
- const data = new FormData();
145
- for (const [key, value] of Object.entries(socket.request.body))
146
- if (Array.isArray(value))
147
- for (const elem of value)
148
- data.append(key, String(elem));
149
- else
150
- data.append(key, String(value));
151
- if (socket.request.files)
152
- parseFiles(data)(socket.request.files);
153
- return data;
154
- });
155
- };
156
116
  /**
157
117
  * @internal
158
118
  */
@@ -177,8 +137,4 @@ const isMultipartFormData = (text) => text !== undefined &&
177
137
  .split(";")
178
138
  .map((str) => str.trim())
179
139
  .some((str) => str === "multipart/form-data");
180
- /**
181
- * @internal
182
- */
183
- const isExpressRequest = (request) => request.app !== undefined;
184
140
  //# sourceMappingURL=TypedFormData.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TypedFormData.js","sourceRoot":"","sources":["../../src/decorators/TypedFormData.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TypedFormData.js","sourceRoot":"","sources":["../../src/decorators/TypedFormData.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestia/core",
3
- "version": "4.0.0-dev.20241027-2",
3
+ "version": "4.0.0-dev.20241027-3",
4
4
  "description": "Super-fast validation decorators of NestJS",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -36,16 +36,13 @@
36
36
  },
37
37
  "homepage": "https://nestia.io",
38
38
  "dependencies": {
39
- "@nestia/fetcher": "^4.0.0-dev.20241027-2",
39
+ "@nestia/fetcher": "^4.0.0-dev.20241027-3",
40
40
  "@nestjs/common": ">=7.0.1",
41
41
  "@nestjs/core": ">=7.0.1",
42
42
  "@samchon/openapi": "^2.0.0-dev.20241127-2",
43
- "@types/multer": "^1.4.11",
44
43
  "detect-ts-node": "^1.0.5",
45
- "fastify-multer": "^2.0.3",
46
44
  "get-function-location": "^2.0.0",
47
45
  "glob": "^7.2.0",
48
- "multer": "1.4.5-lts.1",
49
46
  "path-parser": "^6.1.0",
50
47
  "raw-body": "^2.0.0",
51
48
  "reflect-metadata": ">=0.1.12",
@@ -55,7 +52,7 @@
55
52
  "ws": "^7.5.3"
56
53
  },
57
54
  "peerDependencies": {
58
- "@nestia/fetcher": ">=4.0.0-dev.20241027-2",
55
+ "@nestia/fetcher": ">=4.0.0-dev.20241027-3",
59
56
  "@nestjs/common": ">=7.0.1",
60
57
  "@nestjs/core": ">=7.0.1",
61
58
  "reflect-metadata": ">=0.1.12",
@@ -68,6 +65,7 @@
68
65
  "@types/express": "^4.17.15",
69
66
  "@types/glob": "^7.2.0",
70
67
  "@types/inquirer": "^9.0.3",
68
+ "@types/multer": "^1.4.12",
71
69
  "@types/ts-expose-internals": "npm:ts-expose-internals@5.4.5",
72
70
  "@types/ws": "^8.5.10",
73
71
  "@typescript-eslint/eslint-plugin": "^5.46.1",
@@ -1,18 +1,13 @@
1
1
  import {
2
2
  BadRequestException,
3
3
  ExecutionContext,
4
- InternalServerErrorException,
5
4
  createParamDecorator,
6
5
  } from "@nestjs/common";
7
6
  import type { HttpArgumentsHost } from "@nestjs/common/interfaces";
8
7
  import type express from "express";
9
- import type { FastifyReply, FastifyRequest } from "fastify";
10
- import fastifyMulter from "fastify-multer";
11
- import type * as FastifyMulter from "fastify-multer/lib/interfaces";
12
- import ExpressMulter from "multer";
8
+ import type ExpressMulter from "multer";
13
9
 
14
10
  import type { IRequestFormDataProps } from "../options/IRequestFormDataProps";
15
- import { Singleton } from "../utils/Singleton";
16
11
  import { validate_request_form_data } from "./internal/validate_request_form_data";
17
12
 
18
13
  /**
@@ -70,17 +65,19 @@ export namespace TypedFormData {
70
65
  *
71
66
  * Much easier and type safer than `@nest.UploadFile()` decorator.
72
67
  *
73
- * @param options Options for the `multer` or `fastify-multer`
68
+ * @param factory Factory function ncreating the `multer` or `fastify-multer`
69
+ * instance. In the factory function, you also can specify the
70
+ * multer composition options like `storage` engine.
74
71
  */
75
- export function Body(
76
- options?: ExpressMulter.Options | FastifyMulter.Options,
72
+ export function Body<Multer extends IMulterBase>(
73
+ factory: () => Multer,
77
74
  ): ParameterDecorator;
78
75
 
79
76
  /**
80
77
  * @internal
81
78
  */
82
79
  export function Body<T extends object>(
83
- options: ExpressMulter.Options | FastifyMulter.Options | undefined,
80
+ factory: () => IMulterBase,
84
81
  props?: IRequestFormDataProps<T> | undefined,
85
82
  ): ParameterDecorator {
86
83
  if (typeof File === "undefined")
@@ -88,12 +85,7 @@ export namespace TypedFormData {
88
85
  "Error on TypedFormData.Body(): 'File' class is not supported in the older version of NodeJS. Upgrade the NodeJS to the modern.",
89
86
  );
90
87
  const checker = validate_request_form_data(props);
91
- const predicator = (type: "express" | "fastify") =>
92
- new Singleton(() =>
93
- type === "express"
94
- ? decodeExpress(options as ExpressMulter.Options | undefined, props!)
95
- : decodeFastify(options as FastifyMulter.Options | undefined, props!),
96
- );
88
+ const uploader = decode(factory() as ExpressMulter.Multer, props!);
97
89
  return createParamDecorator(async function TypedFormDataBody(
98
90
  _unknown: any,
99
91
  context: ExecutionContext,
@@ -104,11 +96,7 @@ export namespace TypedFormData {
104
96
  throw new BadRequestException(
105
97
  `Request body type is not "multipart/form-data".`,
106
98
  );
107
-
108
- const decoder = isExpressRequest(request)
109
- ? predicator("express").get()
110
- : predicator("fastify").get();
111
- const data: FormData = await decoder({
99
+ const data: FormData = await uploader({
112
100
  request: request as any,
113
101
  response: http.getResponse(),
114
102
  });
@@ -117,16 +105,27 @@ export namespace TypedFormData {
117
105
  return output;
118
106
  })();
119
107
  }
108
+
109
+ /**
110
+ * Base type of the `multer` or `fastify-multer`.
111
+ */
112
+ export interface IMulterBase {
113
+ single(fieldName: string): any;
114
+ array(fieldName: string, maxCount?: number): any;
115
+ fields(fields: readonly object[]): any;
116
+ any(): any;
117
+ none(): any;
118
+ }
120
119
  }
121
120
 
122
121
  /**
123
122
  * @internal
124
123
  */
125
- const decodeExpress = <T>(
126
- options: ExpressMulter.Options | undefined,
124
+ const decode = <T>(
125
+ multer: ExpressMulter.Multer,
127
126
  props: IRequestFormDataProps<T>,
128
127
  ) => {
129
- const upload = ExpressMulter(options).fields(
128
+ const upload = multer.fields(
130
129
  props!.files.map((file) => ({
131
130
  name: file.name,
132
131
  ...(file.limit === 1 ? { maxCount: 1 } : {}),
@@ -155,52 +154,6 @@ const decodeExpress = <T>(
155
154
  };
156
155
  };
157
156
 
158
- /**
159
- * @internal
160
- */
161
- const decodeFastify = <T>(
162
- options: FastifyMulter.Options | undefined,
163
- props: IRequestFormDataProps<T>,
164
- ) => {
165
- const fastifyInstance = fastifyMulter(options);
166
- const upload = fastifyInstance.fields(
167
- props!.files.map((file) => ({
168
- name: file.name,
169
- ...(file.limit === 1 ? { maxCount: 1 } : {}),
170
- })),
171
- );
172
- const interceptor = (request: FastifyRequest, response: FastifyReply) =>
173
- new Promise<void>((resolve, reject) =>
174
- upload.call(request.server, request, response, (error) => {
175
- if (error) reject(error);
176
- else resolve();
177
- }),
178
- );
179
- return async (socket: {
180
- request: FastifyRequest;
181
- response: FastifyReply;
182
- }): Promise<FormData> => {
183
- if (
184
- (socket.request as any).files === undefined ||
185
- (typeof socket.request as any).files !== "function"
186
- )
187
- throw new InternalServerErrorException(
188
- "Have not configured the `fastify-multer` plugin yet. Inquiry to the backend developer.",
189
- );
190
-
191
- await interceptor(socket.request, socket.response);
192
-
193
- const data: FormData = new FormData();
194
- for (const [key, value] of Object.entries(socket.request.body as any))
195
- if (Array.isArray(value))
196
- for (const elem of value) data.append(key, String(elem));
197
- else data.append(key, String(value));
198
- if ((socket.request as any).files)
199
- parseFiles(data)((socket.request as any).files);
200
- return data;
201
- };
202
- };
203
-
204
157
  /**
205
158
  * @internal
206
159
  */
@@ -235,10 +188,3 @@ const isMultipartFormData = (text?: string): boolean =>
235
188
  .split(";")
236
189
  .map((str) => str.trim())
237
190
  .some((str) => str === "multipart/form-data");
238
-
239
- /**
240
- * @internal
241
- */
242
- const isExpressRequest = (
243
- request: express.Request | FastifyRequest,
244
- ): request is express.Request => (request as express.Request).app !== undefined;