@nestia/core 2.5.3-dev.20240204 → 2.5.4-dev.20240204
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.
- package/lib/decorators/TypedFormData.d.ts +25 -10
- package/lib/decorators/TypedFormData.js +197 -60
- package/lib/decorators/TypedFormData.js.map +1 -1
- package/lib/decorators/internal/validate_request_form_data.d.ts +3 -0
- package/lib/decorators/internal/{validate_request_multipart.js → validate_request_form_data.js} +4 -4
- package/lib/decorators/internal/{validate_request_multipart.js.map → validate_request_form_data.js.map} +1 -1
- package/lib/options/{IRequestMulltipartProps.d.ts → IRequestFormDataProps.d.ts} +4 -4
- package/lib/options/{IRequestMulltipartProps.js → IRequestFormDataProps.js} +1 -1
- package/lib/options/IRequestFormDataProps.js.map +1 -0
- package/lib/programmers/TypedFormDataBodyProgrammer.js.map +1 -1
- package/package.json +6 -5
- package/src/decorators/TypedFormData.ts +111 -47
- package/src/decorators/internal/{validate_request_multipart.ts → validate_request_form_data.ts} +3 -3
- package/src/options/{IRequestMulltipartProps.ts → IRequestFormDataProps.ts} +6 -6
- package/src/programmers/TypedFormDataBodyProgrammer.ts +3 -3
- package/lib/decorators/internal/validate_request_multipart.d.ts +0 -3
- package/lib/options/IRequestMulltipartProps.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { IRequestFormDataProps } from "../options/IRequestFormDataProps";
|
|
2
2
|
/**
|
|
3
3
|
* Type safe multipart/form-data decorator.
|
|
4
4
|
*
|
|
@@ -19,7 +19,29 @@ import { IRequestMultipartProps } from "../options/IRequestMulltipartProps";
|
|
|
19
19
|
* 2. Do not allow dynamic property
|
|
20
20
|
* 3. Only `boolean`, `bigint`, `number`, `string`, `Blob`, `File` or their array types are allowed
|
|
21
21
|
* 4. By the way, union type never be not allowed
|
|
22
|
-
*
|
|
22
|
+
*
|
|
23
|
+
* By the way, if you're using `fastify`, you have to setup `@fastify/multipart`
|
|
24
|
+
* and configure like below when composing the NestJS application. If you don't do
|
|
25
|
+
* that, `@TypedFormData.Body()` will not work properly, and throw 500 internal
|
|
26
|
+
* server error when `Blob` or `File` type being utilized.
|
|
27
|
+
*
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import multipart from "fastify-multipart";
|
|
30
|
+
* import { NestFactory } from "@nestjs/core";
|
|
31
|
+
* import {
|
|
32
|
+
* FastifyAdapter,
|
|
33
|
+
* NestFastifyApplication
|
|
34
|
+
* } from "@nestjs/platform-fastify";
|
|
35
|
+
*
|
|
36
|
+
* export async function main() {
|
|
37
|
+
* const app = await NestFactory.create<NestFastifyApplication>(
|
|
38
|
+
* AppModule,
|
|
39
|
+
* new FastifyAdapter(),
|
|
40
|
+
* );
|
|
41
|
+
* app.register(multipart);
|
|
42
|
+
* await app.listen(3000);
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
23
45
|
*
|
|
24
46
|
* @todo Change to ReadableStream through configuring storage engine of multer
|
|
25
47
|
* @author Jeongho Nam - https://github.com/samchon
|
|
@@ -34,12 +56,5 @@ export declare namespace TypedFormData {
|
|
|
34
56
|
*
|
|
35
57
|
* @param props Automatically filled by transformer
|
|
36
58
|
*/
|
|
37
|
-
function Body<T extends object>(props?:
|
|
38
|
-
interface IProps<T> {
|
|
39
|
-
files: Array<{
|
|
40
|
-
name: string;
|
|
41
|
-
limit: number | null;
|
|
42
|
-
}>;
|
|
43
|
-
validator: IRequestMultipartProps<T>;
|
|
44
|
-
}
|
|
59
|
+
function Body<T extends object>(props?: IRequestFormDataProps<T>): ParameterDecorator;
|
|
45
60
|
}
|
|
@@ -46,6 +46,13 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
50
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
51
|
+
var m = o[Symbol.asyncIterator], i;
|
|
52
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
53
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
54
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
55
|
+
};
|
|
49
56
|
var __values = (this && this.__values) || function(o) {
|
|
50
57
|
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
51
58
|
if (m) return m.call(o);
|
|
@@ -82,7 +89,7 @@ var common_1 = require("@nestjs/common");
|
|
|
82
89
|
var multer_1 = __importDefault(require("multer"));
|
|
83
90
|
var typia_1 = __importDefault(require("typia"));
|
|
84
91
|
var Singleton_1 = require("../utils/Singleton");
|
|
85
|
-
var
|
|
92
|
+
var validate_request_form_data_1 = require("./internal/validate_request_form_data");
|
|
86
93
|
/**
|
|
87
94
|
* Type safe multipart/form-data decorator.
|
|
88
95
|
*
|
|
@@ -103,7 +110,29 @@ var validate_request_multipart_1 = require("./internal/validate_request_multipar
|
|
|
103
110
|
* 2. Do not allow dynamic property
|
|
104
111
|
* 3. Only `boolean`, `bigint`, `number`, `string`, `Blob`, `File` or their array types are allowed
|
|
105
112
|
* 4. By the way, union type never be not allowed
|
|
106
|
-
*
|
|
113
|
+
*
|
|
114
|
+
* By the way, if you're using `fastify`, you have to setup `@fastify/multipart`
|
|
115
|
+
* and configure like below when composing the NestJS application. If you don't do
|
|
116
|
+
* that, `@TypedFormData.Body()` will not work properly, and throw 500 internal
|
|
117
|
+
* server error when `Blob` or `File` type being utilized.
|
|
118
|
+
*
|
|
119
|
+
* ```typescript
|
|
120
|
+
* import multipart from "fastify-multipart";
|
|
121
|
+
* import { NestFactory } from "@nestjs/core";
|
|
122
|
+
* import {
|
|
123
|
+
* FastifyAdapter,
|
|
124
|
+
* NestFastifyApplication
|
|
125
|
+
* } from "@nestjs/platform-fastify";
|
|
126
|
+
*
|
|
127
|
+
* export async function main() {
|
|
128
|
+
* const app = await NestFactory.create<NestFastifyApplication>(
|
|
129
|
+
* AppModule,
|
|
130
|
+
* new FastifyAdapter(),
|
|
131
|
+
* );
|
|
132
|
+
* app.register(multipart);
|
|
133
|
+
* await app.listen(3000);
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
107
136
|
*
|
|
108
137
|
* @todo Change to ReadableStream through configuring storage engine of multer
|
|
109
138
|
* @author Jeongho Nam - https://github.com/samchon
|
|
@@ -120,60 +149,31 @@ var TypedFormData;
|
|
|
120
149
|
* @param props Automatically filled by transformer
|
|
121
150
|
*/
|
|
122
151
|
function Body(props) {
|
|
123
|
-
var checker = (0,
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return upload(request, response, function (error) {
|
|
128
|
-
if (error)
|
|
129
|
-
reject(error);
|
|
130
|
-
else
|
|
131
|
-
resolve();
|
|
132
|
-
});
|
|
152
|
+
var checker = (0, validate_request_form_data_1.validate_request_form_data)(props);
|
|
153
|
+
var predicator = function (type) {
|
|
154
|
+
return new Singleton_1.Singleton(function () {
|
|
155
|
+
return type === "express" ? decodeExpress(props) : decodeFastify(props);
|
|
133
156
|
});
|
|
134
157
|
};
|
|
135
158
|
return (0, common_1.createParamDecorator)(function TypedFormDataBody(_unknown, context) {
|
|
136
159
|
return __awaiter(this, void 0, void 0, function () {
|
|
137
|
-
var http, request,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
switch (_h.label) {
|
|
160
|
+
var http, request, decoder, data, output;
|
|
161
|
+
return __generator(this, function (_a) {
|
|
162
|
+
switch (_a.label) {
|
|
141
163
|
case 0:
|
|
142
164
|
http = context.switchToHttp();
|
|
143
165
|
request = http.getRequest();
|
|
144
166
|
if (isMultipartFormData(request.headers["content-type"]) === false)
|
|
145
|
-
throw new common_1.BadRequestException("Request body type is not \"
|
|
146
|
-
|
|
167
|
+
throw new common_1.BadRequestException("Request body type is not \"multipart/form-data\".");
|
|
168
|
+
decoder = isExpressRequest(request)
|
|
169
|
+
? predicator("express").get()
|
|
170
|
+
: predicator("fastify").get();
|
|
171
|
+
return [4 /*yield*/, decoder({
|
|
172
|
+
request: request,
|
|
173
|
+
response: http.getResponse(),
|
|
174
|
+
})];
|
|
147
175
|
case 1:
|
|
148
|
-
|
|
149
|
-
data = new FormData();
|
|
150
|
-
try {
|
|
151
|
-
for (_a = __values(Object.entries(request.body)), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
152
|
-
_c = __read(_b.value, 2), key = _c[0], value = _c[1];
|
|
153
|
-
try {
|
|
154
|
-
for (_d = (e_2 = void 0, __values(String(value).split(","))), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
155
|
-
elem = _e.value;
|
|
156
|
-
data.append(key, elem);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
160
|
-
finally {
|
|
161
|
-
try {
|
|
162
|
-
if (_e && !_e.done && (_g = _d.return)) _g.call(_d);
|
|
163
|
-
}
|
|
164
|
-
finally { if (e_2) throw e_2.error; }
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
169
|
-
finally {
|
|
170
|
-
try {
|
|
171
|
-
if (_b && !_b.done && (_f = _a.return)) _f.call(_a);
|
|
172
|
-
}
|
|
173
|
-
finally { if (e_1) throw e_1.error; }
|
|
174
|
-
}
|
|
175
|
-
if (request.files)
|
|
176
|
-
parseFiles(data)(request.files);
|
|
176
|
+
data = _a.sent();
|
|
177
177
|
output = checker(data);
|
|
178
178
|
if (output instanceof Error)
|
|
179
179
|
throw output;
|
|
@@ -188,12 +188,148 @@ var TypedFormData;
|
|
|
188
188
|
Object.assign(Body, typia_1.default.http.isFormData);
|
|
189
189
|
Object.assign(Body, typia_1.default.http.validateFormData);
|
|
190
190
|
})(TypedFormData || (exports.TypedFormData = TypedFormData = {}));
|
|
191
|
+
var decodeExpress = function (props) {
|
|
192
|
+
var upload = multerApplication.get().fields(props.files.map(function (file) { return (__assign({ name: file.name }, (file.limit === 1 ? { maxCount: 1 } : {}))); }));
|
|
193
|
+
var interceptor = function (request, response) {
|
|
194
|
+
return new Promise(function (resolve, reject) {
|
|
195
|
+
return upload(request, response, function (error) {
|
|
196
|
+
if (error)
|
|
197
|
+
reject(error);
|
|
198
|
+
else
|
|
199
|
+
resolve();
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
return function (socket) { return __awaiter(void 0, void 0, void 0, function () {
|
|
204
|
+
var data, _a, _b, _c, key, value, _d, _e, elem;
|
|
205
|
+
var e_1, _f, e_2, _g;
|
|
206
|
+
return __generator(this, function (_h) {
|
|
207
|
+
switch (_h.label) {
|
|
208
|
+
case 0: return [4 /*yield*/, interceptor(socket.request, socket.response)];
|
|
209
|
+
case 1:
|
|
210
|
+
_h.sent();
|
|
211
|
+
data = new FormData();
|
|
212
|
+
try {
|
|
213
|
+
for (_a = __values(Object.entries(socket.request.body)), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
214
|
+
_c = __read(_b.value, 2), key = _c[0], value = _c[1];
|
|
215
|
+
try {
|
|
216
|
+
for (_d = (e_2 = void 0, __values(String(value).split(","))), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
217
|
+
elem = _e.value;
|
|
218
|
+
data.append(key, elem);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
222
|
+
finally {
|
|
223
|
+
try {
|
|
224
|
+
if (_e && !_e.done && (_g = _d.return)) _g.call(_d);
|
|
225
|
+
}
|
|
226
|
+
finally { if (e_2) throw e_2.error; }
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
231
|
+
finally {
|
|
232
|
+
try {
|
|
233
|
+
if (_b && !_b.done && (_f = _a.return)) _f.call(_a);
|
|
234
|
+
}
|
|
235
|
+
finally { if (e_1) throw e_1.error; }
|
|
236
|
+
}
|
|
237
|
+
if (socket.request.files)
|
|
238
|
+
parseFiles(data)(socket.request.files);
|
|
239
|
+
return [2 /*return*/, data];
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}); };
|
|
243
|
+
};
|
|
244
|
+
var decodeFastify = function (_props) {
|
|
245
|
+
return function (socket) { return __awaiter(void 0, void 0, void 0, function () {
|
|
246
|
+
var data, _a, _b, _c, key, value, _d, _e, elem, _f, _g, _h, file, _j, _k, _l, _m, e_3_1;
|
|
247
|
+
var e_4, _o, e_5, _p;
|
|
248
|
+
var _q, e_3, _r, _s;
|
|
249
|
+
var _t;
|
|
250
|
+
return __generator(this, function (_u) {
|
|
251
|
+
switch (_u.label) {
|
|
252
|
+
case 0:
|
|
253
|
+
if (socket.request.files === undefined ||
|
|
254
|
+
typeof socket.request.files !== "function")
|
|
255
|
+
throw new common_1.InternalServerErrorException("Have not configured the `fastify-multipart` plugin yet. Inquiry to the backend developer.");
|
|
256
|
+
data = new FormData();
|
|
257
|
+
try {
|
|
258
|
+
for (_a = __values(Object.entries((_t = socket.request.body) !== null && _t !== void 0 ? _t : {})), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
259
|
+
_c = __read(_b.value, 2), key = _c[0], value = _c[1];
|
|
260
|
+
try {
|
|
261
|
+
for (_d = (e_5 = void 0, __values(String(value).split(","))), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
262
|
+
elem = _e.value;
|
|
263
|
+
data.append(key, elem);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
267
|
+
finally {
|
|
268
|
+
try {
|
|
269
|
+
if (_e && !_e.done && (_p = _d.return)) _p.call(_d);
|
|
270
|
+
}
|
|
271
|
+
finally { if (e_5) throw e_5.error; }
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
276
|
+
finally {
|
|
277
|
+
try {
|
|
278
|
+
if (_b && !_b.done && (_o = _a.return)) _o.call(_a);
|
|
279
|
+
}
|
|
280
|
+
finally { if (e_4) throw e_4.error; }
|
|
281
|
+
}
|
|
282
|
+
_u.label = 1;
|
|
283
|
+
case 1:
|
|
284
|
+
_u.trys.push([1, 7, 8, 13]);
|
|
285
|
+
_f = true, _g = __asyncValues(socket.request.files());
|
|
286
|
+
_u.label = 2;
|
|
287
|
+
case 2: return [4 /*yield*/, _g.next()];
|
|
288
|
+
case 3:
|
|
289
|
+
if (!(_h = _u.sent(), _q = _h.done, !_q)) return [3 /*break*/, 6];
|
|
290
|
+
_s = _h.value;
|
|
291
|
+
_f = false;
|
|
292
|
+
file = _s;
|
|
293
|
+
_k = (_j = data).append;
|
|
294
|
+
_l = [file.fieldname];
|
|
295
|
+
_m = File.bind;
|
|
296
|
+
return [4 /*yield*/, file.toBuffer()];
|
|
297
|
+
case 4:
|
|
298
|
+
_k.apply(_j, _l.concat([new (_m.apply(File, [void 0, [_u.sent()], file.filename, {
|
|
299
|
+
type: file.mimetype,
|
|
300
|
+
}]))()]));
|
|
301
|
+
_u.label = 5;
|
|
302
|
+
case 5:
|
|
303
|
+
_f = true;
|
|
304
|
+
return [3 /*break*/, 2];
|
|
305
|
+
case 6: return [3 /*break*/, 13];
|
|
306
|
+
case 7:
|
|
307
|
+
e_3_1 = _u.sent();
|
|
308
|
+
e_3 = { error: e_3_1 };
|
|
309
|
+
return [3 /*break*/, 13];
|
|
310
|
+
case 8:
|
|
311
|
+
_u.trys.push([8, , 11, 12]);
|
|
312
|
+
if (!(!_f && !_q && (_r = _g.return))) return [3 /*break*/, 10];
|
|
313
|
+
return [4 /*yield*/, _r.call(_g)];
|
|
314
|
+
case 9:
|
|
315
|
+
_u.sent();
|
|
316
|
+
_u.label = 10;
|
|
317
|
+
case 10: return [3 /*break*/, 12];
|
|
318
|
+
case 11:
|
|
319
|
+
if (e_3) throw e_3.error;
|
|
320
|
+
return [7 /*endfinally*/];
|
|
321
|
+
case 12: return [7 /*endfinally*/];
|
|
322
|
+
case 13: return [2 /*return*/, data];
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}); };
|
|
326
|
+
};
|
|
191
327
|
/**
|
|
192
328
|
* @internal
|
|
193
329
|
*/
|
|
194
330
|
var parseFiles = function (data) {
|
|
195
331
|
return function (files) {
|
|
196
|
-
var
|
|
332
|
+
var e_6, _a, e_7, _b, e_8, _c;
|
|
197
333
|
if (Array.isArray(files))
|
|
198
334
|
try {
|
|
199
335
|
for (var files_1 = __values(files), files_1_1 = files_1.next(); !files_1_1.done; files_1_1 = files_1.next()) {
|
|
@@ -203,55 +339,56 @@ var parseFiles = function (data) {
|
|
|
203
339
|
}));
|
|
204
340
|
}
|
|
205
341
|
}
|
|
206
|
-
catch (
|
|
342
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
207
343
|
finally {
|
|
208
344
|
try {
|
|
209
345
|
if (files_1_1 && !files_1_1.done && (_a = files_1.return)) _a.call(files_1);
|
|
210
346
|
}
|
|
211
|
-
finally { if (
|
|
347
|
+
finally { if (e_6) throw e_6.error; }
|
|
212
348
|
}
|
|
213
349
|
else
|
|
214
350
|
try {
|
|
215
351
|
for (var _d = __values(Object.entries(files)), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
216
352
|
var _f = __read(_e.value, 2), key = _f[0], value = _f[1];
|
|
217
353
|
try {
|
|
218
|
-
for (var value_1 = (
|
|
354
|
+
for (var value_1 = (e_8 = void 0, __values(value)), value_1_1 = value_1.next(); !value_1_1.done; value_1_1 = value_1.next()) {
|
|
219
355
|
var file = value_1_1.value;
|
|
220
356
|
data.append(key, new File([file.buffer], file.originalname, {
|
|
221
357
|
type: file.mimetype,
|
|
222
358
|
}));
|
|
223
359
|
}
|
|
224
360
|
}
|
|
225
|
-
catch (
|
|
361
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
226
362
|
finally {
|
|
227
363
|
try {
|
|
228
364
|
if (value_1_1 && !value_1_1.done && (_c = value_1.return)) _c.call(value_1);
|
|
229
365
|
}
|
|
230
|
-
finally { if (
|
|
366
|
+
finally { if (e_8) throw e_8.error; }
|
|
231
367
|
}
|
|
232
368
|
}
|
|
233
369
|
}
|
|
234
|
-
catch (
|
|
370
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
235
371
|
finally {
|
|
236
372
|
try {
|
|
237
373
|
if (_e && !_e.done && (_b = _d.return)) _b.call(_d);
|
|
238
374
|
}
|
|
239
|
-
finally { if (
|
|
375
|
+
finally { if (e_7) throw e_7.error; }
|
|
240
376
|
}
|
|
241
377
|
};
|
|
242
378
|
};
|
|
243
379
|
/**
|
|
244
380
|
* @internal
|
|
245
381
|
*/
|
|
246
|
-
function
|
|
247
|
-
return
|
|
382
|
+
var isMultipartFormData = function (text) {
|
|
383
|
+
return text !== undefined &&
|
|
248
384
|
text
|
|
249
385
|
.split(";")
|
|
250
386
|
.map(function (str) { return str.trim(); })
|
|
251
|
-
.some(function (str) { return str === "multipart/form-data"; })
|
|
252
|
-
}
|
|
387
|
+
.some(function (str) { return str === "multipart/form-data"; });
|
|
388
|
+
};
|
|
389
|
+
var isExpressRequest = function (request) { return request.app !== undefined; };
|
|
253
390
|
/**
|
|
254
391
|
* @internal
|
|
255
392
|
*/
|
|
256
|
-
var
|
|
393
|
+
var multerApplication = new Singleton_1.Singleton(function () { return (0, multer_1.default)(); });
|
|
257
394
|
//# sourceMappingURL=TypedFormData.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypedFormData.js","sourceRoot":"","sources":["../../src/decorators/TypedFormData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TypedFormData.js","sourceRoot":"","sources":["../../src/decorators/TypedFormData.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { BadRequestException } from "@nestjs/common";
|
|
2
|
+
import { IRequestFormDataProps } from "../../options/IRequestFormDataProps";
|
|
3
|
+
export declare const validate_request_form_data: <T>(props?: IRequestFormDataProps<T> | undefined) => (() => Error) | ((input: FormData) => BadRequestException | T);
|
package/lib/decorators/internal/{validate_request_multipart.js → validate_request_form_data.js}
RENAMED
|
@@ -3,11 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.validate_request_form_data = void 0;
|
|
7
7
|
var common_1 = require("@nestjs/common");
|
|
8
8
|
var typia_1 = __importDefault(require("typia"));
|
|
9
9
|
var NoTransformConfigureError_1 = require("./NoTransformConfigureError");
|
|
10
|
-
var
|
|
10
|
+
var validate_request_form_data = function (props) {
|
|
11
11
|
if (!props)
|
|
12
12
|
return function () { return (0, NoTransformConfigureError_1.NoTransformConfigureError)("TypedFormData.Bpdu"); };
|
|
13
13
|
else if (props.validator.type === "assert")
|
|
@@ -20,7 +20,7 @@ var validate_request_multipart = function (props) {
|
|
|
20
20
|
return new Error("Error on nestia.core.TypedFormData.Body(): invalid typed validator.");
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
|
-
exports.
|
|
23
|
+
exports.validate_request_form_data = validate_request_form_data;
|
|
24
24
|
var assert = function (closure) {
|
|
25
25
|
return function (input) {
|
|
26
26
|
try {
|
|
@@ -61,4 +61,4 @@ var validate = function (closure) {
|
|
|
61
61
|
};
|
|
62
62
|
};
|
|
63
63
|
var MESSAGE = "Request multipart data is not following the promised type.";
|
|
64
|
-
//# sourceMappingURL=
|
|
64
|
+
//# sourceMappingURL=validate_request_form_data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"
|
|
1
|
+
{"version":3,"file":"validate_request_form_data.js","sourceRoot":"","sources":["../../../src/decorators/internal/validate_request_form_data.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAqD;AACrD,gDAA2D;AAG3D,yEAAwE;AAEjE,IAAM,0BAA0B,GAAG,UACxC,KAAgC;IAEhC,IAAI,CAAC,KAAK;QAAE,OAAO,cAAM,OAAA,IAAA,qDAAyB,EAAC,oBAAoB,CAAC,EAA/C,CAA+C,CAAC;SACpE,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,QAAQ;QACxC,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;SACnC,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;SACjE,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU;QAC1C,OAAO,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO;QACL,OAAA,IAAI,KAAK,CACP,qEAAqE,CACtE;IAFD,CAEC,CAAC;AACN,CAAC,CAAC;AAbW,QAAA,0BAA0B,8BAarC;AAEF,IAAM,MAAM,GACV,UAAI,OAA+B;IACnC,OAAA,UAAC,KAAe;QACd,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb;;;eAA6B,GAAG,GAAG,CAAC;gBAClC,OAAO,IAAI,4BAAmB,CAAC;oBAC7B,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,MAAM,EAAE,GAAG,CAAC,OAAO;oBACnB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AAfD,CAeC,CAAC;AAEJ,IAAM,EAAE,GACN,UAAI,OAAsC;IAC1C,OAAA,UAAC,KAAe;QACd,IAAM,MAAM,GAAa,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,4BAAmB,CAAC,OAAO,CAAC,CAAC;IACrE,CAAC;AAHD,CAGC,CAAC;AAEJ,IAAM,QAAQ,GACZ,UAAI,OAA4C;IAChD,OAAA,UAAC,KAAe;QACd,IAAM,MAAM,GAAmB,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC,OAAO;YACnB,CAAC,CAAC,MAAM,CAAC,IAAI;YACb,CAAC,CAAC,IAAI,4BAAmB,CAAC;gBACtB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;IACT,CAAC;AARD,CAQC,CAAC;AAEJ,IAAM,OAAO,GAAG,4DAA4D,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { IValidation } from "typia";
|
|
2
|
-
export interface
|
|
3
|
-
files: Array<
|
|
4
|
-
validator:
|
|
2
|
+
export interface IRequestFormDataProps<T> {
|
|
3
|
+
files: Array<IRequestFormDataProps.IFile>;
|
|
4
|
+
validator: IRequestFormDataProps.IAssert<T> | IRequestFormDataProps.IIs<T> | IRequestFormDataProps.IValidate<T>;
|
|
5
5
|
}
|
|
6
|
-
export declare namespace
|
|
6
|
+
export declare namespace IRequestFormDataProps {
|
|
7
7
|
interface IAssert<T> {
|
|
8
8
|
type: "assert";
|
|
9
9
|
assert: (input: FormData) => T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IRequestFormDataProps.js","sourceRoot":"","sources":["../../src/options/IRequestFormDataProps.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypedFormDataBodyProgrammer.js","sourceRoot":"","sources":["../../src/programmers/TypedFormDataBodyProgrammer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0DAA4B;AAC5B,qEAAoE;AACpE,6EAA4E;AAC5E,uEAAsE;AACtE,wGAAuG;AACvG,4FAA2F;AAC3F,gGAA+F;AAC/F,4GAA2G;AAG3G,4EAA2E;AAK3E,IAAiB,2BAA2B,CAyF3C;AAzFD,WAAiB,2BAA2B;IAC7B,oCAAQ,GACnB,UAAC,OAAgC;QACjC,OAAA,UAAC,MAAiC;YAClC,OAAA,UAAC,IAAa;gBACZ,gBAAgB;gBAChB,IAAM,UAAU,GAAuB,IAAI,uCAAkB,EAAE,CAAC;gBAChE,IAAM,MAAM,GAAG,iCAAe,CAAC,OAAO,CACpC,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,OAAO,CAChB,CAAC;oBACA,MAAM,EAAE,KAAK;oBACb,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,IAAI;oBACZ,QAAQ,EAAE,+CAAsB,CAAC,QAAQ;iBAC1C,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrB,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK;oBAC1B,MAAM,mCAAgB,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAC3D,MAAM,CAAC,MAAM,CACd,CAAC;gBAEJ,IAAM,KAAK,GACT,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU;qBAC9B,MAAM,CACL,UAAC,CAAC;oBACA,OAAA,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;wBACf,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAC,CAAC,IAAK,OAAA,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAApB,CAAoB,CAAC;gBADhD,CACgD,CACnD;qBACA,GAAG,CAAC,UAAC,CAAC,IAAK,OAAA,CAAC;oBACX,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAW;oBAC5C,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;iBAC3C,CAAC,EAHU,CAGV,CAAC,CAAC;gBAER,2BAA2B;gBAC3B,IAAM,SAAS,GACb,UAAC,
|
|
1
|
+
{"version":3,"file":"TypedFormDataBodyProgrammer.js","sourceRoot":"","sources":["../../src/programmers/TypedFormDataBodyProgrammer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestia/core",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.4-dev.20240204",
|
|
4
4
|
"description": "Super-fast validation decorators of NestJS",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://nestia.io",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@nestia/fetcher": "^2.5.
|
|
39
|
+
"@nestia/fetcher": "^2.5.4-dev.20240204",
|
|
40
40
|
"@nestjs/common": ">=7.0.1",
|
|
41
41
|
"@nestjs/core": ">=7.0.1",
|
|
42
42
|
"@nestjs/platform-express": ">=7.0.1",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"raw-body": ">=2.0.0",
|
|
48
48
|
"reflect-metadata": ">=0.1.12",
|
|
49
49
|
"rxjs": ">=6.0.0",
|
|
50
|
-
"typia": "^5.4.
|
|
50
|
+
"typia": "^5.4.5"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@nestia/fetcher": ">=2.5.
|
|
53
|
+
"@nestia/fetcher": ">=2.5.4-dev.20240204",
|
|
54
54
|
"@nestjs/common": ">=7.0.1",
|
|
55
55
|
"@nestjs/core": ">=7.0.1",
|
|
56
56
|
"@nestjs/platform-express": ">=7.0.1",
|
|
@@ -58,9 +58,10 @@
|
|
|
58
58
|
"raw-body": ">=2.0.0",
|
|
59
59
|
"reflect-metadata": ">=0.1.12",
|
|
60
60
|
"rxjs": ">=6.0.0",
|
|
61
|
-
"typia": ">=5.4.
|
|
61
|
+
"typia": ">=5.4.5 <6.0.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
+
"@fastify/multipart": "^8.1.0",
|
|
64
65
|
"@types/express": "^4.17.15",
|
|
65
66
|
"@types/glob": "^7.2.0",
|
|
66
67
|
"@types/inquirer": "^9.0.3",
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import type { MultipartFile } from "@fastify/multipart";
|
|
1
2
|
import {
|
|
2
3
|
BadRequestException,
|
|
3
4
|
ExecutionContext,
|
|
5
|
+
InternalServerErrorException,
|
|
4
6
|
createParamDecorator,
|
|
5
7
|
} from "@nestjs/common";
|
|
6
|
-
import { HttpArgumentsHost } from "@nestjs/common/interfaces";
|
|
7
|
-
import express from "express";
|
|
8
|
+
import type { HttpArgumentsHost } from "@nestjs/common/interfaces";
|
|
9
|
+
import type express from "express";
|
|
10
|
+
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
8
11
|
import multer from "multer";
|
|
9
12
|
import typia from "typia";
|
|
10
13
|
|
|
11
|
-
import {
|
|
14
|
+
import type { IRequestFormDataProps } from "../options/IRequestFormDataProps";
|
|
12
15
|
import { Singleton } from "../utils/Singleton";
|
|
13
|
-
import {
|
|
16
|
+
import { validate_request_form_data } from "./internal/validate_request_form_data";
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* Type safe multipart/form-data decorator.
|
|
@@ -32,7 +35,29 @@ import { validate_request_multipart } from "./internal/validate_request_multipar
|
|
|
32
35
|
* 2. Do not allow dynamic property
|
|
33
36
|
* 3. Only `boolean`, `bigint`, `number`, `string`, `Blob`, `File` or their array types are allowed
|
|
34
37
|
* 4. By the way, union type never be not allowed
|
|
35
|
-
*
|
|
38
|
+
*
|
|
39
|
+
* By the way, if you're using `fastify`, you have to setup `@fastify/multipart`
|
|
40
|
+
* and configure like below when composing the NestJS application. If you don't do
|
|
41
|
+
* that, `@TypedFormData.Body()` will not work properly, and throw 500 internal
|
|
42
|
+
* server error when `Blob` or `File` type being utilized.
|
|
43
|
+
*
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import multipart from "fastify-multipart";
|
|
46
|
+
* import { NestFactory } from "@nestjs/core";
|
|
47
|
+
* import {
|
|
48
|
+
* FastifyAdapter,
|
|
49
|
+
* NestFastifyApplication
|
|
50
|
+
* } from "@nestjs/platform-fastify";
|
|
51
|
+
*
|
|
52
|
+
* export async function main() {
|
|
53
|
+
* const app = await NestFactory.create<NestFastifyApplication>(
|
|
54
|
+
* AppModule,
|
|
55
|
+
* new FastifyAdapter(),
|
|
56
|
+
* );
|
|
57
|
+
* app.register(multipart);
|
|
58
|
+
* await app.listen(3000);
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
36
61
|
*
|
|
37
62
|
* @todo Change to ReadableStream through configuring storage engine of multer
|
|
38
63
|
* @author Jeongho Nam - https://github.com/samchon
|
|
@@ -48,24 +73,12 @@ export namespace TypedFormData {
|
|
|
48
73
|
* @param props Automatically filled by transformer
|
|
49
74
|
*/
|
|
50
75
|
export function Body<T extends object>(
|
|
51
|
-
props?:
|
|
76
|
+
props?: IRequestFormDataProps<T>,
|
|
52
77
|
): ParameterDecorator {
|
|
53
|
-
const checker =
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
...(file.limit === 1 ? { maxCount: 1 } : {}),
|
|
58
|
-
})),
|
|
59
|
-
);
|
|
60
|
-
const interceptor = (
|
|
61
|
-
request: express.Request,
|
|
62
|
-
response: express.Response,
|
|
63
|
-
) =>
|
|
64
|
-
new Promise<void>((resolve, reject) =>
|
|
65
|
-
upload(request, response, (error) => {
|
|
66
|
-
if (error) reject(error);
|
|
67
|
-
else resolve();
|
|
68
|
-
}),
|
|
78
|
+
const checker = validate_request_form_data(props);
|
|
79
|
+
const predicator = (type: "express" | "fastify") =>
|
|
80
|
+
new Singleton(() =>
|
|
81
|
+
type === "express" ? decodeExpress(props!) : decodeFastify(props!),
|
|
69
82
|
);
|
|
70
83
|
return createParamDecorator(async function TypedFormDataBody(
|
|
71
84
|
_unknown: any,
|
|
@@ -75,15 +88,16 @@ export namespace TypedFormData {
|
|
|
75
88
|
const request: express.Request = http.getRequest();
|
|
76
89
|
if (isMultipartFormData(request.headers["content-type"]) === false)
|
|
77
90
|
throw new BadRequestException(
|
|
78
|
-
`Request body type is not "
|
|
91
|
+
`Request body type is not "multipart/form-data".`,
|
|
79
92
|
);
|
|
80
|
-
await interceptor(request, http.getResponse());
|
|
81
|
-
|
|
82
|
-
const data: FormData = new FormData();
|
|
83
|
-
for (const [key, value] of Object.entries(request.body))
|
|
84
|
-
for (const elem of String(value).split(",")) data.append(key, elem);
|
|
85
|
-
if (request.files) parseFiles(data)(request.files);
|
|
86
93
|
|
|
94
|
+
const decoder = isExpressRequest(request)
|
|
95
|
+
? predicator("express").get()
|
|
96
|
+
: predicator("fastify").get();
|
|
97
|
+
const data: FormData = await decoder({
|
|
98
|
+
request: request as any,
|
|
99
|
+
response: http.getResponse(),
|
|
100
|
+
});
|
|
87
101
|
const output: T | Error = checker(data);
|
|
88
102
|
if (output instanceof Error) throw output;
|
|
89
103
|
return output;
|
|
@@ -92,16 +106,65 @@ export namespace TypedFormData {
|
|
|
92
106
|
Object.assign(Body, typia.http.assertFormData);
|
|
93
107
|
Object.assign(Body, typia.http.isFormData);
|
|
94
108
|
Object.assign(Body, typia.http.validateFormData);
|
|
95
|
-
|
|
96
|
-
export interface IProps<T> {
|
|
97
|
-
files: Array<{
|
|
98
|
-
name: string;
|
|
99
|
-
limit: number | null;
|
|
100
|
-
}>;
|
|
101
|
-
validator: IRequestMultipartProps<T>;
|
|
102
|
-
}
|
|
103
109
|
}
|
|
104
110
|
|
|
111
|
+
const decodeExpress = <T>(props: IRequestFormDataProps<T>) => {
|
|
112
|
+
const upload = multerApplication.get().fields(
|
|
113
|
+
props!.files.map((file) => ({
|
|
114
|
+
name: file.name,
|
|
115
|
+
...(file.limit === 1 ? { maxCount: 1 } : {}),
|
|
116
|
+
})),
|
|
117
|
+
);
|
|
118
|
+
const interceptor = (request: express.Request, response: express.Response) =>
|
|
119
|
+
new Promise<void>((resolve, reject) =>
|
|
120
|
+
upload(request, response, (error) => {
|
|
121
|
+
if (error) reject(error);
|
|
122
|
+
else resolve();
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
return async (socket: {
|
|
126
|
+
request: express.Request;
|
|
127
|
+
response: express.Response;
|
|
128
|
+
}): Promise<FormData> => {
|
|
129
|
+
await interceptor(socket.request, socket.response);
|
|
130
|
+
|
|
131
|
+
const data: FormData = new FormData();
|
|
132
|
+
for (const [key, value] of Object.entries(socket.request.body))
|
|
133
|
+
for (const elem of String(value).split(",")) data.append(key, elem);
|
|
134
|
+
|
|
135
|
+
if (socket.request.files) parseFiles(data)(socket.request.files);
|
|
136
|
+
return data;
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const decodeFastify =
|
|
141
|
+
<T>(_props: IRequestFormDataProps<T>) =>
|
|
142
|
+
async (socket: {
|
|
143
|
+
request: FastifyRequest & {
|
|
144
|
+
files?(): AsyncIterableIterator<MultipartFile>;
|
|
145
|
+
};
|
|
146
|
+
response: FastifyReply;
|
|
147
|
+
}): Promise<FormData> => {
|
|
148
|
+
if (
|
|
149
|
+
socket.request.files === undefined ||
|
|
150
|
+
typeof socket.request.files !== "function"
|
|
151
|
+
)
|
|
152
|
+
throw new InternalServerErrorException(
|
|
153
|
+
"Have not configured the `fastify-multipart` plugin yet. Inquiry to the backend developer.",
|
|
154
|
+
);
|
|
155
|
+
const data: FormData = new FormData();
|
|
156
|
+
for (const [key, value] of Object.entries(socket.request.body ?? {}))
|
|
157
|
+
for (const elem of String(value).split(",")) data.append(key, elem);
|
|
158
|
+
for await (const file of socket.request.files())
|
|
159
|
+
data.append(
|
|
160
|
+
file.fieldname,
|
|
161
|
+
new File([await file.toBuffer()], file.filename, {
|
|
162
|
+
type: file.mimetype,
|
|
163
|
+
}),
|
|
164
|
+
);
|
|
165
|
+
return data;
|
|
166
|
+
};
|
|
167
|
+
|
|
105
168
|
/**
|
|
106
169
|
* @internal
|
|
107
170
|
*/
|
|
@@ -130,17 +193,18 @@ const parseFiles =
|
|
|
130
193
|
/**
|
|
131
194
|
* @internal
|
|
132
195
|
*/
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
196
|
+
const isMultipartFormData = (text?: string): boolean =>
|
|
197
|
+
text !== undefined &&
|
|
198
|
+
text
|
|
199
|
+
.split(";")
|
|
200
|
+
.map((str) => str.trim())
|
|
201
|
+
.some((str) => str === "multipart/form-data");
|
|
202
|
+
|
|
203
|
+
const isExpressRequest = (
|
|
204
|
+
request: express.Request | FastifyRequest,
|
|
205
|
+
): request is express.Request => (request as express.Request).app !== undefined;
|
|
142
206
|
|
|
143
207
|
/**
|
|
144
208
|
* @internal
|
|
145
209
|
*/
|
|
146
|
-
const
|
|
210
|
+
const multerApplication = new Singleton(() => multer());
|
package/src/decorators/internal/{validate_request_multipart.ts → validate_request_form_data.ts}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { BadRequestException } from "@nestjs/common";
|
|
2
2
|
import typia, { IValidation, TypeGuardError } from "typia";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { IRequestFormDataProps } from "../../options/IRequestFormDataProps";
|
|
5
5
|
import { NoTransformConfigureError } from "./NoTransformConfigureError";
|
|
6
6
|
|
|
7
|
-
export const
|
|
8
|
-
props?:
|
|
7
|
+
export const validate_request_form_data = <T>(
|
|
8
|
+
props?: IRequestFormDataProps<T>,
|
|
9
9
|
) => {
|
|
10
10
|
if (!props) return () => NoTransformConfigureError("TypedFormData.Bpdu");
|
|
11
11
|
else if (props.validator.type === "assert")
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { IValidation } from "typia";
|
|
2
2
|
|
|
3
|
-
export interface
|
|
4
|
-
files: Array<
|
|
3
|
+
export interface IRequestFormDataProps<T> {
|
|
4
|
+
files: Array<IRequestFormDataProps.IFile>;
|
|
5
5
|
validator:
|
|
6
|
-
|
|
|
7
|
-
|
|
|
8
|
-
|
|
|
6
|
+
| IRequestFormDataProps.IAssert<T>
|
|
7
|
+
| IRequestFormDataProps.IIs<T>
|
|
8
|
+
| IRequestFormDataProps.IValidate<T>;
|
|
9
9
|
}
|
|
10
|
-
export namespace
|
|
10
|
+
export namespace IRequestFormDataProps {
|
|
11
11
|
export interface IAssert<T> {
|
|
12
12
|
type: "assert";
|
|
13
13
|
assert: (input: FormData) => T;
|
|
@@ -11,7 +11,7 @@ import { IProject } from "typia/lib/transformers/IProject";
|
|
|
11
11
|
import { TransformerError } from "typia/lib/transformers/TransformerError";
|
|
12
12
|
|
|
13
13
|
import { INestiaTransformProject } from "../options/INestiaTransformProject";
|
|
14
|
-
import {
|
|
14
|
+
import { IRequestFormDataProps } from "../options/IRequestFormDataProps";
|
|
15
15
|
|
|
16
16
|
export namespace TypedFormDataBodyProgrammer {
|
|
17
17
|
export const generate =
|
|
@@ -34,7 +34,7 @@ export namespace TypedFormDataBodyProgrammer {
|
|
|
34
34
|
result.errors,
|
|
35
35
|
);
|
|
36
36
|
|
|
37
|
-
const files:
|
|
37
|
+
const files: IRequestFormDataProps.IFile[] =
|
|
38
38
|
result.data.objects[0].properties
|
|
39
39
|
.filter(
|
|
40
40
|
(p) =>
|
|
@@ -48,7 +48,7 @@ export namespace TypedFormDataBodyProgrammer {
|
|
|
48
48
|
|
|
49
49
|
// GENERATE VALIDATION PLAN
|
|
50
50
|
const parameter =
|
|
51
|
-
(key:
|
|
51
|
+
(key: IRequestFormDataProps<any>["validator"]["type"]) =>
|
|
52
52
|
(
|
|
53
53
|
programmer: (
|
|
54
54
|
project: IProject,
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { BadRequestException } from "@nestjs/common";
|
|
2
|
-
import { IRequestMultipartProps } from "../../options/IRequestMulltipartProps";
|
|
3
|
-
export declare const validate_request_multipart: <T>(props?: IRequestMultipartProps<T> | undefined) => (() => Error) | ((input: FormData) => BadRequestException | T);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IRequestMulltipartProps.js","sourceRoot":"","sources":["../../src/options/IRequestMulltipartProps.ts"],"names":[],"mappings":""}
|