@comasoft/nestjs 0.1.71 → 0.1.94

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 (53) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/dist/aws/aws-s3-multipart.service.d.ts +21 -0
  3. package/dist/aws/aws-s3-multipart.service.js +1 -0
  4. package/dist/aws/aws-s3.service.d.ts +2 -2
  5. package/dist/aws/aws-s3.service.js +1 -1
  6. package/dist/aws/aws.module.js +1 -1
  7. package/dist/aws/dto/index.d.ts +1 -0
  8. package/dist/aws/dto/index.js +1 -1
  9. package/dist/aws/dto/multipart.dto.d.ts +40 -0
  10. package/dist/aws/dto/multipart.dto.js +1 -0
  11. package/dist/aws/index.d.ts +1 -0
  12. package/dist/aws/index.js +1 -1
  13. package/dist/category/category.service.d.ts +11 -0
  14. package/dist/category/category.service.js +1 -1
  15. package/dist/database/entities/file.entity.d.ts +6 -4
  16. package/dist/database/entities/file.entity.js +1 -1
  17. package/dist/database/entities/notification-recipient.entity.js +1 -1
  18. package/dist/decorators/format.decorator.d.ts +2 -0
  19. package/dist/decorators/format.decorator.js +1 -0
  20. package/dist/decorators/index.d.ts +2 -0
  21. package/dist/decorators/index.js +1 -1
  22. package/dist/decorators/masking.transform.d.ts +2 -0
  23. package/dist/decorators/masking.transform.js +1 -0
  24. package/dist/dto/file.dto.d.ts +3 -0
  25. package/dist/dto/file.dto.js +1 -1
  26. package/dist/enums.common.d.ts +7 -0
  27. package/dist/enums.common.js +1 -1
  28. package/dist/events/services/event-notification.service.js +1 -1
  29. package/dist/file-upload/file.helper.d.ts +32 -0
  30. package/dist/file-upload/file.helper.js +1 -0
  31. package/dist/file-upload/file.service.d.ts +55 -0
  32. package/dist/file-upload/file.service.js +1 -0
  33. package/dist/file-upload/index.d.ts +2 -0
  34. package/dist/file-upload/index.js +1 -0
  35. package/dist/filters/index.d.ts +1 -0
  36. package/dist/filters/index.js +1 -1
  37. package/dist/filters/validation-exception.filter.d.ts +8 -0
  38. package/dist/filters/validation-exception.filter.js +1 -0
  39. package/dist/index.d.ts +1 -0
  40. package/dist/index.js +1 -1
  41. package/dist/notifications/index.d.ts +1 -0
  42. package/dist/notifications/services/email.service.d.ts +15 -1
  43. package/dist/notifications/services/email.service.js +1 -1
  44. package/dist/notifications/services/kakao.service.js +1 -1
  45. package/dist/notifications/services/notification-send.service.d.ts +1 -1
  46. package/dist/notifications/services/notification-send.service.js +1 -1
  47. package/dist/services/file.service.js +1 -1
  48. package/dist/services/index.d.ts +0 -1
  49. package/dist/services/index.js +1 -1
  50. package/dist/setup-swagger.d.ts +1 -0
  51. package/dist/setup-swagger.js +1 -1
  52. package/dist/utils/pagination.utils.js +1 -1
  53. package/package.json +3 -1
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:medium.com)",
5
+ "WebFetch(domain:github.com)"
6
+ ],
7
+ "deny": [],
8
+ "ask": []
9
+ }
10
+ }
@@ -0,0 +1,21 @@
1
+ import { ConfigService } from '@nestjs/config';
2
+ export declare class S3MultipartService {
3
+ private configService;
4
+ private readonly s3Client;
5
+ private readonly config;
6
+ constructor(configService: ConfigService);
7
+ private generateFileKey;
8
+ initiateMultipartUpload(category: string, originalFileName: string, mimeType: string): Promise<{
9
+ uploadId: string;
10
+ fileKey: string;
11
+ fileName: string;
12
+ path: string;
13
+ }>;
14
+ getUploadPartPresignedUrl(fileKey: string, uploadId: string, partNumber: number): Promise<string>;
15
+ completeMultipartUpload(fileKey: string, uploadId: string, parts: Array<{
16
+ part_number: number;
17
+ etag: string;
18
+ }>): Promise<void>;
19
+ abortMultipartUpload(fileKey: string, uploadId: string): Promise<void>;
20
+ getPublicUrl(category: string, path: string, fileName: string): string;
21
+ }
@@ -0,0 +1 @@
1
+ var e=this&&this.__decorate||function(e,t,r,i){var n,o=arguments.length,a=o<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,i);else for(var c=e.length-1;c>=0;c--)(n=e[c])&&(a=(o<3?n(a):o>3?n(t,r,a):n(t,r))||a);return o>3&&a&&Object.defineProperty(t,r,a),a},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(n,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i.throw(e))}catch(e){o(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.S3MultipartService=void 0;const i=require("@aws-sdk/client-s3"),n=require("@aws-sdk/client-s3"),o=require("@aws-sdk/s3-request-presigner"),a=require("@nestjs/common"),c=require("@nestjs/config"),l=require("nanoid");let s=class S3MultipartService{constructor(e){this.configService=e,this.config={region:this.configService.get("AWS_REGION"),credentials:{accessKeyId:this.configService.get("AWS_ACCESS_KEY_ID"),secretAccessKey:this.configService.get("AWS_SECRET_ACCESS_KEY")},bucket:this.configService.get("AWS_BUCKET_NAME"),cdnUrl:this.configService.get("CDN_URL")},this.s3Client=new i.S3Client({region:this.config.region,credentials:this.config.credentials})}generateFileKey(e,t){const r=new Date,i=r.getFullYear().toString().slice(-2),n=String(r.getMonth()+1).padStart(2,"0"),o=String(r.getDate()).padStart(2,"0");return{category:e,fileName:`${(0,l.nanoid)(8)}.${t}`,path:`${i}${n}${o}`}}initiateMultipartUpload(e,t,i){return r(this,void 0,void 0,function*(){try{let r;i.startsWith("image/")?(r=i.split("/")[1],"jpeg"===r&&(r="jpg")):r=t.split(".").pop()||"bin";const{category:o,fileName:a,path:c}=this.generateFileKey(e,r),l=`uploads/${e}/${c}/${a}`,s=new n.CreateMultipartUploadCommand({Bucket:this.config.bucket,Key:l,ContentType:i}),d=yield this.s3Client.send(s);if(!d.UploadId)throw new Error("Failed to initiate multipart upload: No UploadId returned");return{uploadId:d.UploadId,fileKey:l,fileName:a,path:c}}catch(e){throw new a.InternalServerErrorException(`Failed to initiate multipart upload: ${e.message}`)}})}getUploadPartPresignedUrl(e,t,i){return r(this,void 0,void 0,function*(){try{const r=new n.UploadPartCommand({Bucket:this.config.bucket,Key:e,UploadId:t,PartNumber:i});return yield(0,o.getSignedUrl)(this.s3Client,r,{expiresIn:3600})}catch(e){throw new a.InternalServerErrorException(`Failed to generate presigned URL for part ${i}: ${e.message}`)}})}completeMultipartUpload(e,t,i){return r(this,void 0,void 0,function*(){try{const r=i.sort((e,t)=>e.part_number-t.part_number),o=new n.CompleteMultipartUploadCommand({Bucket:this.config.bucket,Key:e,UploadId:t,MultipartUpload:{Parts:r.map(e=>({PartNumber:e.part_number,ETag:e.etag}))}});yield this.s3Client.send(o)}catch(e){throw new a.InternalServerErrorException(`Failed to complete multipart upload: ${e.message}`)}})}abortMultipartUpload(e,t){return r(this,void 0,void 0,function*(){try{const r=new n.AbortMultipartUploadCommand({Bucket:this.config.bucket,Key:e,UploadId:t});yield this.s3Client.send(r)}catch(e){console.error("Failed to abort multipart upload:",e)}})}getPublicUrl(e,t,r){const i=`uploads/${e}/${t}/${r}`;return`${this.config.cdnUrl}/${i}`}};exports.S3MultipartService=s,exports.S3MultipartService=s=e([(0,a.Injectable)(),t("design:paramtypes",[c.ConfigService])],s);
@@ -1,8 +1,8 @@
1
1
  import { ConfigService } from '@nestjs/config';
2
+ import { File } from '../database/entities';
3
+ import { FileService } from '../file-upload/file.service';
2
4
  import { CreateS3PresignedBaseDto, ResponseS3PresignedDto } from './dto';
3
5
  import { PresignedPostResult } from './types/s3.interface';
4
- import { FileService } from '../services';
5
- import { File } from '../database/entities';
6
6
  export declare class S3Service {
7
7
  private configService;
8
8
  private fileService;
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,r){var n,s=arguments.length,o=s<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(n=e[c])&&(o=(s<3?n(o):s>3?n(t,i,o):n(t,i))||o);return s>3&&o&&Object.defineProperty(t,i,o),o},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__param||function(e,t){return function(i,r){t(i,r,e)}},r=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(n,s){function fulfilled(e){try{step(r.next(e))}catch(e){s(e)}}function rejected(e){try{step(r.throw(e))}catch(e){s(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.S3Service=void 0;const n=require("@aws-sdk/client-s3"),s=require("@aws-sdk/s3-presigned-post"),o=require("@nestjs/common"),c=require("@nestjs/config"),a=require("class-transformer"),l=require("nanoid"),f=require("./constants/storage.constant"),d=require("./dto"),u=require("../services");let g=class S3Service{constructor(e,t){this.configService=e,this.fileService=t,this.config={region:this.configService.get("AWS_REGION"),credentials:{accessKeyId:this.configService.get("AWS_ACCESS_KEY_ID"),secretAccessKey:this.configService.get("AWS_SECRET_ACCESS_KEY")},bucket:this.configService.get("AWS_BUCKET_NAME"),cdnUrl:this.configService.get("CDN_URL")},this.s3=new n.S3({region:this.config.region,credentials:this.config.credentials})}generateFileKey(e,t){const i=new Date,r=i.getFullYear().toString().slice(-2),n=String(i.getMonth()+1).padStart(2,"0"),s=String(i.getDate()).padStart(2,"0");return{category:e,fileName:`${(0,l.nanoid)(8)}.${t}`,path:`${r}${n}${s}`}}getPresigned(e,t){return r(this,void 0,void 0,function*(){const{target:i,files:n,group_number:s}=t,o=yield Promise.all(n.map(e=>r(this,void 0,void 0,function*(){let t;e.mime_type.startsWith("image/")?(t=e.mime_type.split("/")[1],"jpeg"===t&&(t="jpg")):t=e.original_name.split(".").pop();const{fileName:r,path:n}=this.generateFileKey(i,t),s=`uploads/${i}/${n}/${r}`,o=yield this.presignedPost(s,e.mime_type);return{original_name:e.original_name,file_name:r,path:n,mime_type:e.mime_type,size:e.size,meta:e.meta,sort:e.sort,presigned:o}}))),c=yield this.fileService.createPending({target:i,group_number:s,user_id:e,files:o});return(0,a.plainToClass)(d.ResponseS3PresignedDto,{target:i,items:o.map(e=>{var t;return Object.assign(Object.assign({},e),{id:null===(t=c.find(t=>t.file_name===e.file_name))||void 0===t?void 0:t.id})})})})}presignedPost(e,t){return r(this,void 0,void 0,function*(){try{const{url:i,fields:r}=yield(0,s.createPresignedPost)(this.s3,{Bucket:this.config.bucket,Key:e,Conditions:[["content-length-range",0,f.MAX_FILE_SIZE],["eq","$Content-Type",t]],Fields:{"Content-Type":t},Expires:600});return{url:i,fields:r,key:e}}catch(e){throw new o.InternalServerErrorException(e.message)}})}deleteObjectsByKeys(e){return r(this,void 0,void 0,function*(){try{yield this.s3.deleteObjects({Bucket:this.config.bucket,Delete:{Objects:e.map(e=>({Key:e})),Quiet:!1}})}catch(e){}})}getFileKey(e){return`uploads/${e.target}/${e.path}/${e.file_name}`}};exports.S3Service=g,exports.S3Service=g=e([(0,o.Injectable)(),i(1,(0,o.Inject)((0,o.forwardRef)(()=>u.FileService))),t("design:paramtypes",[c.ConfigService,u.FileService])],g);
1
+ var e=this&&this.__decorate||function(e,t,i,r){var n,s=arguments.length,o=s<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(n=e[c])&&(o=(s<3?n(o):s>3?n(t,i,o):n(t,i))||o);return s>3&&o&&Object.defineProperty(t,i,o),o},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__param||function(e,t){return function(i,r){t(i,r,e)}},r=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(n,s){function fulfilled(e){try{step(r.next(e))}catch(e){s(e)}}function rejected(e){try{step(r.throw(e))}catch(e){s(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.S3Service=void 0;const n=require("@aws-sdk/client-s3"),s=require("@aws-sdk/s3-presigned-post"),o=require("@nestjs/common"),c=require("@nestjs/config"),a=require("class-transformer"),l=require("nanoid"),f=require("../file-upload/file.service"),d=require("./constants/storage.constant"),u=require("./dto");let g=class S3Service{constructor(e,t){this.configService=e,this.fileService=t,this.config={region:this.configService.get("AWS_REGION"),credentials:{accessKeyId:this.configService.get("AWS_ACCESS_KEY_ID"),secretAccessKey:this.configService.get("AWS_SECRET_ACCESS_KEY")},bucket:this.configService.get("AWS_BUCKET_NAME"),cdnUrl:this.configService.get("CDN_URL")},this.s3=new n.S3({region:this.config.region,credentials:this.config.credentials})}generateFileKey(e,t){const i=new Date,r=i.getFullYear().toString().slice(-2),n=String(i.getMonth()+1).padStart(2,"0"),s=String(i.getDate()).padStart(2,"0");return{category:e,fileName:`${(0,l.nanoid)(8)}.${t}`,path:`${r}${n}${s}`}}getPresigned(e,t){return r(this,void 0,void 0,function*(){const{target:i,files:n,group_number:s}=t,o=yield Promise.all(n.map(e=>r(this,void 0,void 0,function*(){let t;e.mime_type.startsWith("image/")?(t=e.mime_type.split("/")[1],"jpeg"===t&&(t="jpg")):t=e.original_name.split(".").pop();const{fileName:r,path:n}=this.generateFileKey(i,t),s=`uploads/${i}/${n}/${r}`,o=yield this.presignedPost(s,e.mime_type);return{original_name:e.original_name,file_name:r,path:n,mime_type:e.mime_type,size:e.size,meta:e.meta,sort:e.sort,presigned:o}}))),c=yield this.fileService.createPending({target:i,group_number:s,user_id:e,files:o});return(0,a.plainToClass)(u.ResponseS3PresignedDto,{target:i,items:o.map(e=>{var t;return Object.assign(Object.assign({},e),{id:null===(t=c.find(t=>t.file_name===e.file_name))||void 0===t?void 0:t.id})})})})}presignedPost(e,t){return r(this,void 0,void 0,function*(){try{const{url:i,fields:r}=yield(0,s.createPresignedPost)(this.s3,{Bucket:this.config.bucket,Key:e,Conditions:[["content-length-range",0,d.MAX_FILE_SIZE],["eq","$Content-Type",t]],Fields:{"Content-Type":t},Expires:600});return{url:i,fields:r,key:e}}catch(e){throw new o.InternalServerErrorException(e.message)}})}deleteObjectsByKeys(e){return r(this,void 0,void 0,function*(){try{yield this.s3.deleteObjects({Bucket:this.config.bucket,Delete:{Objects:e.map(e=>({Key:e})),Quiet:!1}})}catch(e){}})}getFileKey(e){return`uploads/${e.target}/${e.path}/${e.file_name}`}};exports.S3Service=g,exports.S3Service=g=e([(0,o.Injectable)(),i(1,(0,o.Inject)((0,o.forwardRef)(()=>f.FileService))),t("design:paramtypes",[c.ConfigService,f.FileService])],g);
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,r,o,t){var s,i=arguments.length,c=i<3?r:null===t?t=Object.getOwnPropertyDescriptor(r,o):t;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,r,o,t);else for(var l=e.length-1;l>=0;l--)(s=e[l])&&(c=(i<3?s(c):i>3?s(r,o,c):s(r,o))||c);return i>3&&c&&Object.defineProperty(r,o,c),c};Object.defineProperty(exports,"__esModule",{value:!0}),exports.AwsModule=void 0;const r=require("@nestjs/common"),o=require("@nestjs/config"),t=require("../services"),s=require("./aws-s3.service"),i=require("./aws.service");let c=class AwsModule{};exports.AwsModule=c,exports.AwsModule=c=e([(0,r.Global)(),(0,r.Module)({imports:[o.ConfigModule],providers:[i.AwsService,s.S3Service,t.FileService],exports:[i.AwsService,s.S3Service,t.FileService]})],c);
1
+ var e=this&&this.__decorate||function(e,r,t,i){var o,s=arguments.length,c=s<3?r:null===i?i=Object.getOwnPropertyDescriptor(r,t):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,r,t,i);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(c=(s<3?o(c):s>3?o(r,t,c):o(r,t))||c);return s>3&&c&&Object.defineProperty(r,t,c),c};Object.defineProperty(exports,"__esModule",{value:!0}),exports.AwsModule=void 0;const r=require("@nestjs/common"),t=require("@nestjs/config"),i=require("../file-upload/file.service"),o=require("./aws-s3-multipart.service"),s=require("./aws-s3.service"),c=require("./aws.service");let l=class AwsModule{};exports.AwsModule=l,exports.AwsModule=l=e([(0,r.Global)(),(0,r.Module)({imports:[t.ConfigModule],providers:[c.AwsService,s.S3Service,o.S3MultipartService,i.FileService],exports:[c.AwsService,s.S3Service,o.S3MultipartService,i.FileService]})],l);
@@ -1,2 +1,3 @@
1
1
  export * from './create-s3-presigned.dto';
2
2
  export * from './response-s3-presigned.dto';
3
+ export * from './multipart.dto';
@@ -1 +1 @@
1
- var e=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,i)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var o in t)"default"===o||Object.prototype.hasOwnProperty.call(r,o)||e(r,t,o)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./create-s3-presigned.dto"),exports),t(require("./response-s3-presigned.dto"),exports);
1
+ var e=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,i)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var o in t)"default"===o||Object.prototype.hasOwnProperty.call(r,o)||e(r,t,o)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./create-s3-presigned.dto"),exports),t(require("./response-s3-presigned.dto"),exports),t(require("./multipart.dto"),exports);
@@ -0,0 +1,40 @@
1
+ export declare class InitiateMultipartUploadDto {
2
+ target: string;
3
+ group_number: number;
4
+ file_name: string;
5
+ mime_type: string;
6
+ size: number;
7
+ meta?: Record<string, any>;
8
+ }
9
+ export declare class InitiateMultipartUploadResponseDto {
10
+ upload_id: string;
11
+ file_id: number;
12
+ file_key: string;
13
+ }
14
+ export declare class GetPartPresignedUrlDto {
15
+ upload_id: string;
16
+ file_key: string;
17
+ part_number: number;
18
+ }
19
+ export declare class GetPartPresignedUrlResponseDto {
20
+ presigned_url: string;
21
+ }
22
+ export declare class MultipartPartDto {
23
+ part_number: number;
24
+ etag: string;
25
+ }
26
+ export declare class CompleteMultipartUploadDto {
27
+ upload_id: string;
28
+ file_key: string;
29
+ parts: MultipartPartDto[];
30
+ }
31
+ export declare class CompleteMultipartUploadResponseDto {
32
+ id: number;
33
+ original_name: string;
34
+ file_name: string;
35
+ path: string;
36
+ mime_type: string;
37
+ size: number;
38
+ full_url: string;
39
+ target: string;
40
+ }
@@ -0,0 +1 @@
1
+ var e=this&&this.__decorate||function(e,t,p,o){var i,r=arguments.length,a=r<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,p):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,p,o);else for(var l=e.length-1;l>=0;l--)(i=e[l])&&(a=(r<3?i(a):r>3?i(t,p,a):i(t,p))||a);return r>3&&a&&Object.defineProperty(t,p,a),a},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.CompleteMultipartUploadResponseDto=exports.CompleteMultipartUploadDto=exports.MultipartPartDto=exports.GetPartPresignedUrlResponseDto=exports.GetPartPresignedUrlDto=exports.InitiateMultipartUploadResponseDto=exports.InitiateMultipartUploadDto=void 0;const p=require("@nestjs/swagger"),o=require("class-transformer"),i=require("class-validator");class InitiateMultipartUploadDto{}exports.InitiateMultipartUploadDto=InitiateMultipartUploadDto,e([(0,p.ApiProperty)({example:"videos",description:"File category"}),(0,i.IsString)(),t("design:type",String)],InitiateMultipartUploadDto.prototype,"target",void 0),e([(0,p.ApiProperty)({example:1,description:"Group number"}),(0,i.IsNumber)(),t("design:type",Number)],InitiateMultipartUploadDto.prototype,"group_number",void 0),e([(0,p.ApiProperty)({example:"video.mp4",description:"Original file name"}),(0,i.IsString)(),t("design:type",String)],InitiateMultipartUploadDto.prototype,"file_name",void 0),e([(0,p.ApiProperty)({example:"video/mp4",description:"MIME type"}),(0,i.IsString)(),t("design:type",String)],InitiateMultipartUploadDto.prototype,"mime_type",void 0),e([(0,p.ApiProperty)({example:104857600,description:"File size in bytes"}),(0,i.IsNumber)(),t("design:type",Number)],InitiateMultipartUploadDto.prototype,"size",void 0),e([(0,p.ApiProperty)({example:{width:1920,height:1080},description:"File metadata (optional)",required:!1}),(0,i.IsOptional)(),(0,i.IsObject)(),t("design:type",Object)],InitiateMultipartUploadDto.prototype,"meta",void 0);class InitiateMultipartUploadResponseDto{}exports.InitiateMultipartUploadResponseDto=InitiateMultipartUploadResponseDto,e([(0,p.ApiProperty)({example:"abc123uploadid",description:"S3 Multipart Upload ID"}),t("design:type",String)],InitiateMultipartUploadResponseDto.prototype,"upload_id",void 0),e([(0,p.ApiProperty)({example:123,description:"Created file ID in database"}),t("design:type",Number)],InitiateMultipartUploadResponseDto.prototype,"file_id",void 0),e([(0,p.ApiProperty)({example:"uploads/videos/250112/abc123.mp4",description:"S3 file key (프론트엔드가 관리)"}),t("design:type",String)],InitiateMultipartUploadResponseDto.prototype,"file_key",void 0);class GetPartPresignedUrlDto{}exports.GetPartPresignedUrlDto=GetPartPresignedUrlDto,e([(0,p.ApiProperty)({example:"abc123uploadid",description:"S3 Multipart Upload ID"}),(0,i.IsString)(),t("design:type",String)],GetPartPresignedUrlDto.prototype,"upload_id",void 0),e([(0,p.ApiProperty)({example:"uploads/videos/250112/abc123.mp4",description:"S3 file key (from initiate response)"}),(0,i.IsString)(),t("design:type",String)],GetPartPresignedUrlDto.prototype,"file_key",void 0),e([(0,p.ApiProperty)({example:1,description:"Part number (starts from 1)"}),(0,i.IsNumber)(),t("design:type",Number)],GetPartPresignedUrlDto.prototype,"part_number",void 0);class GetPartPresignedUrlResponseDto{}exports.GetPartPresignedUrlResponseDto=GetPartPresignedUrlResponseDto,e([(0,p.ApiProperty)({example:"https://s3.amazonaws.com/bucket/key?...",description:"Presigned URL for uploading part"}),t("design:type",String)],GetPartPresignedUrlResponseDto.prototype,"presigned_url",void 0);class MultipartPartDto{}exports.MultipartPartDto=MultipartPartDto,e([(0,p.ApiProperty)({example:1,description:"Part number"}),(0,i.IsNumber)(),t("design:type",Number)],MultipartPartDto.prototype,"part_number",void 0),e([(0,p.ApiProperty)({example:'"abc123etag"',description:"ETag from S3 response"}),(0,i.IsString)(),t("design:type",String)],MultipartPartDto.prototype,"etag",void 0);class CompleteMultipartUploadDto{}exports.CompleteMultipartUploadDto=CompleteMultipartUploadDto,e([(0,p.ApiProperty)({example:"abc123uploadid",description:"S3 Multipart Upload ID"}),(0,i.IsString)(),t("design:type",String)],CompleteMultipartUploadDto.prototype,"upload_id",void 0),e([(0,p.ApiProperty)({example:"uploads/videos/250112/abc123.mp4",description:"S3 file key (from initiate response)"}),(0,i.IsString)(),t("design:type",String)],CompleteMultipartUploadDto.prototype,"file_key",void 0),e([(0,p.ApiProperty)({type:[MultipartPartDto],description:"List of uploaded parts with ETags"}),(0,i.IsArray)(),(0,i.ValidateNested)({each:!0}),(0,o.Type)(()=>MultipartPartDto),t("design:type",Array)],CompleteMultipartUploadDto.prototype,"parts",void 0);class CompleteMultipartUploadResponseDto{}exports.CompleteMultipartUploadResponseDto=CompleteMultipartUploadResponseDto,e([(0,p.ApiProperty)({example:123,description:"File ID"}),t("design:type",Number)],CompleteMultipartUploadResponseDto.prototype,"id",void 0),e([(0,p.ApiProperty)({example:"video.mp4",description:"Original file name"}),t("design:type",String)],CompleteMultipartUploadResponseDto.prototype,"original_name",void 0),e([(0,p.ApiProperty)({example:"abc123.mp4",description:"Stored file name"}),t("design:type",String)],CompleteMultipartUploadResponseDto.prototype,"file_name",void 0),e([(0,p.ApiProperty)({example:"250112",description:"File path (YYMMDD)"}),t("design:type",String)],CompleteMultipartUploadResponseDto.prototype,"path",void 0),e([(0,p.ApiProperty)({example:"video/mp4",description:"MIME type"}),t("design:type",String)],CompleteMultipartUploadResponseDto.prototype,"mime_type",void 0),e([(0,p.ApiProperty)({example:104857600,description:"File size in bytes"}),t("design:type",Number)],CompleteMultipartUploadResponseDto.prototype,"size",void 0),e([(0,p.ApiProperty)({example:"https://cdn.example.com/uploads/videos/250112/abc123.mp4",description:"Full CDN URL"}),t("design:type",String)],CompleteMultipartUploadResponseDto.prototype,"full_url",void 0),e([(0,p.ApiProperty)({example:"videos",description:"File category"}),t("design:type",String)],CompleteMultipartUploadResponseDto.prototype,"target",void 0);
@@ -1,4 +1,5 @@
1
1
  export * from './aws.module';
2
2
  export * from './aws.service';
3
3
  export * from './aws-s3.service';
4
+ export * from './aws-s3-multipart.service';
4
5
  export * from './dto';
package/dist/aws/index.js CHANGED
@@ -1 +1 @@
1
- var e=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var i in r)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||e(t,r,i)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./aws.module"),exports),r(require("./aws.service"),exports),r(require("./aws-s3.service"),exports),r(require("./dto"),exports);
1
+ var e=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var i in r)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||e(t,r,i)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./aws.module"),exports),r(require("./aws.service"),exports),r(require("./aws-s3.service"),exports),r(require("./aws-s3-multipart.service"),exports),r(require("./dto"),exports);
@@ -1,5 +1,6 @@
1
1
  import { DataSource, Repository } from 'typeorm';
2
2
  import { Category } from '../database/entities';
3
+ import { CustomParamsDto } from '../dto/custom-params.dto';
3
4
  import { CreateCategoryBaseDto, UpdateCategoryBaseDto, UpdateCategorySortBaseDto } from './dto';
4
5
  export declare class CategoryService {
5
6
  protected readonly repository: Repository<Category>;
@@ -18,6 +19,16 @@ export declare class CategoryService {
18
19
  findAll(type: string): Promise<{
19
20
  items: Category[];
20
21
  }>;
22
+ findAllPaginated(c_params: CustomParamsDto, type: string): Promise<{
23
+ items: Category[];
24
+ pagination: {
25
+ page: number;
26
+ limit: number;
27
+ count: number;
28
+ count_total: number;
29
+ count_page: number;
30
+ };
31
+ }>;
21
32
  findOne(id: number): Promise<Category>;
22
33
  update(id: number, body: UpdateCategoryBaseDto): Promise<Category>;
23
34
  remove(id: number): Promise<void>;
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,r){var o,n=arguments.length,s=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,r);else for(var d=e.length-1;d>=0;d--)(o=e[d])&&(s=(n<3?o(s):n>3?o(t,i,s):o(t,i))||s);return n>3&&s&&Object.defineProperty(t,i,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__param||function(e,t){return function(i,r){t(i,r,e)}},r=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(o,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?o(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.CategoryService=void 0;const o=require("@nestjs/common"),n=require("@nestjs/typeorm"),s=require("typeorm"),d=require("../database/entities"),a=require("../shared/error-codes");let c=class CategoryService{constructor(e,t){this.repository=e,this.dataSource=t}validateCategoryLimit(e){return r(this,void 0,void 0,function*(){throw new o.BadRequestException("validateCategoryLimit must be implemented in app service")})}checkCategoryUsage(e){return r(this,void 0,void 0,function*(){throw new o.BadRequestException("checkCategoryUsage must be implemented in app service")})}create(e){return r(this,void 0,void 0,function*(){const{type:t,name:i,description:r,slug:n}=e;yield this.validateCategoryLimit(t);if(yield this.repository.findOne({where:{type:t,name:i}}))throw new o.ConflictException({message:"Category name already exists",error_code:a.ErrorCode.CATEGORY_NAME_ALREADY_EXISTS});const s=(yield this.repository.count({where:{type:t}}))+1;return yield this.repository.save(Object.assign(Object.assign({},e),{sort:s}))})}findAll(e){return r(this,void 0,void 0,function*(){return{items:yield this.repository.find({where:{type:e},order:{sort:"ASC"}})}})}findOne(e){return r(this,void 0,void 0,function*(){const t=yield this.repository.findOne({where:{id:e}});if(!t)throw new o.NotFoundException(`Category with ID ${e} not found`);return t})}update(e,t){return r(this,void 0,void 0,function*(){const i=yield this.repository.findOne({where:{id:e}});if(!i)throw new o.NotFoundException(`Category with ID ${e} not found`);if(yield this.repository.findOne({where:{type:i.type,name:t.name,id:(0,s.Not)(e)}}))throw new o.ConflictException({message:"Category name already exists",error_code:a.ErrorCode.CATEGORY_NAME_ALREADY_EXISTS});yield this.repository.update(e,t);return yield this.repository.findOne({where:{id:e}})})}remove(e){return r(this,void 0,void 0,function*(){if(!(yield this.repository.findOne({where:{id:e}})))throw new o.NotFoundException(`Category with ID ${e} not found`);yield this.checkCategoryUsage(e),yield this.repository.update(e,{is_active:!1,deleted_at:new Date})})}updateSort(e){return r(this,void 0,void 0,function*(){const{items:t,type:i}=e,r=yield this.repository.find({where:{type:i}});if(r.length!==t.length)throw new o.BadRequestException("Invalid items ids provided");const n=r.map(e=>{var i;return Object.assign(Object.assign({},e),{sort:(null===(i=t.find(t=>t.id===e.id))||void 0===i?void 0:i.sort)||e.sort})});yield this.repository.save(n)})}};exports.CategoryService=c,exports.CategoryService=c=e([(0,o.Injectable)(),i(0,(0,n.InjectRepository)(d.Category)),t("design:paramtypes",[s.Repository,s.DataSource])],c);
1
+ var e=this&&this.__decorate||function(e,t,i,r){var o,n=arguments.length,s=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,r);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(s=(n<3?o(s):n>3?o(t,i,s):o(t,i))||s);return n>3&&s&&Object.defineProperty(t,i,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__param||function(e,t){return function(i,r){t(i,r,e)}},r=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(o,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?o(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.CategoryService=void 0;const o=require("@nestjs/common"),n=require("@nestjs/typeorm"),s=require("typeorm"),a=require("../database/entities"),d=require("../shared/error-codes"),c=require("../utils"),u=require("../utils/pagination-qb.utils");let y=class CategoryService{constructor(e,t){this.repository=e,this.dataSource=t}validateCategoryLimit(e){return r(this,void 0,void 0,function*(){throw new o.BadRequestException("validateCategoryLimit must be implemented in app service")})}checkCategoryUsage(e){return r(this,void 0,void 0,function*(){throw new o.BadRequestException("checkCategoryUsage must be implemented in app service")})}create(e){return r(this,void 0,void 0,function*(){const{type:t,name:i,description:r,slug:n}=e;yield this.validateCategoryLimit(t);if(yield this.repository.findOne({where:{type:t,name:i}}))throw new o.ConflictException({message:"Category name already exists",error_code:d.ErrorCode.CATEGORY_NAME_ALREADY_EXISTS});const s=(yield this.repository.count({where:{type:t}}))+1;return yield this.repository.save(Object.assign(Object.assign({},e),{sort:s}))})}findAll(e){return r(this,void 0,void 0,function*(){return{items:yield this.repository.find({where:{type:e},order:{sort:"ASC"}})}})}findAllPaginated(e,t){return r(this,void 0,void 0,function*(){const{_page:i,_limit:r,_keyword:o,_group:n,_sort:s}=e;let a=this.repository.createQueryBuilder("category").where("category.type = :type",{type:t});a=(0,u.applyFiltersAndSorting)(a,{_keyword:o,_group:n,_sort:s,keywordFields:["name"],aliasName:"category"});return yield(0,c.paginate)(a,{page:i,limit:r})})}findOne(e){return r(this,void 0,void 0,function*(){const t=yield this.repository.findOne({where:{id:e}});if(!t)throw new o.NotFoundException(`Category with ID ${e} not found`);return t})}update(e,t){return r(this,void 0,void 0,function*(){const i=yield this.repository.findOne({where:{id:e}});if(!i)throw new o.NotFoundException(`Category with ID ${e} not found`);if(yield this.repository.findOne({where:{type:i.type,name:t.name,id:(0,s.Not)(e)}}))throw new o.ConflictException({message:"Category name already exists",error_code:d.ErrorCode.CATEGORY_NAME_ALREADY_EXISTS});yield this.repository.update(e,t);return yield this.repository.findOne({where:{id:e}})})}remove(e){return r(this,void 0,void 0,function*(){if(!(yield this.repository.findOne({where:{id:e}})))throw new o.NotFoundException(`Category with ID ${e} not found`);yield this.checkCategoryUsage(e),yield this.repository.update(e,{is_active:!1,deleted_at:new Date})})}updateSort(e){return r(this,void 0,void 0,function*(){const{items:t,type:i}=e,r=yield this.repository.find({where:{type:i}});if(r.length!==t.length)throw new o.BadRequestException("Invalid items ids provided");const n=r.map(e=>{var i;return Object.assign(Object.assign({},e),{sort:(null===(i=t.find(t=>t.id===e.id))||void 0===i?void 0:i.sort)||e.sort})});yield this.repository.save(n)})}};exports.CategoryService=y,exports.CategoryService=y=e([(0,o.Injectable)(),i(0,(0,n.InjectRepository)(a.Category)),t("design:paramtypes",[s.Repository,s.DataSource])],y);
@@ -1,18 +1,20 @@
1
- import { FILE_STATUS } from '../../enums.common';
1
+ import { FILE_STATUS, FILE_STORAGE_TYPE } from '../../enums.common';
2
2
  export declare class File {
3
3
  id: number;
4
4
  status: FILE_STATUS;
5
+ storage_type: FILE_STORAGE_TYPE;
5
6
  target: string;
6
7
  target_id: number;
7
8
  user_id: number;
8
- original_name: string;
9
+ original_name?: string;
9
10
  file_name: string;
10
11
  path: string;
11
- mime_type: string;
12
- size: number;
12
+ mime_type?: string;
13
+ size?: number;
13
14
  meta: Record<string, any>;
14
15
  group_number: number;
15
16
  sort: number;
17
+ has_thumbnail: boolean;
16
18
  is_active: boolean;
17
19
  created_at: Date;
18
20
  updated_at: Date;
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,o,i){var n,r=arguments.length,p=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)p=Reflect.decorate(e,t,o,i);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(p=(r<3?n(p):r>3?n(t,o,p):n(t,o))||p);return r>3&&p&&Object.defineProperty(t,o,p),p},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.File=void 0;const o=require("typeorm"),i=require("../../enums.common");let n=class File{};exports.File=n,e([(0,o.PrimaryGeneratedColumn)({name:"id",primaryKeyConstraintName:"PK_files"}),t("design:type",Number)],n.prototype,"id",void 0),e([(0,o.Column)("enum",{enum:i.FILE_STATUS}),t("design:type",String)],n.prototype,"status",void 0),e([(0,o.Column)("varchar",{length:25}),t("design:type",String)],n.prototype,"target",void 0),e([(0,o.Column)("int"),t("design:type",Number)],n.prototype,"target_id",void 0),e([(0,o.Column)("int",{nullable:!0}),t("design:type",Number)],n.prototype,"user_id",void 0),e([(0,o.Column)("varchar",{length:255}),t("design:type",String)],n.prototype,"original_name",void 0),e([(0,o.Column)("varchar",{length:255,comment:"UUID 기반 파일명"}),t("design:type",String)],n.prototype,"file_name",void 0),e([(0,o.Column)("varchar",{length:255,comment:"[target]/YYMMDD/[file_name]"}),t("design:type",String)],n.prototype,"path",void 0),e([(0,o.Column)("varchar",{length:100}),t("design:type",String)],n.prototype,"mime_type",void 0),e([(0,o.Column)("int"),t("design:type",Number)],n.prototype,"size",void 0),e([(0,o.Column)("jsonb",{nullable:!0}),t("design:type",Object)],n.prototype,"meta",void 0),e([(0,o.Column)("smallint",{default:0,comment:"0: cover, 1: details ..."}),t("design:type",Number)],n.prototype,"group_number",void 0),e([(0,o.Column)("int",{default:0}),t("design:type",Number)],n.prototype,"sort",void 0),e([(0,o.Column)("boolean",{default:!0}),t("design:type",Boolean)],n.prototype,"is_active",void 0),e([(0,o.CreateDateColumn)({type:"timestamptz"}),t("design:type",Date)],n.prototype,"created_at",void 0),e([(0,o.UpdateDateColumn)({type:"timestamptz"}),t("design:type",Date)],n.prototype,"updated_at",void 0),e([(0,o.DeleteDateColumn)({type:"timestamptz"}),t("design:type",Date)],n.prototype,"deleted_at",void 0),exports.File=n=e([(0,o.Entity)("files"),(0,o.Index)("IDX_files",["id"],{where:"deleted_at IS NULL"}),(0,o.Index)("IDX_files_target_target_id",["target","target_id"]),(0,o.Index)("IDX_files_user_id",["user_id"])],n);
1
+ var e=this&&this.__decorate||function(e,t,o,n){var i,r=arguments.length,a=r<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,o):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,n);else for(var l=e.length-1;l>=0;l--)(i=e[l])&&(a=(r<3?i(a):r>3?i(t,o,a):i(t,o))||a);return r>3&&a&&Object.defineProperty(t,o,a),a},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.File=void 0;const o=require("typeorm"),n=require("../../enums.common");let i=class File{};exports.File=i,e([(0,o.PrimaryGeneratedColumn)({name:"id",primaryKeyConstraintName:"PK_files"}),t("design:type",Number)],i.prototype,"id",void 0),e([(0,o.Column)("enum",{enum:n.FILE_STATUS}),t("design:type",String)],i.prototype,"status",void 0),e([(0,o.Column)("enum",{enum:n.FILE_STORAGE_TYPE,default:n.FILE_STORAGE_TYPE.AWS}),t("design:type",String)],i.prototype,"storage_type",void 0),e([(0,o.Column)("varchar",{length:25}),t("design:type",String)],i.prototype,"target",void 0),e([(0,o.Column)("int"),t("design:type",Number)],i.prototype,"target_id",void 0),e([(0,o.Column)("int",{nullable:!0}),t("design:type",Number)],i.prototype,"user_id",void 0),e([(0,o.Column)("varchar",{length:255,nullable:!0}),t("design:type",String)],i.prototype,"original_name",void 0),e([(0,o.Column)("varchar",{length:255,comment:"object storage: UUID 기반 파일명, remote: file_url"}),t("design:type",String)],i.prototype,"file_name",void 0),e([(0,o.Column)("varchar",{length:255,comment:"object storage: [target]/[path:YYMMDD]/[file_name], remote: file_url"}),t("design:type",String)],i.prototype,"path",void 0),e([(0,o.Column)("varchar",{length:100,nullable:!0}),t("design:type",String)],i.prototype,"mime_type",void 0),e([(0,o.Column)("int",{nullable:!0}),t("design:type",Number)],i.prototype,"size",void 0),e([(0,o.Column)("jsonb",{nullable:!0}),t("design:type",Object)],i.prototype,"meta",void 0),e([(0,o.Column)("smallint",{default:0,comment:"0: cover, 1: details ..."}),t("design:type",Number)],i.prototype,"group_number",void 0),e([(0,o.Column)("int",{default:0}),t("design:type",Number)],i.prototype,"sort",void 0),e([(0,o.Column)("boolean",{default:!0}),t("design:type",Boolean)],i.prototype,"has_thumbnail",void 0),e([(0,o.Column)("boolean",{default:!0}),t("design:type",Boolean)],i.prototype,"is_active",void 0),e([(0,o.CreateDateColumn)({type:"timestamptz"}),t("design:type",Date)],i.prototype,"created_at",void 0),e([(0,o.UpdateDateColumn)({type:"timestamptz"}),t("design:type",Date)],i.prototype,"updated_at",void 0),e([(0,o.DeleteDateColumn)({type:"timestamptz"}),t("design:type",Date)],i.prototype,"deleted_at",void 0),exports.File=i=e([(0,o.Entity)("files"),(0,o.Index)("IDX_files",["id"],{where:"deleted_at IS NULL"}),(0,o.Index)("IDX_files_target_target_id",["target","target_id"]),(0,o.Index)("IDX_files_user_id",["user_id"])],i);
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,n){var o,a=arguments.length,r=a<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,i,n);else for(var p=e.length-1;p>=0;p--)(o=e[p])&&(r=(a<3?o(r):a>3?o(t,i,r):o(t,i))||r);return a>3&&r&&Object.defineProperty(t,i,r),r},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationRecipient=void 0;const i=require("typeorm"),n=require("../../enums.common"),o=require("./notification.entity");class Relations{}e([(0,i.ManyToOne)(()=>o.Notification,e=>e.recipients),(0,i.JoinColumn)({name:"notification_id",foreignKeyConstraintName:"FK_nrecipients_notification_id"}),t("design:type",o.Notification)],Relations.prototype,"notification",void 0);let a=class NotificationRecipient extends Relations{};exports.NotificationRecipient=a,e([(0,i.PrimaryGeneratedColumn)({name:"id",primaryKeyConstraintName:"PK_nrecipients"}),t("design:type",Number)],a.prototype,"id",void 0),e([(0,i.Column)("int"),t("design:type",Number)],a.prototype,"notification_id",void 0),e([(0,i.Column)("varchar",{length:25,nullable:!0}),t("design:type",String)],a.prototype,"type",void 0),e([(0,i.Column)("int"),t("design:type",Number)],a.prototype,"user_id",void 0),e([(0,i.Column)("varchar",{length:100,nullable:!0}),t("design:type",String)],a.prototype,"recipient",void 0),e([(0,i.Column)("varchar",{length:255,nullable:!0}),t("design:type",String)],a.prototype,"title",void 0),e([(0,i.Column)("text",{nullable:!0}),t("design:type",String)],a.prototype,"content",void 0),e([(0,i.Column)("jsonb",{nullable:!0}),t("design:type",Object)],a.prototype,"meta",void 0),e([(0,i.Column)("jsonb",{nullable:!0}),t("design:type",Object)],a.prototype,"variables",void 0),e([(0,i.Column)("enum",{enum:n.NOTIFICATION_STATUS}),t("design:type",String)],a.prototype,"status",void 0),e([(0,i.Column)("timestamptz",{nullable:!0}),t("design:type",Date)],a.prototype,"sent_at",void 0),e([(0,i.Column)("timestamptz",{nullable:!0}),t("design:type",Date)],a.prototype,"read_at",void 0),e([(0,i.Column)("timestamptz",{nullable:!0}),t("design:type",Date)],a.prototype,"failed_at",void 0),e([(0,i.Column)("varchar",{length:255,nullable:!0}),t("design:type",String)],a.prototype,"reason_failed",void 0),e([(0,i.CreateDateColumn)({type:"timestamptz"}),t("design:type",Date)],a.prototype,"created_at",void 0),exports.NotificationRecipient=a=e([(0,i.Entity)("notification_recipients"),(0,i.Index)("IDX_nrecipients_notification_id_status",["notification_id","status"]),(0,i.Index)("IDX_nrecipients_user_id",["user_id"]),(0,i.Index)("IDX_nrecipients_type",["type"])],a);
1
+ var e=this&&this.__decorate||function(e,t,i,n){var o,a=arguments.length,r=a<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,i,n);else for(var p=e.length-1;p>=0;p--)(o=e[p])&&(r=(a<3?o(r):a>3?o(t,i,r):o(t,i))||r);return a>3&&r&&Object.defineProperty(t,i,r),r},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationRecipient=void 0;const i=require("typeorm"),n=require("../../enums.common"),o=require("./notification.entity");class Relations{}e([(0,i.ManyToOne)(()=>o.Notification,e=>e.recipients),(0,i.JoinColumn)({name:"notification_id",foreignKeyConstraintName:"FK_nrecipients_notification_id"}),t("design:type",o.Notification)],Relations.prototype,"notification",void 0);let a=class NotificationRecipient extends Relations{};exports.NotificationRecipient=a,e([(0,i.PrimaryGeneratedColumn)({name:"id",primaryKeyConstraintName:"PK_nrecipients"}),t("design:type",Number)],a.prototype,"id",void 0),e([(0,i.Column)("int"),t("design:type",Number)],a.prototype,"notification_id",void 0),e([(0,i.Column)("varchar",{length:25,nullable:!0}),t("design:type",String)],a.prototype,"type",void 0),e([(0,i.Column)("int",{nullable:!0}),t("design:type",Number)],a.prototype,"user_id",void 0),e([(0,i.Column)("varchar",{length:100,nullable:!0}),t("design:type",String)],a.prototype,"recipient",void 0),e([(0,i.Column)("varchar",{length:255,nullable:!0}),t("design:type",String)],a.prototype,"title",void 0),e([(0,i.Column)("text",{nullable:!0}),t("design:type",String)],a.prototype,"content",void 0),e([(0,i.Column)("jsonb",{nullable:!0}),t("design:type",Object)],a.prototype,"meta",void 0),e([(0,i.Column)("jsonb",{nullable:!0}),t("design:type",Object)],a.prototype,"variables",void 0),e([(0,i.Column)("enum",{enum:n.NOTIFICATION_STATUS}),t("design:type",String)],a.prototype,"status",void 0),e([(0,i.Column)("timestamptz",{nullable:!0}),t("design:type",Date)],a.prototype,"sent_at",void 0),e([(0,i.Column)("timestamptz",{nullable:!0}),t("design:type",Date)],a.prototype,"read_at",void 0),e([(0,i.Column)("timestamptz",{nullable:!0}),t("design:type",Date)],a.prototype,"failed_at",void 0),e([(0,i.Column)("varchar",{length:255,nullable:!0}),t("design:type",String)],a.prototype,"reason_failed",void 0),e([(0,i.CreateDateColumn)({type:"timestamptz"}),t("design:type",Date)],a.prototype,"created_at",void 0),exports.NotificationRecipient=a=e([(0,i.Entity)("notification_recipients"),(0,i.Index)("IDX_nrecipients_notification_id_status",["notification_id","status"]),(0,i.Index)("IDX_nrecipients_user_id",["user_id"]),(0,i.Index)("IDX_nrecipients_type",["type"])],a);
@@ -0,0 +1,2 @@
1
+ export declare function FormatPhone(): PropertyDecorator;
2
+ export declare function FormatBizNo(): PropertyDecorator;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.FormatPhone=function FormatPhone(){return(0,e.Transform)(({value:e})=>{if("string"!=typeof e||""===e.trim())return e;const r=e.replace(/\D/g,"");if(/^(15|16|18)\d{6}$/.test(r))return r.replace(/^((?:15|16|18)\d{2})(\d{4})$/,"$1-$2");if(/^02\d{7,8}$/.test(r)){if(9===r.length)return r.replace(/^(02)(\d{3})(\d{4})$/,"$1-$2-$3");if(10===r.length)return r.replace(/^(02)(\d{4})(\d{4})$/,"$1-$2-$3")}if(/^0\d{9,10}$/.test(r)){if(10===r.length)return r.replace(/^(0\d{2})(\d{3})(\d{4})$/,"$1-$2-$3");if(11===r.length)return r.replace(/^(0\d{2})(\d{4})(\d{4})$/,"$1-$2-$3")}return/^\d{11}$/.test(r)?r.replace(/^(\d{3})(\d{4})(\d{4})$/,"$1-$2-$3"):/^\d{8}$/.test(r)?r.replace(/^(\d{4})(\d{4})$/,"$1-$2"):e})},exports.FormatBizNo=function FormatBizNo(){return(0,e.Transform)(({value:e})=>"string"==typeof e&&10===e.length?e.replace(/(\d{3})(\d{2})(\d{5})/,"$1-$2-$3"):e)};const e=require("class-transformer");
@@ -4,3 +4,5 @@ export * from './patch-body.decorator';
4
4
  export * from './cookies.decorator';
5
5
  export * from './timestamps.decorator';
6
6
  export * from './soft-delete.decorator';
7
+ export * from './format.decorator';
8
+ export * from './masking.transform';
@@ -1 +1 @@
1
- var e=this&&this.__createBinding||(Object.create?function(e,r,t,o){void 0===o&&(o=t);var i=Object.getOwnPropertyDescriptor(r,t);i&&!("get"in i?!r.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,o,i)}:function(e,r,t,o){void 0===o&&(o=t),e[o]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var o in r)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||e(t,r,o)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./custom-params.decorator"),exports),r(require("./api-custom-params.decorator"),exports),r(require("./patch-body.decorator"),exports),r(require("./cookies.decorator"),exports),r(require("./timestamps.decorator"),exports),r(require("./soft-delete.decorator"),exports);
1
+ var e=this&&this.__createBinding||(Object.create?function(e,r,t,o){void 0===o&&(o=t);var i=Object.getOwnPropertyDescriptor(r,t);i&&!("get"in i?!r.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,o,i)}:function(e,r,t,o){void 0===o&&(o=t),e[o]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var o in r)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||e(t,r,o)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./custom-params.decorator"),exports),r(require("./api-custom-params.decorator"),exports),r(require("./patch-body.decorator"),exports),r(require("./cookies.decorator"),exports),r(require("./timestamps.decorator"),exports),r(require("./soft-delete.decorator"),exports),r(require("./format.decorator"),exports),r(require("./masking.transform"),exports);
@@ -0,0 +1,2 @@
1
+ export declare const MaskPhone: () => PropertyDecorator;
2
+ export declare const MaskEmail: () => PropertyDecorator;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.MaskEmail=exports.MaskPhone=void 0;const e=require("class-transformer");exports.MaskPhone=()=>(0,e.Transform)(({value:e})=>{if("string"==typeof e){const r=e.replace(/\D/g,"");return 11===r.length?`${r.slice(0,3)}-${r.slice(3,5)}**-${r.slice(7,9)}**`:e.replace(/(\d{3})-(\d{2})\d+-(\d{2})\d+/,"$1-$2**-$3**")}return e});exports.MaskEmail=()=>(0,e.Transform)(({value:e})=>{if("string"==typeof e){const[r,s]=e.split("@"),t=r.slice(0,2)+"*".repeat(r.length-2);return s?`${t}@${s}`:t}return e});
@@ -1,6 +1,9 @@
1
1
  declare class FileMetaDto {
2
2
  width?: number;
3
3
  height?: number;
4
+ orientation?: number;
5
+ duration?: number;
6
+ encoding?: string;
4
7
  }
5
8
  export declare class FileDto {
6
9
  id: number;
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,o,i){var r,s=arguments.length,l=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,o,i);else for(var p=e.length-1;p>=0;p--)(r=e[p])&&(l=(s<3?r(l):s>3?r(t,o,l):r(t,o))||l);return s>3&&l&&Object.defineProperty(t,o,l),l},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileThumbnailDto=exports.FileDto=void 0;const o=require("@nestjs/swagger"),i=require("class-transformer");class FileMetaDto{}e([(0,i.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"width",void 0),e([(0,i.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"height",void 0);class FileDto{}exports.FileDto=FileDto,e([(0,i.Expose)(),t("design:type",Number)],FileDto.prototype,"id",void 0),e([(0,i.Expose)(),t("design:type",String)],FileDto.prototype,"original_name",void 0),e([(0,i.Expose)(),t("design:type",String)],FileDto.prototype,"mime_type",void 0),e([(0,i.Expose)(),t("design:type",Number)],FileDto.prototype,"size",void 0),e([(0,i.Expose)(),(0,i.Transform)(({obj:e})=>`${process.env.CDN_URL||""}/uploads/${e.target}/${e.path}/${e.file_name}`),t("design:type",String)],FileDto.prototype,"full_url",void 0),e([(0,i.Expose)(),(0,i.Transform)(({obj:e})=>{var t;return(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/"))?`${process.env.CDN_URL||""}/thumbnails/${e.target}/${e.path}/sm/${e.file_name}`:void 0}),t("design:type",String)],FileDto.prototype,"thumbnail_small",void 0),e([(0,i.Expose)(),(0,i.Transform)(({obj:e})=>{var t;return(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/"))?`${process.env.CDN_URL||""}/thumbnails/${e.target}/${e.path}/md/${e.file_name}`:void 0}),t("design:type",String)],FileDto.prototype,"thumbnail_medium",void 0),e([(0,i.Expose)(),(0,i.Type)(()=>FileMetaDto),(0,i.Transform)(({obj:e})=>e.meta),t("design:type",FileMetaDto)],FileDto.prototype,"meta",void 0);class FileThumbnailDto extends((0,o.PickType)(FileDto,["thumbnail_small","thumbnail_medium"])){}exports.FileThumbnailDto=FileThumbnailDto;
1
+ var e=this&&this.__decorate||function(e,t,o,i){var r,p=arguments.length,s=p<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,o,i);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(s=(p<3?r(s):p>3?r(t,o,s):r(t,o))||s);return p>3&&s&&Object.defineProperty(t,o,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileThumbnailDto=exports.FileDto=void 0;const o=require("@nestjs/swagger"),i=require("class-transformer");class FileMetaDto{}e([(0,i.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"width",void 0),e([(0,i.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"height",void 0),e([(0,i.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"orientation",void 0),e([(0,i.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"duration",void 0),e([(0,i.Expose)(),t("design:type",String)],FileMetaDto.prototype,"encoding",void 0);class FileDto{}exports.FileDto=FileDto,e([(0,i.Expose)(),t("design:type",Number)],FileDto.prototype,"id",void 0),e([(0,i.Expose)(),t("design:type",String)],FileDto.prototype,"original_name",void 0),e([(0,i.Expose)(),t("design:type",String)],FileDto.prototype,"mime_type",void 0),e([(0,i.Expose)(),t("design:type",Number)],FileDto.prototype,"size",void 0),e([(0,i.Expose)(),(0,i.Transform)(({obj:e})=>`${process.env.CDN_URL||""}/uploads/${e.target}/${e.path}/${e.file_name}`),t("design:type",String)],FileDto.prototype,"full_url",void 0),e([(0,i.Expose)(),(0,i.Transform)(({obj:e})=>{var t;return(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/"))?`${process.env.CDN_URL||""}/thumbnails/${e.target}/${e.path}/sm/${e.file_name}`:void 0}),t("design:type",String)],FileDto.prototype,"thumbnail_small",void 0),e([(0,i.Expose)(),(0,i.Transform)(({obj:e})=>{var t;return(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/"))?`${process.env.CDN_URL||""}/thumbnails/${e.target}/${e.path}/md/${e.file_name}`:void 0}),t("design:type",String)],FileDto.prototype,"thumbnail_medium",void 0),e([(0,i.Expose)(),(0,i.Type)(()=>FileMetaDto),(0,i.Transform)(({obj:e})=>e.meta),t("design:type",FileMetaDto)],FileDto.prototype,"meta",void 0);class FileThumbnailDto extends((0,o.PickType)(FileDto,["thumbnail_small","thumbnail_medium"])){}exports.FileThumbnailDto=FileThumbnailDto;
@@ -40,6 +40,13 @@ export declare enum FILE_STATUS {
40
40
  FAILED = "failed",
41
41
  DELETED = "deleted"
42
42
  }
43
+ export declare enum FILE_STORAGE_TYPE {
44
+ AWS = "aws",
45
+ NCP = "ncp",
46
+ REMOTE = "remote",
47
+ LOCAL = "local",
48
+ OTHER = "other"
49
+ }
43
50
  export declare enum NOTIFICATION_STATUS {
44
51
  PENDING = "pending",
45
52
  SENT = "sent",
@@ -1 +1 @@
1
- var e,o,t,n,E,p,i;Object.defineProperty(exports,"__esModule",{value:!0}),exports.LIKE_TYPE=exports.NOTIFICATION_STATUS=exports.FILE_STATUS=exports.AUDIT_ACTION=exports.DEVICE_TYPE=exports.MIME_TYPE=exports.FILE_TYPE=void 0,function(e){e.IMAGE="IMAGE",e.VIDEO="VIDEO",e.DOCUMENT="DOCUMENT",e.AUDIO="AUDIO",e.OTHER="OTHER"}(e||(exports.FILE_TYPE=e={})),function(e){e.JPEG="image/jpeg",e.PNG="image/png",e.GIF="image/gif",e.PDF="application/pdf",e.DOC="application/msword",e.DOCX="application/vnd.openxmlformats-officedocument.wordprocessingml.document",e.XLS="application/vnd.ms-excel",e.XLSX="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",e.PPT="application/vnd.ms-powerpoint",e.PPTX="application/vnd.openxmlformats-officedocument.presentationml.presentation",e.TXT="text/plain",e.HTML="text/html",e.CSV="text/csv"}(o||(exports.MIME_TYPE=o={})),function(e){e.ANDROID="android",e.IOS="ios",e.PC="pc",e.MAC="mac",e.OTHER="other"}(t||(exports.DEVICE_TYPE=t={})),function(e){e.CREATE="create",e.READ="read",e.UPDATE="update",e.DELETE="delete",e.DOWNLOAD="download"}(n||(exports.AUDIT_ACTION=n={})),function(e){e.PENDING="pending",e.COMPLETED="completed",e.FAILED="failed",e.DELETED="deleted"}(E||(exports.FILE_STATUS=E={})),function(e){e.PENDING="pending",e.SENT="sent",e.READ="read",e.FAILED="failed"}(p||(exports.NOTIFICATION_STATUS=p={})),function(e){e.LIKE="like",e.DISLIKE="dislike",e.NONE="none"}(i||(exports.LIKE_TYPE=i={}));
1
+ var e,o,t,E,n,p,T,i;Object.defineProperty(exports,"__esModule",{value:!0}),exports.LIKE_TYPE=exports.NOTIFICATION_STATUS=exports.FILE_STORAGE_TYPE=exports.FILE_STATUS=exports.AUDIT_ACTION=exports.DEVICE_TYPE=exports.MIME_TYPE=exports.FILE_TYPE=void 0,function(e){e.IMAGE="IMAGE",e.VIDEO="VIDEO",e.DOCUMENT="DOCUMENT",e.AUDIO="AUDIO",e.OTHER="OTHER"}(e||(exports.FILE_TYPE=e={})),function(e){e.JPEG="image/jpeg",e.PNG="image/png",e.GIF="image/gif",e.PDF="application/pdf",e.DOC="application/msword",e.DOCX="application/vnd.openxmlformats-officedocument.wordprocessingml.document",e.XLS="application/vnd.ms-excel",e.XLSX="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",e.PPT="application/vnd.ms-powerpoint",e.PPTX="application/vnd.openxmlformats-officedocument.presentationml.presentation",e.TXT="text/plain",e.HTML="text/html",e.CSV="text/csv"}(o||(exports.MIME_TYPE=o={})),function(e){e.ANDROID="android",e.IOS="ios",e.PC="pc",e.MAC="mac",e.OTHER="other"}(t||(exports.DEVICE_TYPE=t={})),function(e){e.CREATE="create",e.READ="read",e.UPDATE="update",e.DELETE="delete",e.DOWNLOAD="download"}(E||(exports.AUDIT_ACTION=E={})),function(e){e.PENDING="pending",e.COMPLETED="completed",e.FAILED="failed",e.DELETED="deleted"}(n||(exports.FILE_STATUS=n={})),function(e){e.AWS="aws",e.NCP="ncp",e.REMOTE="remote",e.LOCAL="local",e.OTHER="other"}(p||(exports.FILE_STORAGE_TYPE=p={})),function(e){e.PENDING="pending",e.SENT="sent",e.READ="read",e.FAILED="failed"}(T||(exports.NOTIFICATION_STATUS=T={})),function(e){e.LIKE="like",e.DISLIKE="dislike",e.NONE="none"}(i||(exports.LIKE_TYPE=i={}));
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,a){var n,c=arguments.length,s=c<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,a);else for(var o=e.length-1;o>=0;o--)(n=e[o])&&(s=(c<3?n(s):c>3?n(t,i,s):n(t,i))||s);return c>3&&s&&Object.defineProperty(t,i,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,a){return new(i||(i=Promise))(function(n,c){function fulfilled(e){try{step(a.next(e))}catch(e){c(e)}}function rejected(e){try{step(a.throw(e))}catch(e){c(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((a=a.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EventNotificationService=void 0;const a=require("@nestjs/common"),n=require("../../notifications");let c=class EventNotificationService{constructor(e,t){this.notificationService=e,this.notificationSendService=t}send(e){return i(this,void 0,void 0,function*(){if(null==e?void 0:e.web){const t=yield this.notificationSendService.send({type:"web",recipients:e.web.recipients,template_key:e.web.template_key,variables:e.web.variables,meta:e.web.meta});console.log("📧 [EVENT-NOTIFICATION] Web 발송 결과:",t)}if(null==e?void 0:e.email){yield this.notificationService.create({type:"email",template_key:e.email.template_key,recipients:e.email.recipients,variables:e.email.variables});const t=yield this.notificationSendService.send({type:"email",recipients:e.email.recipients,subject:e.email.subject,body:e.email.body,template_key:e.email.template_key,variables:e.email.variables});console.log("📧 [EVENT-NOTIFICATION] Email 발송 결과:",t)}if(null==e?void 0:e.kakao){yield this.notificationService.create({type:"kakao",template_key:e.kakao.template_key,recipients:e.kakao.recipients,variables:e.kakao.variables});const t=yield this.notificationSendService.send({type:"kakao",recipients:e.kakao.recipients,template_key:e.kakao.template_key,variables:e.kakao.variables});console.log("📱 [EVENT-NOTIFICATION] Kakao 발송 결과:",t)}if(null==e?void 0:e.sms){yield this.notificationService.create({type:"sms",template_key:e.sms.template_key,recipients:e.sms.recipients,variables:e.sms.variables});const t=yield this.notificationSendService.send({type:"sms",recipients:e.sms.recipients,content:e.sms.content,template_key:e.sms.template_key,variables:e.sms.variables});console.log("📱 [EVENT-NOTIFICATION] SMS 발송 결과:",t)}if(null==e?void 0:e.slack){yield this.notificationService.create({type:"slack",template_key:e.slack.template_key,recipients:[{user_id:0,recipient:e.slack.channel}],variables:e.slack.variables});const t=yield this.notificationSendService.send({type:"slack",channel:e.slack.channel,content:e.slack.content,template_key:e.slack.template_key,variables:e.slack.variables});console.log("📢 [EVENT-NOTIFICATION] Slack 발송 결과:",t)}})}};exports.EventNotificationService=c,exports.EventNotificationService=c=e([(0,a.Injectable)(),t("design:paramtypes",[n.NotificationService,n.NotificationSendService])],c);
1
+ var e=this&&this.__decorate||function(e,t,i,a){var n,c=arguments.length,s=c<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,a);else for(var l=e.length-1;l>=0;l--)(n=e[l])&&(s=(c<3?n(s):c>3?n(t,i,s):n(t,i))||s);return c>3&&s&&Object.defineProperty(t,i,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,a){return new(i||(i=Promise))(function(n,c){function fulfilled(e){try{step(a.next(e))}catch(e){c(e)}}function rejected(e){try{step(a.throw(e))}catch(e){c(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((a=a.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EventNotificationService=void 0;const a=require("@nestjs/common"),n=require("../../notifications");let c=class EventNotificationService{constructor(e,t){this.notificationService=e,this.notificationSendService=t}send(e){return i(this,void 0,void 0,function*(){if(null==e?void 0:e.web){yield this.notificationSendService.send({type:"web",recipients:e.web.recipients,template_key:e.web.template_key,variables:e.web.variables,meta:e.web.meta})}if(null==e?void 0:e.email){yield this.notificationService.create({type:"email",template_key:e.email.template_key,recipients:e.email.recipients,variables:e.email.variables});yield this.notificationSendService.send({type:"email",recipients:e.email.recipients,subject:e.email.subject,body:e.email.body,template_key:e.email.template_key,variables:e.email.variables})}if(null==e?void 0:e.kakao){yield this.notificationService.create({type:"kakao",template_key:e.kakao.template_key,recipients:e.kakao.recipients,variables:e.kakao.variables});yield this.notificationSendService.send({type:"kakao",recipients:e.kakao.recipients,template_key:e.kakao.template_key,variables:e.kakao.variables})}if(null==e?void 0:e.sms){yield this.notificationService.create({type:"sms",template_key:e.sms.template_key,recipients:e.sms.recipients,variables:e.sms.variables});yield this.notificationSendService.send({type:"sms",recipients:e.sms.recipients,content:e.sms.content,template_key:e.sms.template_key,variables:e.sms.variables})}if(null==e?void 0:e.slack){yield this.notificationService.create({type:"slack",template_key:e.slack.template_key,recipients:[{user_id:0,recipient:e.slack.channel}],variables:e.slack.variables});yield this.notificationSendService.send({type:"slack",channel:e.slack.channel,content:e.slack.content,template_key:e.slack.template_key,variables:e.slack.variables})}})}};exports.EventNotificationService=c,exports.EventNotificationService=c=e([(0,a.Injectable)(),t("design:paramtypes",[n.NotificationService,n.NotificationSendService])],c);
@@ -0,0 +1,32 @@
1
+ import { EntityManager } from 'typeorm';
2
+ import { FileService } from './file.service';
3
+ export type FileUploadMode = 'single' | 'multiple';
4
+ export type FileUploadResult<T extends FileUploadMode> = T extends 'single' ? {
5
+ file_id: number | null;
6
+ } | null : {
7
+ uploaded_file_ids: number[];
8
+ } | null;
9
+ export declare function handleFileUpload<T extends FileUploadMode>(fileService: FileService, mode: T, params: {
10
+ target: string;
11
+ target_id: number;
12
+ user_id: number;
13
+ file_ids?: number[];
14
+ delete_file_ids?: number[];
15
+ group_number?: number;
16
+ manager: EntityManager;
17
+ }): Promise<FileUploadResult<T>>;
18
+ export declare function handleFileDelete(fileService: FileService, params: {
19
+ target: string;
20
+ target_id: number;
21
+ user_id: number;
22
+ file_ids: number[];
23
+ manager?: EntityManager;
24
+ }): Promise<void>;
25
+ export declare function handleFileSort(params: {
26
+ target: string;
27
+ target_id: number;
28
+ file_ids: number[];
29
+ uploaded_file_ids?: number[];
30
+ group_number: number;
31
+ manager: EntityManager;
32
+ }): Promise<void>;
@@ -0,0 +1 @@
1
+ var e=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(l,r){function fulfilled(e){try{step(n.next(e))}catch(e){r(e)}}function rejected(e){try{step(n.throw(e))}catch(e){r(e)}}function step(e){e.done?l(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.handleFileUpload=function handleFileUpload(t,i,n){return e(this,void 0,void 0,function*(){var e;const{target:l,target_id:r,user_id:d,file_ids:o,delete_file_ids:a,manager:s}=n,u=null!==(e=n.group_number)&&void 0!==e?e:"single"===i?0:9;return a&&a.length>0&&(yield t.softDelete({target:l,target_id:r,user_id:d,delete_file_ids:a,manager:s})),o&&o.length>0?(yield t.statusCompleted({target:l,target_id:r,user_id:d,file_ids:o,group_number:u,manager:s}),"single"===i?{file_id:o[0]}:{uploaded_file_ids:o}):a&&a.length>0&&"single"===i?{file_id:null}:null})},exports.handleFileDelete=function handleFileDelete(t,i){return e(this,void 0,void 0,function*(){const{target:e,target_id:n,user_id:l,file_ids:r,manager:d}=i;r&&r.length>0&&(yield t.softDelete({target:e,target_id:n,user_id:l,delete_file_ids:r,manager:d}))})},exports.handleFileSort=function handleFileSort(i){return e(this,void 0,void 0,function*(){const{target:e,target_id:n,file_ids:l,uploaded_file_ids:r=[],group_number:d,manager:o}=i;if(l&&l.length>0){const i=o.getRepository("File"),a=l.map(e=>{if(e<0){const i=Math.abs(e)-1;if(i>=r.length)throw new t.BadRequestException(`Invalid file sort index: ${e} (uploaded files count: ${r.length})`);return r[i]}return e}),s=(yield i.find({where:{target:e,target_id:n,group_number:d},select:["id"]})).map(e=>e.id),u=a.filter(e=>!s.includes(e));if(u.length>0)throw new t.BadRequestException(`Invalid file IDs in sort: [${u.join(", ")}] (not found in target files)`);if(a.length!==s.length)throw new t.BadRequestException(`Incomplete file sort: expected ${s.length} files, got ${a.length}`);for(let t=0;t<a.length;t++)yield i.update({id:a[t],target:e,target_id:n,group_number:d},{sort:t+1})}})};const t=require("@nestjs/common");
@@ -0,0 +1,55 @@
1
+ import { DataSource, EntityManager } from 'typeorm';
2
+ import { S3Service } from '../aws/aws-s3.service';
3
+ import { File } from '../database/entities';
4
+ import { FILE_STATUS } from '../enums.common';
5
+ interface FileInput {
6
+ original_name: string;
7
+ file_name: string;
8
+ path: string;
9
+ mime_type: string;
10
+ size: number;
11
+ meta?: Record<string, any>;
12
+ sort?: number;
13
+ }
14
+ export interface CreateFileInput {
15
+ target: string;
16
+ group_number?: number;
17
+ user_id: number;
18
+ files: FileInput[];
19
+ manager?: EntityManager;
20
+ }
21
+ export type StatusCompletedInput = Omit<CreateFileInput, 'files'> & {
22
+ target_id: number;
23
+ file_ids?: number[];
24
+ };
25
+ export type SoftDeleteInput = Omit<CreateFileInput, 'files'> & {
26
+ target_id: number;
27
+ delete_file_ids: number[];
28
+ };
29
+ export declare class FileService {
30
+ private readonly dataSource;
31
+ private readonly s3Service;
32
+ constructor(dataSource: DataSource, s3Service: S3Service);
33
+ findAll({ target, target_id, group_number, }: {
34
+ target: string;
35
+ target_id: number;
36
+ group_number?: number;
37
+ }): Promise<File[]>;
38
+ createPending({ target, user_id, files, manager, group_number }: CreateFileInput): Promise<({
39
+ sort: number;
40
+ group_number: number;
41
+ original_name: string;
42
+ file_name: string;
43
+ path: string;
44
+ mime_type: string;
45
+ size: number;
46
+ meta?: Record<string, any>;
47
+ status: FILE_STATUS.PENDING;
48
+ target: string;
49
+ target_id: number;
50
+ user_id: number;
51
+ } & File)[]>;
52
+ statusCompleted({ target, target_id, user_id, file_ids, manager }: StatusCompletedInput): Promise<void>;
53
+ softDelete({ target, target_id, user_id, delete_file_ids, manager }: SoftDeleteInput): Promise<void>;
54
+ }
55
+ export {};
@@ -0,0 +1 @@
1
+ var e=this&&this.__decorate||function(e,t,r,i){var n,o=arguments.length,s=o<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,r,i);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(s=(o<3?n(s):o>3?n(t,r,s):n(t,r))||s);return o>3&&s&&Object.defineProperty(t,r,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__param||function(e,t){return function(r,i){t(r,i,e)}},i=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(n,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i.throw(e))}catch(e){o(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileService=void 0;const n=require("@nestjs/common"),o=require("typeorm"),s=require("../aws/aws-s3.service"),a=require("../database/entities"),c=require("../enums.common");let u=class FileService{constructor(e,t){this.dataSource=e,this.s3Service=t}findAll(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r}){return this.dataSource.getRepository(a.File).find({where:{target:e,target_id:t,group_number:r},order:{sort:"ASC"}})})}createPending(e){return i(this,arguments,void 0,function*({target:e,user_id:t,files:r,manager:i,group_number:n}){const o=i?i.getRepository(a.File):this.dataSource.getRepository(a.File),s=yield o.save(r.map((r,i)=>{var o;return Object.assign(Object.assign({status:c.FILE_STATUS.PENDING,target:e,target_id:0,user_id:t},r),{sort:null!==(o=r.sort)&&void 0!==o?o:i+1,group_number:n})}));return s})}statusCompleted(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,file_ids:i,manager:n}){const s=n?n.getRepository(a.File):this.dataSource.getRepository(a.File);yield s.update({target:e,id:(0,o.In)(i)},{status:c.FILE_STATUS.COMPLETED,target_id:t})})}softDelete(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,delete_file_ids:i,manager:n}){const s=n?n.getRepository(a.File):this.dataSource.getRepository(a.File),u=yield s.find({where:{target:e,user_id:r,target_id:t,id:(0,o.In)(i)}});yield this.s3Service.deleteObjectsByKeys(u.map(e=>this.s3Service.getFileKey(e))),yield s.update({id:(0,o.In)(u.map(e=>e.id))},{status:c.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}};exports.FileService=u,exports.FileService=u=e([(0,n.Injectable)(),r(1,(0,n.Inject)((0,n.forwardRef)(()=>s.S3Service))),t("design:paramtypes",[o.DataSource,s.S3Service])],u);
@@ -0,0 +1,2 @@
1
+ export * from './file.service';
2
+ export * from './file.helper';
@@ -0,0 +1 @@
1
+ var e=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var i in r)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||e(t,r,i)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./file.service"),exports),r(require("./file.helper"),exports);
@@ -1 +1,2 @@
1
1
  export * from './http-exception.filter';
2
+ export * from './validation-exception.filter';
@@ -1 +1 @@
1
- var e=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(r,i)||e(r,t,i)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./http-exception.filter"),exports);
1
+ var e=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(r,i)||e(r,t,i)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./http-exception.filter"),exports),t(require("./validation-exception.filter"),exports);
@@ -0,0 +1,8 @@
1
+ import { ArgumentsHost, ExceptionFilter, UnprocessableEntityException } from '@nestjs/common';
2
+ export declare class ValidationExceptionFilter implements ExceptionFilter {
3
+ catch(exception: UnprocessableEntityException, host: ArgumentsHost): void;
4
+ private flattenValidationErrors;
5
+ private parseStringError;
6
+ private formatValidationErrors;
7
+ private constraintKeyToErrorCode;
8
+ }
@@ -0,0 +1 @@
1
+ var e=this&&this.__decorate||function(e,t,i,s){var r,I=arguments.length,n=I<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,i,s);else for(var o=e.length-1;o>=0;o--)(r=e[o])&&(n=(I<3?r(n):I>3?r(t,i,n):r(t,i))||n);return I>3&&n&&Object.defineProperty(t,i,n),n};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ValidationExceptionFilter=void 0;const t=require("@nestjs/common");let i=class ValidationExceptionFilter{catch(e,t){const i=t.switchToHttp(),s=i.getResponse(),r=e.getResponse(),I=this.flattenValidationErrors(r.message);s.status(422).json({success:!1,status:422,path:i.getRequest().url,errors:I})}flattenValidationErrors(e){return Array.isArray(e)&&0===e.length?[{field:"unknown",code:"VALIDATION_ERROR",message:"Validation failed"}]:Array.isArray(e)&&e.length>0&&"string"==typeof e[0]?e.map(e=>this.parseStringError(e)):Array.isArray(e)&&e.length>0&&"object"==typeof e[0]?this.formatValidationErrors(e):"string"==typeof e?[{field:"unknown",code:"VALIDATION_ERROR",message:e}]:[{field:"unknown",code:"VALIDATION_ERROR",message:"Validation failed"}]}parseStringError(e){const t=e.trim().split(" ")[0];return{field:/^[a-z_][a-z0-9_]*$/i.test(t)?t:"unknown",code:"VALIDATION_ERROR",message:e}}formatValidationErrors(e,t=""){const i=[];for(const s of e){const e=t?`${t}.${s.property}`:s.property;if(s.constraints)for(const[t,r]of Object.entries(s.constraints))i.push({field:e,code:this.constraintKeyToErrorCode(t),message:r});if(s.children&&s.children.length>0){const t=this.formatValidationErrors(s.children,e);i.push(...t)}}return i}constraintKeyToErrorCode(e){return{isNotEmpty:"REQUIRED",isDefined:"REQUIRED",isOptional:"OPTIONAL",isEmail:"INVALID_EMAIL",isUrl:"INVALID_URL",isUUID:"INVALID_UUID",isPhoneNumber:"INVALID_PHONE",isISO8601:"INVALID_DATE_FORMAT",isMongoId:"INVALID_MONGO_ID",isJWT:"INVALID_JWT",isHexadecimal:"INVALID_HEX",isHash:"INVALID_HASH",isAlpha:"INVALID_ALPHA",isAlphanumeric:"INVALID_ALPHANUMERIC",isAscii:"INVALID_ASCII",isBase64:"INVALID_BASE64",isJSON:"INVALID_JSON",isLowercase:"INVALID_LOWERCASE",isUppercase:"INVALID_UPPERCASE",isCreditCard:"INVALID_CREDIT_CARD",isCurrency:"INVALID_CURRENCY",isDecimal:"INVALID_DECIMAL",isIP:"INVALID_IP",isPort:"INVALID_PORT",isMACAddress:"INVALID_MAC_ADDRESS",isMimeType:"INVALID_MIME_TYPE",isLatLong:"INVALID_LAT_LONG",isLocale:"INVALID_LOCALE",minLength:"MIN_LENGTH",maxLength:"MAX_LENGTH",length:"INVALID_LENGTH",matches:"PATTERN_MISMATCH",contains:"MUST_CONTAIN",notContains:"MUST_NOT_CONTAIN",min:"MIN_VALUE",max:"MAX_VALUE",isPositive:"MUST_BE_POSITIVE",isNegative:"MUST_BE_NEGATIVE",isDivisibleBy:"DIVISIBLE_BY",isString:"INVALID_TYPE_STRING",isNumber:"INVALID_TYPE_NUMBER",isInt:"INVALID_TYPE_INTEGER",isBoolean:"INVALID_TYPE_BOOLEAN",isArray:"INVALID_TYPE_ARRAY",isObject:"INVALID_TYPE_OBJECT",isDate:"INVALID_TYPE_DATE",isInstance:"INVALID_TYPE_INSTANCE",arrayMinSize:"ARRAY_MIN_SIZE",arrayMaxSize:"ARRAY_MAX_SIZE",arrayUnique:"ARRAY_UNIQUE",arrayNotEmpty:"ARRAY_NOT_EMPTY",arrayContains:"ARRAY_MUST_CONTAIN",arrayNotContains:"ARRAY_MUST_NOT_CONTAIN",isEnum:"INVALID_ENUM",isIn:"INVALID_VALUE",isNotIn:"INVALID_VALUE",equals:"MUST_EQUAL",notEquals:"MUST_NOT_EQUAL",whitelistValidation:"INVALID_PROPERTY",isNotEmptyObject:"REQUIRED_OBJECT",minDate:"MIN_DATE",maxDate:"MAX_DATE"}[e]||e.toUpperCase()}};exports.ValidationExceptionFilter=i,exports.ValidationExceptionFilter=i=e([(0,t.Catch)(t.UnprocessableEntityException)],i);
package/dist/index.d.ts CHANGED
@@ -17,5 +17,6 @@ export * from './comment';
17
17
  export * from './like';
18
18
  export * from './role';
19
19
  export * from './services';
20
+ export * from './file-upload';
20
21
  export * from './logger';
21
22
  export * from './guards';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var e=this&&this.__createBinding||(Object.create?function(e,r,t,o){void 0===o&&(o=t);var i=Object.getOwnPropertyDescriptor(r,t);i&&!("get"in i?!r.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,o,i)}:function(e,r,t,o){void 0===o&&(o=t),e[o]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var o in r)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||e(t,r,o)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./enums.common"),exports),r(require("./decorators"),exports),r(require("./dto"),exports),r(require("./filters"),exports),r(require("./interceptors"),exports),r(require("./utils"),exports),r(require("./setup-swagger"),exports),r(require("./logger"),exports),r(require("./redis"),exports),r(require("./passport"),exports),r(require("./events"),exports),r(require("./notifications"),exports),r(require("./aws"),exports),r(require("./library.module"),exports),r(require("./category"),exports),r(require("./comment"),exports),r(require("./like"),exports),r(require("./role"),exports),r(require("./services"),exports),r(require("./logger"),exports),r(require("./guards"),exports);
1
+ var e=this&&this.__createBinding||(Object.create?function(e,r,t,o){void 0===o&&(o=t);var i=Object.getOwnPropertyDescriptor(r,t);i&&!("get"in i?!r.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,o,i)}:function(e,r,t,o){void 0===o&&(o=t),e[o]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var o in r)"default"===o||Object.prototype.hasOwnProperty.call(t,o)||e(t,r,o)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./enums.common"),exports),r(require("./decorators"),exports),r(require("./dto"),exports),r(require("./filters"),exports),r(require("./interceptors"),exports),r(require("./utils"),exports),r(require("./setup-swagger"),exports),r(require("./logger"),exports),r(require("./redis"),exports),r(require("./passport"),exports),r(require("./events"),exports),r(require("./notifications"),exports),r(require("./aws"),exports),r(require("./library.module"),exports),r(require("./category"),exports),r(require("./comment"),exports),r(require("./like"),exports),r(require("./role"),exports),r(require("./services"),exports),r(require("./file-upload"),exports),r(require("./logger"),exports),r(require("./guards"),exports);
@@ -4,6 +4,7 @@ export interface NotificationRecipient {
4
4
  user_id: number;
5
5
  recipient: string;
6
6
  variables?: Record<string, any>;
7
+ meta?: Record<string, any>;
7
8
  }
8
9
  export interface NotificationOptions {
9
10
  web?: {
@@ -2,6 +2,7 @@ import { ConfigService } from '@nestjs/config';
2
2
  export declare class EmailService {
3
3
  private readonly configService;
4
4
  private sesClient;
5
+ private resendClient;
5
6
  constructor(configService: ConfigService);
6
7
  send(recipients: Array<{
7
8
  recipient: string;
@@ -15,7 +16,7 @@ export declare class EmailService {
15
16
  success: boolean;
16
17
  content: string;
17
18
  status: string;
18
- }[] | import("@aws-sdk/client-ses").SendEmailCommandOutput>;
19
+ }[] | import("@aws-sdk/client-ses").SendEmailCommandOutput | import("resend").CreateEmailResponse>;
19
20
  sendAws(recipients: Array<{
20
21
  recipient: string;
21
22
  user_id: number;
@@ -29,4 +30,17 @@ export declare class EmailService {
29
30
  content: string;
30
31
  status: string;
31
32
  }[] | import("@aws-sdk/client-ses").SendEmailCommandOutput>;
33
+ sendResend(recipients: Array<{
34
+ recipient: string;
35
+ user_id: number;
36
+ subject: string;
37
+ text: string;
38
+ variables?: Record<string, any>;
39
+ }>): Promise<{
40
+ user_id: number;
41
+ recipient: string;
42
+ success: boolean;
43
+ content: string;
44
+ status: string;
45
+ }[] | import("resend").CreateEmailResponse>;
32
46
  }
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,n){var s,r=arguments.length,c=r<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,i,n);else for(var o=e.length-1;o>=0;o--)(s=e[o])&&(c=(r<3?s(c):r>3?s(t,i,c):s(t,i))||c);return r>3&&c&&Object.defineProperty(t,i,c),c},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(s,r){function fulfilled(e){try{step(n.next(e))}catch(e){r(e)}}function rejected(e){try{step(n.throw(e))}catch(e){r(e)}}function step(e){e.done?s(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EmailService=void 0;const n=require("@aws-sdk/client-ses"),s=require("@nestjs/common"),r=require("@nestjs/config");let c=class EmailService{constructor(e){this.configService=e,"aws"===this.configService.get("EMAIL_PROVIDER")&&(this.sesClient=new n.SESClient({region:this.configService.get("AWS_REGION"),credentials:{accessKeyId:this.configService.get("AWS_ACCESS_KEY_ID"),secretAccessKey:this.configService.get("AWS_SECRET_ACCESS_KEY")}}))}send(e){return i(this,void 0,void 0,function*(){const t=this.configService.get("EMAIL_PROVIDER");if(!t||!this.configService.get("EMAIL_FROM"))throw new Error("EMAIL_PROVIDER or EMAIL_FROM is not set");return"aws"===t?this.sendAws(e):[]})}sendAws(e){return i(this,void 0,void 0,function*(){if("production"!==process.env.NODE_ENV)return e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,content:e.text,status:"sent"}));for(const t of e){const e=new n.SendEmailCommand({Source:this.configService.get("EMAIL_NOREPLY_SOURCE"),Destination:{ToAddresses:[t.recipient]},Message:{Subject:{Data:t.subject,Charset:"UTF-8"},Body:{Html:{Data:t.text,Charset:"UTF-8"}}}});return yield this.sesClient.send(e)}})}};exports.EmailService=c,exports.EmailService=c=e([(0,s.Injectable)(),t("design:paramtypes",[r.ConfigService])],c);
1
+ var e=this&&this.__decorate||function(e,t,i,n){var s,r=arguments.length,c=r<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,i,n);else for(var o=e.length-1;o>=0;o--)(s=e[o])&&(c=(r<3?s(c):r>3?s(t,i,c):s(t,i))||c);return r>3&&c&&Object.defineProperty(t,i,c),c},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(s,r){function fulfilled(e){try{step(n.next(e))}catch(e){r(e)}}function rejected(e){try{step(n.throw(e))}catch(e){r(e)}}function step(e){e.done?s(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EmailService=void 0;const n=require("@aws-sdk/client-ses"),s=require("@nestjs/common"),r=require("@nestjs/config"),c=require("resend");let o=class EmailService{constructor(e){this.configService=e,"aws"===this.configService.get("EMAIL_PROVIDER")&&(this.sesClient=new n.SESClient({region:this.configService.get("AWS_REGION"),credentials:{accessKeyId:this.configService.get("AWS_ACCESS_KEY_ID"),secretAccessKey:this.configService.get("AWS_SECRET_ACCESS_KEY")}})),"resend"===this.configService.get("EMAIL_PROVIDER")&&(this.resendClient=new c.Resend(this.configService.get("RESEND_API_KEY")))}send(e){return i(this,void 0,void 0,function*(){const t=this.configService.get("EMAIL_PROVIDER");if(!t||!this.configService.get("EMAIL_FROM"))throw new Error("EMAIL_PROVIDER or EMAIL_FROM is not set");return"aws"===t?this.sendAws(e):"resend"===t?this.sendResend(e):[]})}sendAws(e){return i(this,void 0,void 0,function*(){if("production"!==process.env.NODE_ENV)return e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,content:e.text,status:"sent"}));for(const t of e){const e=new n.SendEmailCommand({Source:this.configService.get("EMAIL_NOREPLY_SOURCE"),Destination:{ToAddresses:[t.recipient]},Message:{Subject:{Data:t.subject,Charset:"UTF-8"},Body:{Html:{Data:t.text,Charset:"UTF-8"}}}});return yield this.sesClient.send(e)}})}sendResend(e){return i(this,void 0,void 0,function*(){if("production"!==process.env.NODE_ENV)return console.log("📧 [EMAIL] Resend 배열 발송:",{count:e.length,from:this.configService.get("EMAIL_FROM"),provider:this.configService.get("EMAIL_PROVIDER"),recipients:e.map(e=>({user_id:e.user_id,recipient:e.recipient,subject:e.subject,text:e.text.substring(0,50)+(e.text.length>50?"...":""),variables:e.variables})),timestamp:(new Date).toISOString()}),e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,content:e.text,status:"sent"}));for(const t of e){return yield this.resendClient.emails.send({from:this.configService.get("EMAIL_NOREPLY_SOURCE"),to:[t.recipient],subject:t.subject,html:t.text})}})}};exports.EmailService=o,exports.EmailService=o=e([(0,s.Injectable)(),t("design:paramtypes",[r.ConfigService])],o);
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,r){var o,n=arguments.length,s=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(o=e[c])&&(s=(n<3?o(s):n>3?o(t,i,s):o(t,i))||s);return n>3&&s&&Object.defineProperty(t,i,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(o,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?o(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.KakaoService=void 0;const r=require("@nestjs/common"),o=require("@nestjs/config"),n=require("../../redis");let s=class KakaoService{constructor(e,t){this.configService=e,this.redis=t}send(e){return i(this,void 0,void 0,function*(){const t=this.configService.get("KAKAO_PROVIDER");if(!t||!this.configService.get("KAKAO_FROM"))throw new Error("KAKAO_PROVIDER or KAKAO_FROM is not set");return"aligo"===t?this.sendAligo(e):"ppurio"===t?this.sendPpurio(e):[]})}sendAligo(e){return i(this,void 0,void 0,function*(){return console.log("📱 [KAKAO] Aligo 배열 발송:",{count:e.length,from:this.configService.get("KAKAO_FROM"),provider:"aligo",recipients:e.map(e=>({user_id:e.user_id,recipient:e.recipient,template_code:e.template_code,variables:e.variables})),timestamp:(new Date).toISOString()}),e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,messageId:`aligo-${Date.now()}-${e.user_id}`,status:"sent"}))})}getPpurioToken(){return i(this,void 0,void 0,function*(){if(yield this.redis.get("ppurio_token"))return yield this.redis.get("ppurio_token");const e=this.configService.get("PPURIO_ACCOUNT"),t=this.configService.get("PPURIO_PASSWORD"),i=btoa(`${e}:${t}`),r=yield fetch("https://api.bizppurio.com/v1/token",{method:"POST",headers:{"Content-Type":"application/json; charset=utf-8",Authorization:`Basic ${i}`},body:JSON.stringify({grant_type:"client_credentials"})}),o=yield r.json();if(o.accesstoken)return yield this.redis.set("ppurio_token",o.accesstoken,86e3),yield this.redis.get("ppurio_token");throw new Error(`cannot get ppurio access token: ${JSON.stringify(o)}`)})}sendPpurioMessage(e){return i(this,void 0,void 0,function*(){const t=e.recipient.trim().replace(/-/g,"");if(t.startsWith("0100")&&t.length<=10)return;const i=yield this.getPpurioToken(),r=yield fetch("https://api.bizppurio.com/v3/message",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({account:this.configService.get("PPURIO_ACCOUNT"),refkey:this.configService.get("PPURIO_PASSWORD"),type:"at",from:this.configService.get("SMS_FROM"),to:e.recipient,content:{at:{senderkey:e.sender_key,templatecode:e.template_code,message:e.message}}})});return yield r.json()})}sendPpurio(e){return i(this,void 0,void 0,function*(){if("production"!==process.env.NODE_ENV)return console.log("📱 [KAKAO] Ppurio 발송:",{count:e.length,from:this.configService.get("KAKAO_FROM"),provider:"ppurio",recipients:e.map(e=>({user_id:e.user_id,recipient:e.recipient,sender_key:e.sender_key,template_code:e.template_code,message:e.message})),timestamp:(new Date).toISOString()}),e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,messageId:`ppurio-${Date.now()}-${e.user_id}`,message:e.message,status:"sent"}));return yield Promise.all(e.map(e=>this.sendPpurioMessage(e)))})}};exports.KakaoService=s,exports.KakaoService=s=e([(0,r.Injectable)(),t("design:paramtypes",[o.ConfigService,n.RedisService])],s);
1
+ var e=this&&this.__decorate||function(e,t,i,r){var o,n=arguments.length,s=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(o=e[c])&&(s=(n<3?o(s):n>3?o(t,i,s):o(t,i))||s);return n>3&&s&&Object.defineProperty(t,i,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(o,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?o(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.KakaoService=void 0;const r=require("@nestjs/common"),o=require("@nestjs/config"),n=require("../../redis");let s=class KakaoService{constructor(e,t){this.configService=e,this.redis=t}send(e){return i(this,void 0,void 0,function*(){const t=this.configService.get("KAKAO_PROVIDER");if(!t||!this.configService.get("KAKAO_FROM"))throw new Error("KAKAO_PROVIDER or KAKAO_FROM is not set");return"aligo"===t?this.sendAligo(e):"ppurio"===t?this.sendPpurio(e):[]})}sendAligo(e){return i(this,void 0,void 0,function*(){return console.log("📱 [KAKAO] Aligo 배열 발송:",{count:e.length,from:this.configService.get("KAKAO_FROM"),provider:"aligo",recipients:e.map(e=>({user_id:e.user_id,recipient:e.recipient,template_code:e.template_code,variables:e.variables})),timestamp:(new Date).toISOString()}),e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,messageId:`aligo-${Date.now()}-${e.user_id}`,status:"sent"}))})}getPpurioToken(){return i(this,void 0,void 0,function*(){if(yield this.redis.get("ppurio_token"))return yield this.redis.get("ppurio_token");const e=this.configService.get("PPURIO_ACCOUNT"),t=this.configService.get("PPURIO_PASSWORD"),i=btoa(`${e}:${t}`),r=yield fetch("https://api.bizppurio.com/v1/token",{method:"POST",headers:{"Content-Type":"application/json; charset=utf-8",Authorization:`Basic ${i}`},body:JSON.stringify({grant_type:"client_credentials"})}),o=yield r.json();if(o.accesstoken)return yield this.redis.set("ppurio_token",o.accesstoken,86e3),yield this.redis.get("ppurio_token");throw new Error(`cannot get ppurio access token: ${JSON.stringify(o)}`)})}sendPpurioMessage(e){return i(this,void 0,void 0,function*(){const t=e.recipient.trim().replace(/-/g,"");if(t.startsWith("0100")||11!==t.length)return;const i=yield this.getPpurioToken(),r=yield fetch("https://api.bizppurio.com/v3/message",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({account:this.configService.get("PPURIO_ACCOUNT"),refkey:this.configService.get("PPURIO_PASSWORD"),type:"at",from:this.configService.get("SMS_FROM"),to:e.recipient,content:{at:{senderkey:e.sender_key,templatecode:e.template_code,message:e.message}}})});return yield r.json()})}sendPpurio(e){return i(this,void 0,void 0,function*(){if("production"!==process.env.NODE_ENV)return console.log("📱 [KAKAO] Ppurio 발송:",{count:e.length,from:this.configService.get("KAKAO_FROM"),provider:"ppurio",recipients:e.map(e=>({user_id:e.user_id,recipient:e.recipient,sender_key:e.sender_key,template_code:e.template_code,message:e.message})),timestamp:(new Date).toISOString()}),e.map(e=>({user_id:e.user_id,recipient:e.recipient,success:!0,messageId:`ppurio-${Date.now()}-${e.user_id}`,message:e.message,status:"sent"}));return yield Promise.all(e.map(e=>this.sendPpurioMessage(e)))})}};exports.KakaoService=s,exports.KakaoService=s=e([(0,r.Injectable)(),t("design:paramtypes",[o.ConfigService,n.RedisService])],s);
@@ -15,7 +15,7 @@ export declare class NotificationSendService {
15
15
  private readonly messageTemplateService;
16
16
  private readonly dataSource;
17
17
  constructor(emailService: EmailService, smsService: SmsService, kakaoService: KakaoService, slackService: SlackService, webNotificationService: WebNotificationService, messageTemplateService: MessageTemplateService, dataSource: DataSource);
18
- send(payload: NotificationPayload): Promise<any[] | import("@aws-sdk/client-ses").SendEmailCommandOutput | {
18
+ send(payload: NotificationPayload): Promise<any[] | import("@aws-sdk/client-ses").SendEmailCommandOutput | import("resend").CreateEmailResponse | {
19
19
  success: boolean;
20
20
  }>;
21
21
  private sendWeb;
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,r){var s,n=arguments.length,a=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(s=e[c])&&(a=(n<3?s(a):n>3?s(t,i,a):s(t,i))||a);return n>3&&a&&Object.defineProperty(t,i,a),a},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(s,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?s(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationSendService=void 0;const r=require("@nestjs/common"),s=require("typeorm"),n=require("./email.service"),a=require("./kakao.service"),c=require("./message-template.service"),o=require("./slack.service"),l=require("./sms.service"),d=require("./web.service");let m=class NotificationSendService{constructor(e,t,i,r,s,n,a){this.emailService=e,this.smsService=t,this.kakaoService=i,this.slackService=r,this.webNotificationService=s,this.messageTemplateService=n,this.dataSource=a}send(e){return i(this,void 0,void 0,function*(){switch(e.type){case"web":return this.sendWeb(e);case"email":return this.sendEmail(e);case"sms":return this.sendSms(e);case"kakao":return this.sendKakao(e);case"slack":return this.sendSlack(e)}})}sendWeb(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r,s;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("web",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,n).title||e.title||"",s=this.messageTemplateService.renderTemplate(t,n).content}else{if(!e.title||!e.content)throw new Error("title, content is required");r=e.title,s=e.content}t.push({recipient:i.recipient,user_id:i.user_id,title:r,content:s,variables:i.variables,meta:e.meta})}return yield this.webNotificationService.send(Object.assign(Object.assign({},e),{recipients:t}))})}sendEmail(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r,s;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("email",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,n).content,s=t.subject}else{if(!e.subject||!e.body)throw new Error("subject, body is required");r=e.body,s=e.subject}t.push({recipient:i.recipient,user_id:i.user_id,subject:s,text:r,variables:i.variables})}return yield this.emailService.send(t)})}sendSms(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("sms",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const s=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,s).content}else{if(!e.content)throw new Error("content is required");r=e.content}t.push({recipient:i.recipient,user_id:i.user_id,content:r,variables:i.variables})}return yield this.smsService.send(t)})}sendKakao(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r;if(!e.template_key)throw new Error("template_key is required");const s=yield this.messageTemplateService.getTemplate("kakao",e.template_key);if(!s)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(s,n).content,t.push({recipient:i.recipient,user_id:i.user_id,sender_key:s.sender_key,template_code:s.template_code,message:r})}return yield this.kakaoService.send(t)})}sendSlack(e){return i(this,void 0,void 0,function*(){let t;if(e.template_key){const i=yield this.messageTemplateService.getTemplate("slack",e.template_key);if(!i)throw new Error("Template not found "+e.template_key);t=this.messageTemplateService.renderTemplate(i,e.variables||{}).content}else{if(!e.content)throw new Error("content is required");t=e.content}return[yield this.slackService.send(e.channel,t)]})}};exports.NotificationSendService=m,exports.NotificationSendService=m=e([(0,r.Injectable)(),t("design:paramtypes",[n.EmailService,l.SmsService,a.KakaoService,o.SlackService,d.WebNotificationService,c.MessageTemplateService,s.DataSource])],m);
1
+ var e=this&&this.__decorate||function(e,t,i,r){var s,n=arguments.length,a=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(s=e[c])&&(a=(n<3?s(a):n>3?s(t,i,a):s(t,i))||a);return n>3&&a&&Object.defineProperty(t,i,a),a},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))(function(s,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?s(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationSendService=void 0;const r=require("@nestjs/common"),s=require("typeorm"),n=require("./email.service"),a=require("./kakao.service"),c=require("./message-template.service"),o=require("./slack.service"),l=require("./sms.service"),d=require("./web.service");let m=class NotificationSendService{constructor(e,t,i,r,s,n,a){this.emailService=e,this.smsService=t,this.kakaoService=i,this.slackService=r,this.webNotificationService=s,this.messageTemplateService=n,this.dataSource=a}send(e){return i(this,void 0,void 0,function*(){switch(e.type){case"web":return this.sendWeb(e);case"email":return this.sendEmail(e);case"sms":return this.sendSms(e);case"kakao":return this.sendKakao(e);case"slack":return this.sendSlack(e)}})}sendWeb(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r,s;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("web",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,n).title||e.title||"",s=this.messageTemplateService.renderTemplate(t,n).content}else{if(!e.title||!e.content)throw new Error("title, content is required");r=e.title,s=e.content}t.push({recipient:i.recipient,user_id:i.user_id,title:r,content:s,variables:i.variables,meta:i.meta||e.meta})}return yield this.webNotificationService.send(Object.assign(Object.assign({},e),{recipients:t}))})}sendEmail(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r,s;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("email",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,n).content,s=t.subject}else{if(!e.subject||!e.body)throw new Error("subject, body is required");r=e.body,s=e.subject}t.push({recipient:i.recipient,user_id:i.user_id,subject:s,text:r,variables:i.variables})}return yield this.emailService.send(t)})}sendSms(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("sms",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const s=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,s).content}else{if(!e.content)throw new Error("content is required");r=e.content}t.push({recipient:i.recipient,user_id:i.user_id,content:r,variables:i.variables})}return yield this.smsService.send(t)})}sendKakao(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r;if(!e.template_key)throw new Error("template_key is required");const s=yield this.messageTemplateService.getTemplate("kakao",e.template_key);if(!s)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(s,n).content,t.push({recipient:i.recipient,user_id:i.user_id,sender_key:s.sender_key,template_code:s.template_code,message:r})}return yield this.kakaoService.send(t)})}sendSlack(e){return i(this,void 0,void 0,function*(){let t;if(e.template_key){const i=yield this.messageTemplateService.getTemplate("slack",e.template_key);if(!i)throw new Error("Template not found "+e.template_key);t=this.messageTemplateService.renderTemplate(i,e.variables||{}).content}else{if(!e.content)throw new Error("content is required");t=e.content}return[yield this.slackService.send(e.channel,t)]})}};exports.NotificationSendService=m,exports.NotificationSendService=m=e([(0,r.Injectable)(),t("design:paramtypes",[n.EmailService,l.SmsService,a.KakaoService,o.SlackService,d.WebNotificationService,c.MessageTemplateService,s.DataSource])],m);
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,r,i){var n,s=arguments.length,a=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,i);else for(var o=e.length-1;o>=0;o--)(n=e[o])&&(a=(s<3?n(a):s>3?n(t,r,a):n(t,r))||a);return s>3&&a&&Object.defineProperty(t,r,a),a},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__param||function(e,t){return function(r,i){t(r,i,e)}},i=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(n,s){function fulfilled(e){try{step(i.next(e))}catch(e){s(e)}}function rejected(e){try{step(i.throw(e))}catch(e){s(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileService=void 0;const n=require("@nestjs/common"),s=require("typeorm"),a=require("../aws/aws-s3.service"),o=require("../database/entities"),c=require("../enums.common");let u=class FileService{constructor(e,t){this.dataSource=e,this.s3Service=t}findAll(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r}){return this.dataSource.getRepository(o.File).find({where:{target:e,target_id:t,group_number:r}})})}createPending(e){return i(this,arguments,void 0,function*({target:e,user_id:t,files:r,manager:i,group_number:n}){const s=i?i.getRepository(o.File):this.dataSource.getRepository(o.File),a=yield s.save(r.map((r,i)=>{var s;return Object.assign(Object.assign({status:c.FILE_STATUS.PENDING,target:e,target_id:0,user_id:t},r),{sort:null!==(s=r.sort)&&void 0!==s?s:i+1,group_number:n})}));return a})}statusCompleted(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,file_ids:i,manager:n}){const a=n?n.getRepository(o.File):this.dataSource.getRepository(o.File);yield a.update({target:e,id:(0,s.In)(i)},{status:c.FILE_STATUS.COMPLETED,target_id:t})})}softDelete(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,delete_file_ids:i,manager:n}){const a=n?n.getRepository(o.File):this.dataSource.getRepository(o.File),u=yield a.find({where:{target:e,user_id:r,target_id:t,id:(0,s.In)(i)}});yield this.s3Service.deleteObjectsByKeys(u.map(e=>this.s3Service.getFileKey(e))),yield a.update({id:(0,s.In)(u.map(e=>e.id))},{status:c.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}};exports.FileService=u,exports.FileService=u=e([(0,n.Injectable)(),r(1,(0,n.Inject)((0,n.forwardRef)(()=>a.S3Service))),t("design:paramtypes",[s.DataSource,a.S3Service])],u);
1
+ var e=this&&this.__decorate||function(e,t,r,i){var n,o=arguments.length,s=o<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,r,i);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(s=(o<3?n(s):o>3?n(t,r,s):n(t,r))||s);return o>3&&s&&Object.defineProperty(t,r,s),s},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__param||function(e,t){return function(r,i){t(r,i,e)}},i=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(n,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i.throw(e))}catch(e){o(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileService=void 0;const n=require("@nestjs/common"),o=require("typeorm"),s=require("../aws/aws-s3.service"),a=require("../database/entities"),c=require("../enums.common");let u=class FileService{constructor(e,t){this.dataSource=e,this.s3Service=t}findAll(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r}){return this.dataSource.getRepository(a.File).find({where:{target:e,target_id:t,group_number:r},order:{sort:"ASC"}})})}createPending(e){return i(this,arguments,void 0,function*({target:e,user_id:t,files:r,manager:i,group_number:n}){const o=i?i.getRepository(a.File):this.dataSource.getRepository(a.File),s=yield o.save(r.map((r,i)=>{var o;return Object.assign(Object.assign({status:c.FILE_STATUS.PENDING,target:e,target_id:0,user_id:t},r),{sort:null!==(o=r.sort)&&void 0!==o?o:i+1,group_number:n})}));return s})}statusCompleted(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,file_ids:i,manager:n}){const s=n?n.getRepository(a.File):this.dataSource.getRepository(a.File);yield s.update({target:e,id:(0,o.In)(i)},{status:c.FILE_STATUS.COMPLETED,target_id:t})})}softDelete(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,delete_file_ids:i,manager:n}){const s=n?n.getRepository(a.File):this.dataSource.getRepository(a.File),u=yield s.find({where:{target:e,user_id:r,target_id:t,id:(0,o.In)(i)}});yield this.s3Service.deleteObjectsByKeys(u.map(e=>this.s3Service.getFileKey(e))),yield s.update({id:(0,o.In)(u.map(e=>e.id))},{status:c.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}};exports.FileService=u,exports.FileService=u=e([(0,n.Injectable)(),r(1,(0,n.Inject)((0,n.forwardRef)(()=>s.S3Service))),t("design:paramtypes",[o.DataSource,s.S3Service])],u);
@@ -1,2 +1 @@
1
1
  export * from './permission-checker.service';
2
- export * from './file.service';
@@ -1 +1 @@
1
- var e=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var i in r)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||e(t,r,i)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./permission-checker.service"),exports),r(require("./file.service"),exports);
1
+ var e=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(r,i)||e(r,t,i)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./permission-checker.service"),exports);
@@ -4,6 +4,7 @@ export interface SwaggerConfig {
4
4
  description: string;
5
5
  version: string;
6
6
  uri: string;
7
+ defaultToken?: string;
7
8
  }
8
9
  declare function setupSwagger(app: INestApplication, config: SwaggerConfig): void;
9
10
  export { setupSwagger };
@@ -1 +1 @@
1
- Object.defineProperty(exports,"__esModule",{value:!0}),exports.setupSwagger=function setupSwagger(t,r){const o=(new e.DocumentBuilder).setTitle(r.title).setDescription(r.description).setVersion(r.version).addBearerAuth({type:"http",bearerFormat:"Bearer",scheme:"Bearer",name:"Authorization",in:"header"},"access_token").addCookieAuth("refresh_token",{type:"apiKey",in:"cookie",name:"refresh_token"}).build(),n=e.SwaggerModule.createDocument(t,o);e.SwaggerModule.setup(r.uri,t,n,{swaggerOptions:{persistAuthorization:!0,defaultModelsExpandDepth:-1,defaultModelExpandDepth:-1,docExpansion:"none"}})};const e=require("@nestjs/swagger");
1
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.setupSwagger=function setupSwagger(t,r){const a=(new e.DocumentBuilder).setTitle(r.title).setDescription(r.description).setVersion(r.version).addBearerAuth({type:"http",bearerFormat:"Bearer",scheme:"Bearer",name:"Authorization",in:"header"},"access_token").addCookieAuth("refresh_token",{type:"apiKey",in:"cookie",name:"refresh_token"}).build(),o=e.SwaggerModule.createDocument(t,a);e.SwaggerModule.setup(r.uri,t,o,{swaggerOptions:Object.assign({persistAuthorization:!0,defaultModelsExpandDepth:-1,defaultModelExpandDepth:-1,docExpansion:"none"},r.defaultToken&&{authAction:{access_token:{name:"access_token",schema:{type:"http",scheme:"bearer",bearerFormat:"JWT"},value:r.defaultToken}}})})};const e=require("@nestjs/swagger");
@@ -1 +1 @@
1
- var e=this&&this.__awaiter||function(e,t,n,i){return new(n||(n=Promise))(function(a,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i.throw(e))}catch(e){o(e)}}function step(e){e.done?a(e.value):function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.paginate=function paginate(t,n){return e(this,void 0,void 0,function*(){const{page:e,limit:i}=n,a=t.connection.createQueryBuilder().select("COUNT(*)","count").from(`(${t.getQuery()})`,"subquery").setParameters(t.getParameters()),[o,r]=yield Promise.all([t.skip((e-1)*i).take(i).getMany(),a.getRawOne().then(e=>parseInt(e.count))]),u=Math.ceil(r/i);return{items:o,pagination:{page:e,limit:i,count:o.length,count_total:r,count_page:u}}})};
1
+ var t=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))(function(o,a){function fulfilled(t){try{step(i.next(t))}catch(t){a(t)}}function rejected(t){try{step(i.throw(t))}catch(t){a(t)}}function step(t){t.done?o(t.value):function adopt(t){return t instanceof n?t:new n(function(e){e(t)})}(t.value).then(fulfilled,rejected)}step((i=i.apply(t,e||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.paginate=function paginate(e,n){return t(this,void 0,void 0,function*(){const{page:t,limit:i}=n,o=e.clone(),[a,c]=yield Promise.all([e.skip((t-1)*i).take(i).getMany(),o.getCount()]),u=Math.ceil(c/i);return{items:a,pagination:{page:t,limit:i,count:a.length,count_total:c,count_page:u}}})};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comasoft/nestjs",
3
- "version": "0.1.71",
3
+ "version": "0.1.94",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "exports": {
@@ -34,6 +34,7 @@
34
34
  "@aws-sdk/client-s3": "^3.842.0",
35
35
  "@aws-sdk/client-ses": "^3.862.0",
36
36
  "@aws-sdk/s3-presigned-post": "^3.842.0",
37
+ "@aws-sdk/s3-request-presigner": "^3.929.0",
37
38
  "@nestjs/config": "^4.0.2",
38
39
  "date-fns-tz": "^3.2.0",
39
40
  "express": "4.21.2",
@@ -43,6 +44,7 @@
43
44
  "passport-kakao": "1.0.1",
44
45
  "passport-local": "1.0.0",
45
46
  "pino-pretty": "^13.0.0",
47
+ "resend": "^6.4.1",
46
48
  "ua-parser-js": "^2.0.3"
47
49
  },
48
50
  "devDependencies": {