@nestia/core 4.0.0-dev.20241027-2 → 4.0.0-dev.20241027-4

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 | Promise<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,14 +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
14
  const Singleton_1 = require("../utils/Singleton");
20
15
  const validate_request_form_data_1 = require("./internal/validate_request_form_data");
21
16
  /**
@@ -70,23 +65,18 @@ var TypedFormData;
70
65
  /**
71
66
  * @internal
72
67
  */
73
- function Body(options, props) {
68
+ function Body(factory, props) {
74
69
  if (typeof File === "undefined")
75
70
  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
71
  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));
72
+ const uploader = new Singleton_1.Singleton(() => __awaiter(this, void 0, void 0, function* () { return decode((yield factory()), props); }));
80
73
  return (0, common_1.createParamDecorator)(function TypedFormDataBody(_unknown, context) {
81
74
  return __awaiter(this, void 0, void 0, function* () {
82
75
  const http = context.switchToHttp();
83
76
  const request = http.getRequest();
84
77
  if (isMultipartFormData(request.headers["content-type"]) === false)
85
78
  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({
79
+ const data = yield (yield uploader.get())({
90
80
  request: request,
91
81
  response: http.getResponse(),
92
82
  });
@@ -102,8 +92,8 @@ var TypedFormData;
102
92
  /**
103
93
  * @internal
104
94
  */
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 } : {})))));
95
+ const decode = (multer, props) => {
96
+ const upload = multer.fields(props.files.map((file) => (Object.assign({ name: file.name }, (file.limit === 1 ? { maxCount: 1 } : {})))));
107
97
  const interceptor = (request, response) => new Promise((resolve, reject) => upload(request, response, (error) => {
108
98
  if (error)
109
99
  reject(error);
@@ -124,35 +114,6 @@ const decodeExpress = (options, props) => {
124
114
  return data;
125
115
  });
126
116
  };
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
117
  /**
157
118
  * @internal
158
119
  */
@@ -177,8 +138,4 @@ const isMultipartFormData = (text) => text !== undefined &&
177
138
  .split(";")
178
139
  .map((str) => str.trim())
179
140
  .some((str) => str === "multipart/form-data");
180
- /**
181
- * @internal
182
- */
183
- const isExpressRequest = (request) => request.app !== undefined;
184
141
  //# 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-4",
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-4",
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-4",
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,15 +1,11 @@
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
11
  import { Singleton } from "../utils/Singleton";
@@ -70,17 +66,19 @@ export namespace TypedFormData {
70
66
  *
71
67
  * Much easier and type safer than `@nest.UploadFile()` decorator.
72
68
  *
73
- * @param options Options for the `multer` or `fastify-multer`
69
+ * @param factory Factory function ncreating the `multer` or `fastify-multer`
70
+ * instance. In the factory function, you also can specify the
71
+ * multer composition options like `storage` engine.
74
72
  */
75
- export function Body(
76
- options?: ExpressMulter.Options | FastifyMulter.Options,
73
+ export function Body<Multer extends IMulterBase>(
74
+ factory: () => Multer | Promise<Multer>,
77
75
  ): ParameterDecorator;
78
76
 
79
77
  /**
80
78
  * @internal
81
79
  */
82
80
  export function Body<T extends object>(
83
- options: ExpressMulter.Options | FastifyMulter.Options | undefined,
81
+ factory: () => Promise<IMulterBase>,
84
82
  props?: IRequestFormDataProps<T> | undefined,
85
83
  ): ParameterDecorator {
86
84
  if (typeof File === "undefined")
@@ -88,12 +86,9 @@ export namespace TypedFormData {
88
86
  "Error on TypedFormData.Body(): 'File' class is not supported in the older version of NodeJS. Upgrade the NodeJS to the modern.",
89
87
  );
90
88
  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
- );
89
+ const uploader = new Singleton(async () =>
90
+ decode((await factory()) as ExpressMulter.Multer, props!),
91
+ );
97
92
  return createParamDecorator(async function TypedFormDataBody(
98
93
  _unknown: any,
99
94
  context: ExecutionContext,
@@ -104,11 +99,9 @@ export namespace TypedFormData {
104
99
  throw new BadRequestException(
105
100
  `Request body type is not "multipart/form-data".`,
106
101
  );
107
-
108
- const decoder = isExpressRequest(request)
109
- ? predicator("express").get()
110
- : predicator("fastify").get();
111
- const data: FormData = await decoder({
102
+ const data: FormData = await (
103
+ await uploader.get()
104
+ )({
112
105
  request: request as any,
113
106
  response: http.getResponse(),
114
107
  });
@@ -117,16 +110,27 @@ export namespace TypedFormData {
117
110
  return output;
118
111
  })();
119
112
  }
113
+
114
+ /**
115
+ * Base type of the `multer` or `fastify-multer`.
116
+ */
117
+ export interface IMulterBase {
118
+ single(fieldName: string): any;
119
+ array(fieldName: string, maxCount?: number): any;
120
+ fields(fields: readonly object[]): any;
121
+ any(): any;
122
+ none(): any;
123
+ }
120
124
  }
121
125
 
122
126
  /**
123
127
  * @internal
124
128
  */
125
- const decodeExpress = <T>(
126
- options: ExpressMulter.Options | undefined,
129
+ const decode = <T>(
130
+ multer: ExpressMulter.Multer,
127
131
  props: IRequestFormDataProps<T>,
128
132
  ) => {
129
- const upload = ExpressMulter(options).fields(
133
+ const upload = multer.fields(
130
134
  props!.files.map((file) => ({
131
135
  name: file.name,
132
136
  ...(file.limit === 1 ? { maxCount: 1 } : {}),
@@ -155,52 +159,6 @@ const decodeExpress = <T>(
155
159
  };
156
160
  };
157
161
 
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
162
  /**
205
163
  * @internal
206
164
  */
@@ -235,10 +193,3 @@ const isMultipartFormData = (text?: string): boolean =>
235
193
  .split(";")
236
194
  .map((str) => str.trim())
237
195
  .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;