@tsed/platform-multer 8.7.0

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.
Files changed (51) hide show
  1. package/.barrelsby.json +5 -0
  2. package/lib/esm/adapters/express/MulterModule.js +30 -0
  3. package/lib/esm/adapters/express/MulterModule.js.map +1 -0
  4. package/lib/esm/adapters/koa/MulterModule.js +57 -0
  5. package/lib/esm/adapters/koa/MulterModule.js.map +1 -0
  6. package/lib/esm/common/constants/constants.js +3 -0
  7. package/lib/esm/common/constants/constants.js.map +1 -0
  8. package/lib/esm/common/decorators/multerFileSize.js +32 -0
  9. package/lib/esm/common/decorators/multerFileSize.js.map +1 -0
  10. package/lib/esm/common/decorators/multerOptions.js +50 -0
  11. package/lib/esm/common/decorators/multerOptions.js.map +1 -0
  12. package/lib/esm/common/decorators/multipartFile.js +77 -0
  13. package/lib/esm/common/decorators/multipartFile.js.map +1 -0
  14. package/lib/esm/common/errors/MulterException.js +17 -0
  15. package/lib/esm/common/errors/MulterException.js.map +1 -0
  16. package/lib/esm/common/index.js +11 -0
  17. package/lib/esm/common/index.js.map +1 -0
  18. package/lib/esm/common/interfaces/PlatformMulterSettings.js +2 -0
  19. package/lib/esm/common/interfaces/PlatformMulterSettings.js.map +1 -0
  20. package/lib/esm/common/middlewares/PlatformMulterMiddleware.js +40 -0
  21. package/lib/esm/common/middlewares/PlatformMulterMiddleware.js.map +1 -0
  22. package/lib/esm/index.js +2 -0
  23. package/lib/esm/index.js.map +1 -0
  24. package/lib/types/adapters/express/MulterModule.d.ts +1 -0
  25. package/lib/types/adapters/koa/MulterModule.d.ts +1 -0
  26. package/lib/types/common/constants/constants.d.ts +7 -0
  27. package/lib/types/common/decorators/multerFileSize.d.ts +28 -0
  28. package/lib/types/common/decorators/multerOptions.d.ts +43 -0
  29. package/lib/types/common/decorators/multipartFile.d.ts +48 -0
  30. package/lib/types/common/errors/MulterException.d.ts +14 -0
  31. package/lib/types/common/index.d.ts +10 -0
  32. package/lib/types/common/interfaces/PlatformMulterSettings.d.ts +44 -0
  33. package/lib/types/common/middlewares/PlatformMulterMiddleware.d.ts +11 -0
  34. package/lib/types/index.d.ts +1 -0
  35. package/package.json +102 -0
  36. package/src/adapters/express/MulterModule.ts +40 -0
  37. package/src/adapters/koa/MulterModule.ts +73 -0
  38. package/src/common/constants/constants.ts +10 -0
  39. package/src/common/decorators/multerFileSize.spec.ts +22 -0
  40. package/src/common/decorators/multerFileSize.ts +32 -0
  41. package/src/common/decorators/multerOptions.spec.ts +21 -0
  42. package/src/common/decorators/multerOptions.ts +53 -0
  43. package/src/common/decorators/multipartFile.spec.ts +260 -0
  44. package/src/common/decorators/multipartFile.ts +91 -0
  45. package/src/common/errors/MulterException.ts +20 -0
  46. package/src/common/index.ts +10 -0
  47. package/src/common/interfaces/PlatformMulterSettings.ts +45 -0
  48. package/src/common/middlewares/PlatformMulterMiddleware.spec.ts +98 -0
  49. package/src/common/middlewares/PlatformMulterMiddleware.ts +46 -0
  50. package/src/index.ts +1 -0
  51. package/vitest.config.mts +21 -0
@@ -0,0 +1,5 @@
1
+ {
2
+ "directory": ["./src/common"],
3
+ "exclude": ["**/__mock__", "**/__fixtures__", "**/__mocks__", "**/*.spec.ts", "**/getConfiguration.ts", "FakeResponse.ts"],
4
+ "delete": true
5
+ }
@@ -0,0 +1,30 @@
1
+ import { promisify } from "node:util";
2
+ import { injectable } from "@tsed/di";
3
+ import { MULTER_MODULE } from "../../common/index.js";
4
+ async function factory() {
5
+ const { default: multer } = await import("multer");
6
+ return {
7
+ multer,
8
+ get(options) {
9
+ const instance = multer(options);
10
+ const makePromise = (multer, name) => {
11
+ // istanbul ignore next
12
+ if (!multer[name])
13
+ return;
14
+ const fn = multer[name];
15
+ multer[name] = function apply(...args) {
16
+ const middleware = Reflect.apply(fn, this, args);
17
+ return (req, res) => promisify(middleware)(req, res);
18
+ };
19
+ };
20
+ makePromise(instance, "any");
21
+ makePromise(instance, "array");
22
+ makePromise(instance, "fields");
23
+ makePromise(instance, "none");
24
+ makePromise(instance, "single");
25
+ return instance;
26
+ }
27
+ };
28
+ }
29
+ injectable(MULTER_MODULE).asyncFactory(factory).token();
30
+ //# sourceMappingURL=MulterModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MulterModule.js","sourceRoot":"","sources":["../../../../src/adapters/express/MulterModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEpD,KAAK,UAAU,OAAO;IACpB,MAAM,EAAC,OAAO,EAAE,MAAM,EAAC,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEjD,OAAO;QACL,MAAM;QACN,GAAG,CAAC,OAAgB;YAClB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAEjC,MAAM,WAAW,GAAG,CAAC,MAAW,EAAE,IAAY,EAAE,EAAE;gBAChD,uBAAuB;gBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAE1B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;gBAExB,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,IAAW;oBAC1C,MAAM,UAAU,GAAQ,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;oBAEtD,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACjE,CAAC,CAAC;YACJ,CAAC,CAAC;YAEF,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC7B,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC/B,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAChC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9B,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAEhC,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,UAAU,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { promisify } from "node:util";
2
+ import { injectable } from "@tsed/di";
3
+ import { MULTER_MODULE } from "../../common/index.js";
4
+ /**
5
+ * @ignore
6
+ */
7
+ function createRawMiddleware(middleware) {
8
+ return async (request) => {
9
+ const ctx = request.ctx;
10
+ await middleware(ctx.req, ctx.res);
11
+ const forwardKey = (key) => {
12
+ if (ctx.req[key]) {
13
+ ctx.request[key] = ctx.req[key];
14
+ ctx[key] = ctx.req[key];
15
+ delete ctx.req[key];
16
+ }
17
+ };
18
+ if ("request" in ctx) {
19
+ if (ctx.req.body) {
20
+ ctx.request.body = ctx.req.body;
21
+ delete ctx.req.body;
22
+ }
23
+ forwardKey("file");
24
+ forwardKey("files");
25
+ }
26
+ };
27
+ }
28
+ /**
29
+ * @ignore
30
+ */
31
+ function makePromise(multer, name) {
32
+ // istanbul ignore next
33
+ if (!multer[name])
34
+ return;
35
+ const fn = multer[name];
36
+ multer[name] = function apply(...args) {
37
+ const middleware = Reflect.apply(fn, this, args);
38
+ return createRawMiddleware(promisify(middleware));
39
+ };
40
+ }
41
+ async function factory() {
42
+ const { default: multer } = await import("multer");
43
+ return {
44
+ multer,
45
+ get(options) {
46
+ const instance = multer(options);
47
+ makePromise(instance, "any");
48
+ makePromise(instance, "array");
49
+ makePromise(instance, "fields");
50
+ makePromise(instance, "none");
51
+ makePromise(instance, "single");
52
+ return instance;
53
+ }
54
+ };
55
+ }
56
+ injectable(MULTER_MODULE).asyncFactory(factory).token();
57
+ //# sourceMappingURL=MulterModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MulterModule.js","sourceRoot":"","sources":["../../../../src/adapters/koa/MulterModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAIpC,OAAO,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AAEpD;;GAEG;AACH,SAAS,mBAAmB,CAAC,UAAe;IAC1C,OAAO,KAAK,EAAE,OAAoB,EAAE,EAAE;QACpC,MAAM,GAAG,GAAQ,OAAO,CAAC,GAAG,CAAC;QAE7B,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAEnC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE;YACjC,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAChC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACxB,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACjB,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;gBAChC,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YACtB,CAAC;YAED,UAAU,CAAC,MAAM,CAAC,CAAC;YACnB,UAAU,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,MAAW,EAAE,IAAY;IAC5C,uBAAuB;IACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO;IAE1B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAExB,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,IAAW;QAC1C,MAAM,UAAU,GAAQ,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAEtD,OAAO,mBAAmB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,OAAO;IACpB,MAAM,EAAC,OAAO,EAAE,MAAM,EAAC,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEjD,OAAO;QACL,MAAM;QACN,GAAG,CAAC,OAAgB;YAClB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAEjC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC7B,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC/B,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAChC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9B,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAEhC,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,UAAU,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const MULTER_MODULE = Symbol.for("MULTER_MODULE");
2
+ export const PLATFORM_MULTER_OPTIONS = Symbol.for("PLATFORM_MULTER_OPTIONS");
3
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/common/constants/constants.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { MulterOptions } from "./multerOptions.js";
2
+ /**
3
+ * Define file size limit.
4
+ *
5
+ * ```typescript
6
+ * import {Post} from "@tsed/schema";
7
+ * import {MulterOptions, MultipartFile} from "@tsed/platform-multer";
8
+ * import {Controller} from "@tsed/di";
9
+ * import {Multer} from "@types/multer";
10
+ *
11
+ * type MulterFile = Express.Multer.File;
12
+ *
13
+ * @Controller('/')
14
+ * class MyCtrl {
15
+ * @Post('/file2')
16
+ * @MulterFileSize(1024) // (Ko). Applied for all fields
17
+ * private uploadFile(@MultipartFile("file1") file: MulterFile, @MultipartFile("file2") file2: MulterFile) {
18
+ *
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * > See the tutorial on the [multer configuration](/docs/upload-files.md).
24
+ * @param fileSize
25
+ * @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor}
26
+ * @decorator
27
+ * @multer
28
+ */
29
+ export function MulterFileSize(fileSize) {
30
+ return MulterOptions({ limits: { fileSize } });
31
+ }
32
+ //# sourceMappingURL=multerFileSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multerFileSize.js","sourceRoot":"","sources":["../../../../src/common/decorators/multerFileSize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,aAAa,CAAC,EAAC,MAAM,EAAE,EAAC,QAAQ,EAAC,EAAC,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { StoreMerge } from "@tsed/core";
2
+ import { PLATFORM_MULTER_OPTIONS } from "../constants/constants.js";
3
+ /**
4
+ * Define multer option for all MultipartFile
5
+ *
6
+ * ```typescript
7
+ * import {PlatformMulterFile, MultipartFile, MulterOptions} from "@tsed/platform-multer";
8
+ * import {Controller} from "@tsed/di";
9
+ * import {Post} from "@tsed/schema";
10
+ *
11
+ * @Controller('/')
12
+ * class MyCtrl {
13
+ * @Post('/file')
14
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile) {
15
+ *
16
+ * }
17
+ *
18
+ * @Post('/file')
19
+ * @MulterOptions({dest: "/other-dir"})
20
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile) {
21
+ *
22
+ * }
23
+ *
24
+ * @Post('/file2')
25
+ * @MulterOptions({dest: "/other-dir"})
26
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile, @MultipartFile("file2") file2: PlatformMulterFile) {
27
+ *
28
+ * }
29
+ *
30
+ * @Post('/files')
31
+ * private uploadFile(@MultipartFile("file1") files: PlatformMulterFile[]) {
32
+ *
33
+ * }
34
+ * }
35
+ * ```
36
+ *
37
+ * See the tutorial on the [multer configuration](/docs/upload-files.md).
38
+ *
39
+ * @param {multer.Options} options
40
+ * @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor}
41
+ * @decorator
42
+ * @multer
43
+ */
44
+ export function MulterOptions(options) {
45
+ return (target, propertyKey, descriptor) => {
46
+ StoreMerge(PLATFORM_MULTER_OPTIONS, { options })(target, propertyKey, descriptor);
47
+ return descriptor;
48
+ };
49
+ }
50
+ //# sourceMappingURL=multerOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multerOptions.js","sourceRoot":"","sources":["../../../../src/common/decorators/multerOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AAGtC,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO,CAAC,MAAW,EAAE,WAAmB,EAAE,UAA8B,EAAE,EAAE;QAC1E,UAAU,CAAC,uBAAuB,EAAE,EAAC,OAAO,EAAC,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAEhF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { Metadata, StoreMerge, useDecorators, useMethodDecorators } from "@tsed/core";
2
+ import { UseBefore } from "@tsed/platform-middlewares";
3
+ import { ParamTypes, UseParam } from "@tsed/platform-params";
4
+ import { InFile } from "@tsed/schema";
5
+ import { PLATFORM_MULTER_OPTIONS } from "../constants/constants.js";
6
+ import { PlatformMulterMiddleware } from "../middlewares/PlatformMulterMiddleware.js";
7
+ function mapOptions(name, maxCount) {
8
+ return {
9
+ fields: [
10
+ {
11
+ name,
12
+ maxCount
13
+ }
14
+ ]
15
+ };
16
+ }
17
+ /**
18
+ * Define a parameter as Multipart file.
19
+ *
20
+ * ```typescript
21
+ * import {Post} from "@tsed/schema";
22
+ * import {Controller, MulterOptions, MultipartFile} from "@tsed/platform-multer";
23
+ * import {Controller} from "@tsed/di";
24
+ * import {Multer} from "@types/multer";
25
+ *
26
+ * type MulterFile = Express.Multer.File;
27
+ *
28
+ * @Controller('/')
29
+ * class MyCtrl {
30
+ * @Post('/file')
31
+ * private uploadFile(@MultipartFile("file1") file: MulterFile) {
32
+ *
33
+ * }
34
+ *
35
+ * @Post('/file')
36
+ * @MulterOptions({dest: "/other-dir"})
37
+ * private uploadFile(@MultipartFile("file1") file: MulterFile) {
38
+ *
39
+ * }
40
+ *
41
+ * @Post('/file2')
42
+ * @MulterOptions({dest: "/other-dir"})
43
+ * private uploadFile(@MultipartFile("file1") file: MulterFile, @MultipartFile("file2") file2: MulterFile) {
44
+ *
45
+ * }
46
+ *
47
+ * @Post('/files')
48
+ * private uploadFile(@MultipartFile("file1") files: MulterFile[]) {
49
+ *
50
+ * }
51
+ * }
52
+ * ```
53
+ *
54
+ * > See the tutorial on the [multer configuration](/docs/upload-files.md).
55
+ *
56
+ * @param name
57
+ * @param maxCount
58
+ * @returns Function
59
+ * @decorator
60
+ * @input
61
+ */
62
+ export function MultipartFile(name, maxCount) {
63
+ return (...args) => {
64
+ const [target, propertyKey, index] = args;
65
+ const multiple = Metadata.getParamTypes(target, propertyKey)[index] === Array;
66
+ name = (typeof name === "object" ? undefined : name);
67
+ const expression = [name, !multiple && "0"].filter(Boolean).join(".");
68
+ const decorators = useDecorators(InFile(name), useMethodDecorators(StoreMerge(PLATFORM_MULTER_OPTIONS, mapOptions(name, maxCount)), UseBefore(PlatformMulterMiddleware)), UseParam({
69
+ paramType: ParamTypes.FILES,
70
+ dataPath: "$ctx.request.files",
71
+ expression,
72
+ useValidation: true
73
+ }));
74
+ decorators(...args);
75
+ };
76
+ }
77
+ //# sourceMappingURL=multipartFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipartFile.js","sourceRoot":"","sources":["../../../../src/common/decorators/multipartFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,mBAAmB,EAAC,MAAM,YAAY,CAAC;AACzG,OAAO,EAAC,SAAS,EAAC,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAGpC,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAC,wBAAwB,EAAC,MAAM,4CAA4C,CAAC;AAEpF,SAAS,UAAU,CAAC,IAAY,EAAE,QAA4B;IAC5D,OAAO;QACL,MAAM,EAAE;YACN;gBACE,IAAI;gBACJ,QAAQ;aACT;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,QAAiB;IAC3D,OAAO,CAAC,GAAG,IAAyB,EAAQ,EAAE;QAC5C,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,KAAe,CAAC,KAAK,KAAK,CAAC;QAExF,IAAI,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAE,CAAC;QAEtD,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,aAAa,CAC9B,MAAM,CAAC,IAAI,CAAC,EACZ,mBAAmB,CAAC,UAAU,CAAC,uBAAuB,EAAE,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,wBAAwB,CAAC,CAAC,EACzH,QAAQ,CAAC;YACP,SAAS,EAAE,UAAU,CAAC,KAAK;YAC3B,QAAQ,EAAE,oBAAoB;YAC9B,UAAU;YACV,aAAa,EAAE,IAAI;SACpB,CAAC,CACH,CAAC;QAEF,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { BadRequest } from "@tsed/exceptions";
2
+ /**
3
+ * Exception thrown when a Multer error occurs during file upload operations.
4
+ * Extends the BadRequest exception with Multer-specific properties.
5
+ */
6
+ export class MulterException extends BadRequest {
7
+ /**
8
+ * Creates a new MulterException
9
+ * @param er - The original Multer error
10
+ */
11
+ constructor(er) {
12
+ super(er.message);
13
+ this.origin = er;
14
+ this.name = er.code;
15
+ }
16
+ }
17
+ //# sourceMappingURL=MulterException.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MulterException.js","sourceRoot":"","sources":["../../../../src/common/errors/MulterException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAG5C;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAG7C;;;OAGG;IACH,YAAY,EAAe;QACzB,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @file Automatically generated by @tsed/barrels.
3
+ */
4
+ export * from "./constants/constants.js";
5
+ export * from "./decorators/multerFileSize.js";
6
+ export * from "./decorators/multerOptions.js";
7
+ export * from "./decorators/multipartFile.js";
8
+ export * from "./errors/MulterException.js";
9
+ export * from "./interfaces/PlatformMulterSettings.js";
10
+ export * from "./middlewares/PlatformMulterMiddleware.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PlatformMulterSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformMulterSettings.js","sourceRoot":"","sources":["../../../../src/common/interfaces/PlatformMulterSettings.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import { __decorate, __metadata, __param } from "tslib";
2
+ import { constant, inject, injectable, ProviderType } from "@tsed/di";
3
+ import { Context } from "@tsed/platform-params";
4
+ import { MULTER_MODULE, PLATFORM_MULTER_OPTIONS } from "../constants/constants.js";
5
+ import { MulterException } from "../errors/MulterException.js";
6
+ /**
7
+ * @middleware
8
+ */
9
+ export class PlatformMulterMiddleware {
10
+ async use(ctx) {
11
+ try {
12
+ const { fields, options = {} } = ctx.endpoint.get(PLATFORM_MULTER_OPTIONS);
13
+ const settings = {
14
+ ...constant("multer", {}),
15
+ ...options
16
+ };
17
+ /* istanbul ignore next */
18
+ if (settings.storage) {
19
+ settings.dest = undefined;
20
+ }
21
+ const { get } = await inject(MULTER_MODULE);
22
+ const middleware = get(settings).fields(fields);
23
+ return await middleware(ctx.getRequest(), ctx.getResponse());
24
+ }
25
+ catch (er) {
26
+ if (er.code) {
27
+ throw new MulterException(er);
28
+ }
29
+ throw er;
30
+ }
31
+ }
32
+ }
33
+ __decorate([
34
+ __param(0, Context()),
35
+ __metadata("design:type", Function),
36
+ __metadata("design:paramtypes", [Object]),
37
+ __metadata("design:returntype", Promise)
38
+ ], PlatformMulterMiddleware.prototype, "use", null);
39
+ injectable(PlatformMulterMiddleware).type(ProviderType.MIDDLEWARE).priority(-10);
40
+ //# sourceMappingURL=PlatformMulterMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformMulterMiddleware.js","sourceRoot":"","sources":["../../../../src/common/middlewares/PlatformMulterMiddleware.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,QAAQ,EAAa,MAAM,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,UAAU,CAAC;AAE/E,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAC;AAI9C,OAAO,EAAC,aAAa,EAAE,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,wBAAwB;IAC7B,AAAN,KAAK,CAAC,GAAG,CAAY,GAA4C;QAC/D,IAAI,CAAC;YACH,MAAM,EAAC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAG5C,uBAAuB,CAAC,CAAC;YAE5B,MAAM,QAAQ,GAAY;gBACxB,GAAG,QAAQ,CAAU,QAAQ,EAAE,EAAE,CAAC;gBAClC,GAAG,OAAO;aACX,CAAC;YAEF,0BAA0B;YAC1B,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,QAAQ,CAAC,IAAI,GAAG,SAAS,CAAC;YAC5B,CAAC;YAED,MAAM,EAAC,GAAG,EAAC,GAAG,MAAM,MAAM,CAAyB,aAAa,CAAC,CAAC;YAElE,MAAM,UAAU,GAAQ,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAErD,OAAO,MAAM,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;gBACZ,MAAM,IAAI,eAAe,CAAC,EAAE,CAAC,CAAC;YAChC,CAAC;YAED,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;CACF;AA9BO;IAAK,WAAA,OAAO,EAAE,CAAA;;;;mDA6BnB;AAGH,UAAU,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./common/index.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { Multer, Options } from "multer";
2
+ export interface MULTER_MODULE {
3
+ multer: Multer;
4
+ get(options: Options): Multer;
5
+ }
6
+ export declare const MULTER_MODULE: unique symbol;
7
+ export declare const PLATFORM_MULTER_OPTIONS: unique symbol;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Define file size limit.
3
+ *
4
+ * ```typescript
5
+ * import {Post} from "@tsed/schema";
6
+ * import {MulterOptions, MultipartFile} from "@tsed/platform-multer";
7
+ * import {Controller} from "@tsed/di";
8
+ * import {Multer} from "@types/multer";
9
+ *
10
+ * type MulterFile = Express.Multer.File;
11
+ *
12
+ * @Controller('/')
13
+ * class MyCtrl {
14
+ * @Post('/file2')
15
+ * @MulterFileSize(1024) // (Ko). Applied for all fields
16
+ * private uploadFile(@MultipartFile("file1") file: MulterFile, @MultipartFile("file2") file2: MulterFile) {
17
+ *
18
+ * }
19
+ * }
20
+ * ```
21
+ *
22
+ * > See the tutorial on the [multer configuration](/docs/upload-files.md).
23
+ * @param fileSize
24
+ * @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor}
25
+ * @decorator
26
+ * @multer
27
+ */
28
+ export declare function MulterFileSize(fileSize: number): MethodDecorator;
@@ -0,0 +1,43 @@
1
+ import type { Options } from "multer";
2
+ /**
3
+ * Define multer option for all MultipartFile
4
+ *
5
+ * ```typescript
6
+ * import {PlatformMulterFile, MultipartFile, MulterOptions} from "@tsed/platform-multer";
7
+ * import {Controller} from "@tsed/di";
8
+ * import {Post} from "@tsed/schema";
9
+ *
10
+ * @Controller('/')
11
+ * class MyCtrl {
12
+ * @Post('/file')
13
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile) {
14
+ *
15
+ * }
16
+ *
17
+ * @Post('/file')
18
+ * @MulterOptions({dest: "/other-dir"})
19
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile) {
20
+ *
21
+ * }
22
+ *
23
+ * @Post('/file2')
24
+ * @MulterOptions({dest: "/other-dir"})
25
+ * private uploadFile(@MultipartFile("file1") file: PlatformMulterFile, @MultipartFile("file2") file2: PlatformMulterFile) {
26
+ *
27
+ * }
28
+ *
29
+ * @Post('/files')
30
+ * private uploadFile(@MultipartFile("file1") files: PlatformMulterFile[]) {
31
+ *
32
+ * }
33
+ * }
34
+ * ```
35
+ *
36
+ * See the tutorial on the [multer configuration](/docs/upload-files.md).
37
+ *
38
+ * @param {multer.Options} options
39
+ * @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor}
40
+ * @decorator
41
+ * @multer
42
+ */
43
+ export declare function MulterOptions(options: Options): MethodDecorator;
@@ -0,0 +1,48 @@
1
+ import type { PlatformMulterFile } from "../interfaces/PlatformMulterSettings.js";
2
+ /**
3
+ * Define a parameter as Multipart file.
4
+ *
5
+ * ```typescript
6
+ * import {Post} from "@tsed/schema";
7
+ * import {Controller, MulterOptions, MultipartFile} from "@tsed/platform-multer";
8
+ * import {Controller} from "@tsed/di";
9
+ * import {Multer} from "@types/multer";
10
+ *
11
+ * type MulterFile = Express.Multer.File;
12
+ *
13
+ * @Controller('/')
14
+ * class MyCtrl {
15
+ * @Post('/file')
16
+ * private uploadFile(@MultipartFile("file1") file: MulterFile) {
17
+ *
18
+ * }
19
+ *
20
+ * @Post('/file')
21
+ * @MulterOptions({dest: "/other-dir"})
22
+ * private uploadFile(@MultipartFile("file1") file: MulterFile) {
23
+ *
24
+ * }
25
+ *
26
+ * @Post('/file2')
27
+ * @MulterOptions({dest: "/other-dir"})
28
+ * private uploadFile(@MultipartFile("file1") file: MulterFile, @MultipartFile("file2") file2: MulterFile) {
29
+ *
30
+ * }
31
+ *
32
+ * @Post('/files')
33
+ * private uploadFile(@MultipartFile("file1") files: MulterFile[]) {
34
+ *
35
+ * }
36
+ * }
37
+ * ```
38
+ *
39
+ * > See the tutorial on the [multer configuration](/docs/upload-files.md).
40
+ *
41
+ * @param name
42
+ * @param maxCount
43
+ * @returns Function
44
+ * @decorator
45
+ * @input
46
+ */
47
+ export declare function MultipartFile(name: string, maxCount?: number): ParameterDecorator;
48
+ export type MultipartFile = PlatformMulterFile;
@@ -0,0 +1,14 @@
1
+ import { BadRequest } from "@tsed/exceptions";
2
+ import type { MulterError } from "multer";
3
+ /**
4
+ * Exception thrown when a Multer error occurs during file upload operations.
5
+ * Extends the BadRequest exception with Multer-specific properties.
6
+ */
7
+ export declare class MulterException extends BadRequest {
8
+ origin: MulterError;
9
+ /**
10
+ * Creates a new MulterException
11
+ * @param er - The original Multer error
12
+ */
13
+ constructor(er: MulterError);
14
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @file Automatically generated by @tsed/barrels.
3
+ */
4
+ export * from "./constants/constants.js";
5
+ export * from "./decorators/multerFileSize.js";
6
+ export * from "./decorators/multerOptions.js";
7
+ export * from "./decorators/multipartFile.js";
8
+ export * from "./errors/MulterException.js";
9
+ export * from "./interfaces/PlatformMulterSettings.js";
10
+ export * from "./middlewares/PlatformMulterMiddleware.js";
@@ -0,0 +1,44 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ /// <reference types="node" resolution-mode="require"/>
4
+ import type { Readable } from "node:stream";
5
+ import type { Field, Multer, Options } from "multer";
6
+ declare global {
7
+ namespace TsED {
8
+ interface Configuration {
9
+ multer?: Options;
10
+ }
11
+ }
12
+ }
13
+ export type PlatformMulter = Multer;
14
+ export type PlatformMulterSettings = Options;
15
+ export interface PlatformMulterFile {
16
+ /** Name of the form field associated with this file. */
17
+ fieldname: string;
18
+ /** Name of the file on the uploader's computer. */
19
+ originalname: string;
20
+ /**
21
+ * Value of the `Content-Transfer-Encoding` header for this file.
22
+ * @deprecated since July 2015
23
+ * @see RFC 7578, Section 4.7
24
+ */
25
+ encoding: string;
26
+ /** Value of the `Content-Type` header for this file. */
27
+ mimetype: string;
28
+ /** Size of the file in bytes. */
29
+ size: number;
30
+ /**
31
+ * A readable stream of this file. Only available to the `_handleFile`
32
+ * callback for custom `StorageEngine`s.
33
+ */
34
+ stream: Readable;
35
+ /** `DiskStorage` only: Directory to which this file has been uploaded. */
36
+ destination: string;
37
+ /** `DiskStorage` only: Name of this file within `destination`. */
38
+ filename: string;
39
+ /** `DiskStorage` only: Full path to the uploaded file. */
40
+ path: string;
41
+ /** `MemoryStorage` only: A Buffer containing the entire file. */
42
+ buffer: Buffer;
43
+ }
44
+ export type PlatformMulterField = Field;
@@ -0,0 +1,11 @@
1
+ import { DIContext } from "@tsed/di";
2
+ import { MiddlewareMethods } from "@tsed/platform-middlewares";
3
+ import { JsonMethodStore } from "@tsed/schema";
4
+ /**
5
+ * @middleware
6
+ */
7
+ export declare class PlatformMulterMiddleware implements MiddlewareMethods {
8
+ use(ctx: DIContext & {
9
+ endpoint: JsonMethodStore;
10
+ }): Promise<any>;
11
+ }
@@ -0,0 +1 @@
1
+ export * from "./common/index.js";