arkos 1.0.1-beta → 1.0.2-alpha

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 (65) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/app.js +1 -1
  3. package/dist/cjs/app.js.map +1 -1
  4. package/dist/cjs/exports/services/index.js +3 -3
  5. package/dist/cjs/exports/services/index.js.map +1 -1
  6. package/dist/cjs/modules/auth/__tests__/auth.controller.test.js +0 -1
  7. package/dist/cjs/modules/auth/__tests__/auth.controller.test.js.map +1 -1
  8. package/dist/cjs/modules/auth/__tests__/auth.service.test.js +470 -0
  9. package/dist/cjs/modules/auth/__tests__/auth.service.test.js.map +1 -0
  10. package/dist/cjs/modules/auth/auth.service.js +30 -9
  11. package/dist/cjs/modules/auth/auth.service.js.map +1 -1
  12. package/dist/cjs/modules/email/email.service.js +12 -7
  13. package/dist/cjs/modules/email/email.service.js.map +1 -1
  14. package/dist/cjs/modules/file-uploader/__tests__/file-uploader.service.test.js +402 -0
  15. package/dist/cjs/modules/file-uploader/__tests__/file-uploader.service.test.js.map +1 -0
  16. package/dist/cjs/modules/file-uploader/file-uploader.controller.js +226 -0
  17. package/dist/cjs/modules/file-uploader/file-uploader.controller.js.map +1 -0
  18. package/dist/cjs/modules/file-uploader/file-uploader.router.js +50 -0
  19. package/dist/cjs/modules/file-uploader/file-uploader.router.js.map +1 -0
  20. package/dist/cjs/modules/file-uploader/file-uploader.service.js +299 -0
  21. package/dist/cjs/modules/file-uploader/file-uploader.service.js.map +1 -0
  22. package/dist/cjs/modules/file-uploader/utils/helpers/__tests__/file-uploader.helpers.test.js +164 -0
  23. package/dist/cjs/modules/file-uploader/utils/helpers/__tests__/file-uploader.helpers.test.js.map +1 -0
  24. package/dist/cjs/modules/file-uploader/utils/helpers/file-uploader.helpers.js +85 -0
  25. package/dist/cjs/modules/file-uploader/utils/helpers/file-uploader.helpers.js.map +1 -0
  26. package/dist/cjs/server.js +1 -1
  27. package/dist/cjs/server.js.map +1 -1
  28. package/dist/cjs/types/arkos-config.js.map +1 -1
  29. package/dist/cjs/types/auth.js.map +1 -1
  30. package/dist/cjs/types/index.js.map +1 -1
  31. package/dist/cjs/utils/helpers/models.helpers.js +19 -6
  32. package/dist/cjs/utils/helpers/models.helpers.js.map +1 -1
  33. package/dist/es2020/app.js +1 -1
  34. package/dist/es2020/app.js.map +1 -1
  35. package/dist/es2020/exports/services/index.js +1 -1
  36. package/dist/es2020/exports/services/index.js.map +1 -1
  37. package/dist/es2020/modules/auth/auth.service.js +30 -9
  38. package/dist/es2020/modules/auth/auth.service.js.map +1 -1
  39. package/dist/es2020/modules/email/email.service.js +12 -7
  40. package/dist/es2020/modules/email/email.service.js.map +1 -1
  41. package/dist/es2020/modules/file-uploader/file-uploader.controller.js +220 -0
  42. package/dist/es2020/modules/file-uploader/file-uploader.controller.js.map +1 -0
  43. package/dist/es2020/modules/file-uploader/file-uploader.router.js +44 -0
  44. package/dist/es2020/modules/file-uploader/file-uploader.router.js.map +1 -0
  45. package/dist/es2020/modules/file-uploader/file-uploader.service.js +291 -0
  46. package/dist/es2020/modules/file-uploader/file-uploader.service.js.map +1 -0
  47. package/dist/es2020/modules/file-uploader/utils/helpers/file-uploader.helpers.js +77 -0
  48. package/dist/es2020/modules/file-uploader/utils/helpers/file-uploader.helpers.js.map +1 -0
  49. package/dist/es2020/server.js +1 -1
  50. package/dist/es2020/server.js.map +1 -1
  51. package/dist/es2020/types/arkos-config.js.map +1 -1
  52. package/dist/es2020/types/auth.js.map +1 -1
  53. package/dist/es2020/types/index.js.map +1 -1
  54. package/dist/es2020/utils/helpers/models.helpers.js +19 -6
  55. package/dist/es2020/utils/helpers/models.helpers.js.map +1 -1
  56. package/dist/types/exports/services/index.d.ts +1 -1
  57. package/dist/types/modules/email/email.service.d.ts +1 -2
  58. package/dist/types/modules/file-uploader/file-uploader.controller.d.ts +3 -0
  59. package/dist/types/modules/file-uploader/file-uploader.router.d.ts +3 -0
  60. package/dist/types/modules/file-uploader/file-uploader.service.d.ts +30 -0
  61. package/dist/types/modules/file-uploader/utils/helpers/file-uploader.helpers.d.ts +2 -0
  62. package/dist/types/types/arkos-config.d.ts +8 -1
  63. package/dist/types/types/auth.d.ts +2 -2
  64. package/dist/types/types/index.d.ts +1 -0
  65. package/package.json +6 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-uploader.service.test.js","sourceRoot":"","sources":["../../../../../src/modules/file-uploader/__tests__/file-uploader.service.test.ts"],"names":[],"mappings":"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","sourcesContent":["import multer from \"multer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { promisify } from \"util\";\nimport sharp from \"sharp\";\nimport {\n FileUploaderService,\n getFileUploaderServices,\n} from \"../file-uploader.service\";\nimport AppError from \"../../error-handler/utils/app-error\";\nimport { getArkosConfig } from \"../../../server\";\n\n// Mock dependencies\njest.mock(\"multer\");\njest.mock(\"path\");\njest.mock(\"fs\");\njest.mock(\"sharp\");\njest.mock(\"util\");\njest.mock(\"../../../server\");\njest.mock(\"../../error-handler/utils/app-error\");\njest.mock(\"../../../utils/helpers/prisma.helpers\");\njest.mock(\"../../../utils/helpers/models.helpers\");\n\ndescribe(\"FileUploaderService\", () => {\n let mockReq: any;\n let mockRes: any;\n let mockNext: any;\n let fileUploaderService: FileUploaderService;\n let mockStorage: any;\n let mockUploader: any;\n let mockSharp: any;\n let mockUnlink = jest.fn().mockResolvedValue(undefined);\n\n let mockStat = jest.fn().mockResolvedValue({ isFile: () => true });\n\n let mockRename = jest.fn().mockResolvedValue(undefined);\n\n beforeEach(() => {\n // Reset all mocks\n jest.resetAllMocks();\n\n // Setup mock request, response, and next function\n mockReq = {\n get: jest.fn((key) => {\n if (key === \"host\") return \"localhost:3000\";\n return null;\n }),\n query: {},\n files: [],\n file: null,\n };\n\n mockRes = {\n status: jest.fn().mockReturnThis(),\n json: jest.fn(),\n };\n\n mockNext = jest.fn();\n\n (fs.existsSync as any as jest.Mock).mockReturnValue(false);\n (fs.mkdirSync as any as jest.Mock).mockReturnValue(undefined);\n\n const mockPromisify = jest.fn((fn) => fn);\n (promisify as any as jest.Mock).mockImplementation(mockPromisify);\n\n (fs.stat as any as jest.Mock) = jest\n .fn()\n .mockReturnValue({ isFile: () => true });\n\n (fs.unlink as any as jest.Mock) = jest.fn();\n\n (fs.access as any as jest.Mock) = jest\n .fn()\n .mockReturnValue({ isFile: () => true });\n\n // (fs.rename as any as jest.Mock) = jest\n // .fn()\n // .mockReturnValue({ isFile: () => true });\n\n mockUnlink = jest.fn().mockResolvedValue(undefined);\n\n mockStat = jest.fn().mockResolvedValue({ isFile: () => true });\n\n (promisify as any as jest.Mock).mockImplementation((fn) => {\n if (fn === fs.unlink) return mockUnlink;\n if (fn === fs.stat) return mockStat;\n if (fn === fs.rename) return mockRename;\n return jest.fn();\n });\n\n // Setup mock for path operations\n (path.join as any as jest.Mock).mockImplementation((...args) =>\n args.join(\"/\")\n );\n (path.extname as any as jest.Mock).mockImplementation((filePath) => \".jpg\");\n (path.basename as any as jest.Mock).mockImplementation((filePath, ext) => {\n return ext ? filePath.replace(ext, \"\") : filePath;\n });\n (path.dirname as any as jest.Mock).mockImplementation((filePath) => {\n const parts = filePath.split(\"/\");\n return parts.slice(0, -1).join(\"/\");\n });\n\n // Setup mock for multer storage\n mockStorage = {\n destination: jest.fn(),\n filename: jest.fn(),\n };\n\n (multer.diskStorage as any as jest.Mock).mockReturnValue(mockStorage);\n\n // Setup mock for multer uploader\n mockUploader = {\n single: jest\n .fn()\n .mockReturnValue((req: any, res: any, next: any) => next()),\n array: jest\n .fn()\n .mockReturnValue((req: any, res: any, next: any) => next()),\n };\n\n (multer as unknown as any as jest.Mock).mockReturnValue(mockUploader);\n\n // Setup mock for getArkosConfig\n (getArkosConfig as any as jest.Mock).mockReturnValue({\n fileUpload: {\n baseRoute: \"/api/uploads\",\n baseUploadDir: \"/uploads\",\n restrictions: {\n images: {\n maxCount: 30,\n maxSize: 15 * 1024 * 1024,\n supportedFilesRegex: /jpeg|jpg|png/,\n },\n },\n },\n });\n\n // Setup mock for sharp\n mockSharp = {\n metadata: jest.fn().mockResolvedValue({ width: 800, height: 600 }),\n resize: jest.fn().mockReturnThis(),\n toFormat: jest.fn().mockReturnThis(),\n toFile: jest.fn().mockResolvedValue({}),\n };\n\n (sharp as unknown as any as jest.Mock).mockReturnValue(mockSharp);\n\n // Initialize the service\n fileUploaderService = new FileUploaderService(\n \"uploads/images\",\n 5 * 1024 * 1024,\n /jpeg|jpg|png/,\n 30\n );\n });\n\n describe(\"constructor\", () => {\n it(\"should initialize with default parameters when not provided\", () => {\n const service = new FileUploaderService(\"uploads/images\");\n\n expect(service[\"uploadDir\"]).toBe(\"./uploads/images/\");\n expect(service[\"fileSizeLimit\"]).toBe(5 * 1024 * 1024); // Default 5MB\n expect(service[\"allowedFileTypes\"]).toEqual(/.*/);\n expect(service[\"maxCount\"]).toBe(30);\n });\n\n it(\"should create the upload directory if it doesn't exist\", () => {\n expect(fs.existsSync).toHaveBeenCalledWith(\"./uploads/images/\");\n expect(fs.mkdirSync).toHaveBeenCalledWith(\"./uploads/images/\", {\n recursive: true,\n });\n });\n\n it(\"should configure multer storage with correct destination and filename\", () => {\n const mockDestinationFn = jest.fn();\n const mockFilenameFn = jest.fn();\n\n (multer.diskStorage as jest.Mock).mockReturnValue({\n destination: mockDestinationFn,\n filename: mockFilenameFn,\n });\n\n new FileUploaderService(\"uploads/images\");\n\n const destinationCallback = (multer.diskStorage as jest.Mock).mock\n .calls[0][0].destination;\n\n const cb = jest.fn();\n destinationCallback({}, {}, cb);\n expect(cb).toHaveBeenCalledWith(null, \"./uploads/images/\");\n\n const filenameCallback = (multer.diskStorage as jest.Mock).mock\n .calls[0][0].filename;\n\n const fileCb = jest.fn();\n const mockFile = { originalname: \"test.jpg\" };\n filenameCallback({}, mockFile, fileCb);\n expect(fileCb).toHaveBeenCalledWith(\n null,\n expect.stringMatching(/\\d+-\\d+\\.jpg/)\n );\n });\n });\n\n describe(\"fileFilter\", () => {\n it(\"should accept valid file types\", () => {\n const fileFilter = fileUploaderService[\"fileFilter\"];\n const cb = jest.fn();\n const mockFile = {\n originalname: \"test.jpg\",\n mimetype: \"image/jpeg\",\n };\n\n fileFilter({}, mockFile, cb);\n\n expect(cb).toHaveBeenCalledWith(null, true);\n });\n\n it(\"should reject invalid file types\", () => {\n // Override the regex for this test\n fileUploaderService[\"allowedFileTypes\"] = /jpeg|jpg|png/;\n\n const fileFilter = fileUploaderService[\"fileFilter\"];\n const cb = jest.fn();\n const mockFile = {\n originalname: \"test.pdf\",\n mimetype: \"application/pdf\",\n };\n\n // Mock path.extname to return .pdf\n (path.extname as any as jest.Mock).mockReturnValueOnce(\".pdf\");\n\n fileFilter({}, mockFile, cb);\n\n expect(cb).toHaveBeenCalledWith(expect.any(AppError));\n expect(AppError).toHaveBeenCalledWith(\"Invalid file type\", 400);\n });\n });\n\n describe(\"getUploader\", () => {\n it(\"should return multer instance with correct configuration\", () => {\n const uploader = fileUploaderService.getUploader();\n\n expect(multer).toHaveBeenCalledWith({\n storage: mockStorage,\n fileFilter: expect.any(Function),\n limits: { fileSize: 5 * 1024 * 1024 },\n });\n\n expect(uploader).toBe(mockUploader);\n });\n });\n\n describe(\"handleSingleUpload\", () => {\n it(\"should call next() if upload is successful\", () => {\n const middleware = fileUploaderService.handleSingleUpload();\n\n middleware(mockReq, mockRes, mockNext);\n\n expect(mockUploader.single).toHaveBeenCalledWith(expect.any(String));\n expect(mockNext).toHaveBeenCalled();\n });\n\n it(\"should delete old file if oldFilePath is provided\", async () => {\n // Make promisify return our specific mocks when called with the right functions\n\n // Override multer implementation\n mockUploader.single.mockReturnValueOnce((req: any, res: any, next: any) =>\n next()\n );\n\n const middleware = fileUploaderService.handleSingleUpload(\n \"old22/path/to/file.jpg\"\n );\n\n await middleware(mockReq, mockRes, () => {});\n\n expect(mockStat).toHaveBeenCalledWith(\"old22/path/to/file.jpg\");\n expect(mockUnlink).toHaveBeenCalledWith(\"old22/path/to/file.jpg\");\n });\n\n it(\"should pass multer errors to next\", () => {\n const multerError = new multer.MulterError(\n \"LIMIT_FILE_SIZE\",\n \"fieldname\"\n );\n\n mockUploader.single.mockReturnValueOnce((req: any, res: any, next: any) =>\n next(multerError)\n );\n\n const middleware = fileUploaderService.handleSingleUpload();\n\n middleware(mockReq, mockRes, mockNext);\n\n expect(mockNext).toHaveBeenCalledWith(multerError);\n });\n\n it(\"should pass regular errors to next\", () => {\n const regularError = new Error(\"Some other error\");\n\n mockUploader.single.mockReturnValueOnce((req: any, res: any, next: any) =>\n next(regularError)\n );\n\n const middleware = fileUploaderService.handleSingleUpload();\n\n middleware(mockReq, mockRes, mockNext);\n\n expect(mockNext).toHaveBeenCalledWith(regularError);\n });\n });\n\n describe(\"handleMultipleUpload\", () => {\n it(\"should call next() if multiple upload is successful\", () => {\n const middleware = fileUploaderService.handleMultipleUpload();\n\n middleware(mockReq, mockRes, mockNext);\n\n expect(mockUploader.array).toHaveBeenCalledWith(expect.any(String), 30);\n expect(mockNext).toHaveBeenCalled();\n });\n\n it(\"should pass multer errors to next\", () => {\n const multerError = new multer.MulterError(\n \"LIMIT_FILE_COUNT\",\n \"fieldname\"\n );\n\n mockUploader.array.mockReturnValueOnce((req: any, res: any, next: any) =>\n next(multerError)\n );\n\n const middleware = fileUploaderService.handleMultipleUpload();\n\n middleware(mockReq, mockRes, mockNext);\n\n expect(mockNext).toHaveBeenCalledWith(multerError);\n });\n });\n\n describe(\"handleDeleteSingleFile\", () => {\n it(\"should delete the file if it exists\", async () => {\n const middleware =\n fileUploaderService.handleDeleteSingleFile(\"path/to/file.jpg\");\n\n await middleware(mockReq, mockRes, mockNext);\n\n expect(mockStat).toHaveBeenCalledWith(\"path/to/file.jpg\");\n expect(mockUnlink).toHaveBeenCalledWith(\"path/to/file.jpg\");\n expect(mockNext).toHaveBeenCalled();\n });\n\n it(\"should call next even if file doesn't exist\", async () => {\n const middleware = fileUploaderService.handleDeleteSingleFile(\n \"nonexistent/file.jpg\"\n );\n\n await middleware(mockReq, mockRes, mockNext);\n\n expect(mockNext).toHaveBeenCalled();\n });\n });\n\n describe(\"deleteFileByUrl\", () => {\n it(\"should delete a file by its URL\", async () => {\n const result = await fileUploaderService.deleteFileByUrl(\n \"http://localhost:3000/api/uploads/images/file.jpg\"\n );\n\n expect(mockStat).toHaveBeenCalled();\n expect(mockUnlink).toHaveBeenCalled();\n expect(result).toBe(true);\n });\n\n it(\"should throw AppError if file URL is invalid\", async () => {\n await expect(\n fileUploaderService.deleteFileByUrl(\n \"http://localhost:3000/invalid/path\"\n )\n ).rejects.toBeInstanceOf(AppError);\n\n expect(AppError).toHaveBeenCalledWith(\n \"Invalid file URL: base route not found\",\n 400\n );\n });\n\n it(\"should throw AppError if file doesn't exist\", async () => {\n // Setup fs.access to fail with ENOENT error\n const enoentError = new Error(\"File not found\");\n (enoentError as any).code = \"ENOENT\";\n mockStat.mockImplementationOnce((path, mode, cb) => {\n throw enoentError;\n });\n\n await expect(\n fileUploaderService.deleteFileByUrl(\n \"http://localhost:3000/api/uploads/images/nonexistent.jpg\"\n )\n ).rejects.toBeInstanceOf(AppError);\n\n expect(AppError).toHaveBeenCalledWith(\"File not found\", 404);\n });\n });\n\n describe(\"upload\", () => {\n beforeEach(() => {\n // Setup base test environment\n mockReq.query = { multiple: \"false\" };\n mockReq.file = {\n path: \"test.jpg\",\n originalname: \"test.jpg\",\n };\n });\n\n it(\"should handle single file upload successfully\", async () => {\n // Setup mocks\n mockUploader.single.mockReturnValueOnce(\n (req: any, res: any, next: Function) => {\n req.file = mockReq.file;\n next();\n }\n );\n\n const result = await fileUploaderService.upload(mockReq, mockRes);\n\n expect(result).toBe(\"http://localhost:3000/api/uploads/images/test.jpg\");\n });\n\n it(\"should handle multiple file uploads successfully\", async () => {\n // Setup mocks for multiple files\n mockReq.query = { multiple: \"true\" };\n mockReq.files = [\n { path: \"test1.jpg\", originalname: \"test1.jpg\" },\n { path: \"test2.jpg\", originalname: \"test2.jpg\" },\n ];\n mockReq.file = null;\n\n mockUploader.array.mockReturnValueOnce(\n (req: any, res: any, next: Function) => {\n req.files = mockReq.files;\n next();\n }\n );\n\n const result = await fileUploaderService.upload(mockReq, mockRes);\n\n expect(Array.isArray(result)).toBe(true);\n expect(result).toHaveLength(2);\n expect(result![0]).toBe(\n \"http://localhost:3000/api/uploads/images/test1.jpg\"\n );\n expect(result![1]).toBe(\n \"http://localhost:3000/api/uploads/images/test2.jpg\"\n );\n });\n\n it(\"should process images with Sharp when uploading image files\", async () => {\n // Setup specific mock for image processing\n mockReq.file = {\n path: \"test.jpg\",\n originalname: \"test.jpg\",\n };\n\n // Mock that we're using the image uploader\n fileUploaderService[\"uploadDir\"] = \"/uploads/images/\";\n // console.log(fileUploaderService.uploadDir);\n const imageUploaderService = new FileUploaderService(\"uploads/images\");\n\n mockUploader.single.mockReturnValueOnce(\n (req: any, res: any, next: Function) => {\n req.file = mockReq.file;\n next();\n }\n );\n\n const result = await imageUploaderService.upload(mockReq, mockRes, {\n width: 300,\n height: 200,\n format: \"webp\",\n });\n\n expect(sharp).toHaveBeenCalledWith(\"test.jpg\");\n expect(mockSharp.resize).toHaveBeenCalledWith(\n 300,\n 200,\n expect.any(Object)\n );\n expect(mockSharp.toFormat).toHaveBeenCalledWith(\"webp\");\n expect(mockSharp.toFile).toHaveBeenCalled();\n expect(mockRename).toHaveBeenCalled();\n expect(result).toBe(\"http://localhost:3000/api/uploads/images/test.jpg\");\n });\n\n it(\"should throw AppError if no file is uploaded\", async () => {\n // Setup no files\n mockReq.file = null;\n mockReq.files = null;\n\n mockUploader.single.mockReturnValueOnce(\n (req: any, res: any, next: Function) => next()\n );\n\n await expect(\n fileUploaderService.upload(mockReq, mockRes)\n ).rejects.toBeInstanceOf(AppError);\n expect(AppError).toHaveBeenCalledWith(\"No file uploaded\", 400);\n });\n\n it(\"should handle upload errors\", async () => {\n const uploadError = new Error(\"Upload failed\");\n\n mockUploader.single.mockReturnValueOnce(\n (req: any, res: any, next: Function) => next(uploadError)\n );\n\n await expect(\n fileUploaderService.upload(mockReq, mockRes)\n ).rejects.toEqual(uploadError);\n });\n\n it(\"should handle image processing errors\", async () => {\n mockReq.file = {\n path: \"uploads/images/test.jpg\",\n originalname: \"test.jpg\",\n };\n\n // Mock that we're using the image uploader\n fileUploaderService[\"uploadDir\"] = \"./uploads/images/\";\n\n mockUploader.single.mockReturnValueOnce(\n (req: any, res: any, next: Function) => {\n req.file = mockReq.file;\n next();\n }\n );\n\n // Setup Sharp to throw an error\n const processingError = new Error(\"Image processing failed\");\n mockSharp.toFile.mockRejectedValueOnce(processingError);\n\n await expect(\n fileUploaderService.upload(mockReq, mockRes, { format: \"webp\" })\n ).rejects.toEqual(processingError);\n });\n });\n\n describe(\"getFileUploaderServices\", () => {\n it(\"should return all file uploader services\", () => {\n const services = getFileUploaderServices();\n\n expect(services).toHaveProperty(\"imageUploaderService\");\n expect(services).toHaveProperty(\"videoUploaderService\");\n expect(services).toHaveProperty(\"documentUploaderService\");\n expect(services).toHaveProperty(\"fileUploaderService\");\n\n expect(services.imageUploaderService).toBeInstanceOf(FileUploaderService);\n expect(services.videoUploaderService).toBeInstanceOf(FileUploaderService);\n expect(services.documentUploaderService).toBeInstanceOf(\n FileUploaderService\n );\n expect(services.fileUploaderService).toBeInstanceOf(FileUploaderService);\n });\n\n it(\"should use config values when available\", () => {\n // Setup config with custom values\n (getArkosConfig as any as jest.Mock).mockReturnValue({\n fileUpload: {\n baseRoute: \"/custom/api/uploads\",\n baseUploadDir: \"/custom/uploads\",\n restrictions: {\n images: {\n maxCount: 50,\n maxSize: 20 * 1024 * 1024,\n supportedFilesRegex: /custom-regex/,\n },\n },\n },\n });\n\n const services = getFileUploaderServices();\n\n // Test that the custom config values were used\n expect(services.imageUploaderService[\"uploadDir\"]).toBe(\n \"./custom/uploads/images/\"\n );\n expect(services.imageUploaderService[\"maxCount\"]).toBe(50);\n expect(services.imageUploaderService[\"fileSizeLimit\"]).toBe(\n 20 * 1024 * 1024\n );\n expect(services.imageUploaderService[\"allowedFileTypes\"]).toEqual(\n /custom-regex/\n );\n });\n\n it(\"should use default values when config is not available\", () => {\n // Setup empty config\n (getArkosConfig as any as jest.Mock).mockReturnValue({});\n\n const services = getFileUploaderServices();\n\n // Test that default values were used\n expect(services.imageUploaderService[\"uploadDir\"]).toBe(\n \"./uploads/images/\"\n );\n expect(services.videoUploaderService[\"uploadDir\"]).toBe(\n \"./uploads/videos/\"\n );\n expect(services.documentUploaderService[\"uploadDir\"]).toBe(\n \"./uploads/documents/\"\n );\n expect(services.fileUploaderService[\"uploadDir\"]).toBe(\n \"./uploads/files/\"\n );\n });\n });\n});\n"]}
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.streamFile = exports.deleteFile = exports.uploadFile = void 0;
16
+ const app_error_1 = __importDefault(require("../error-handler/utils/app-error"));
17
+ const file_uploader_service_1 = require("./file-uploader.service");
18
+ const path_1 = __importDefault(require("path"));
19
+ const fs_1 = __importDefault(require("fs"));
20
+ const sharp_1 = __importDefault(require("sharp"));
21
+ const catch_async_1 = __importDefault(require("../error-handler/utils/catch-async"));
22
+ const util_1 = require("util");
23
+ const server_1 = require("../../server");
24
+ const stat = (0, util_1.promisify)(fs_1.default.stat);
25
+ const unlink = (0, util_1.promisify)(fs_1.default.unlink);
26
+ const access = (0, util_1.promisify)(fs_1.default.access);
27
+ const mkdir = (0, util_1.promisify)(fs_1.default.mkdir);
28
+ exports.uploadFile = (0, catch_async_1.default)((req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
29
+ const { fileType } = req.params;
30
+ const { format, width, height, resizeTo } = req.query;
31
+ const { documentUploaderService, fileUploaderService, imageUploaderService, videoUploaderService, } = (0, file_uploader_service_1.getFileUploaderServices)();
32
+ const { fileUpload } = (0, server_1.getArkosConfig)();
33
+ const baseUploadDir = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseUploadDir) || "/uploads";
34
+ const uploadPath = path_1.default.resolve(process.cwd(), baseUploadDir, fileType);
35
+ try {
36
+ yield access(uploadPath);
37
+ }
38
+ catch (error) {
39
+ yield mkdir(uploadPath, { recursive: true });
40
+ }
41
+ let uploader;
42
+ switch (fileType) {
43
+ case "images":
44
+ uploader = imageUploaderService;
45
+ break;
46
+ case "videos":
47
+ uploader = videoUploaderService;
48
+ break;
49
+ case "documents":
50
+ uploader = documentUploaderService;
51
+ break;
52
+ case "files":
53
+ uploader = fileUploaderService;
54
+ break;
55
+ default:
56
+ return next(new app_error_1.default("Invalid file type", 400));
57
+ }
58
+ uploader.handleMultipleUpload()(req, res, (err) => __awaiter(void 0, void 0, void 0, function* () {
59
+ var _a;
60
+ if (err)
61
+ return next(err);
62
+ const protocol = ((_a = req.get("host")) === null || _a === void 0 ? void 0 : _a.includes("localhost"))
63
+ ? "http"
64
+ : "https";
65
+ const baseURL = `${protocol}://${req.get("host")}`;
66
+ const baseRoute = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/api/uploads";
67
+ const generateRelativePath = (filePath) => {
68
+ if (baseUploadDir.startsWith("..")) {
69
+ return path_1.default.join(fileType, path_1.default.basename(filePath));
70
+ }
71
+ else {
72
+ return filePath.replace(`${process.cwd()}${baseUploadDir}/`, "");
73
+ }
74
+ };
75
+ const processImage = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
76
+ const ext = path_1.default.extname(filePath).toLowerCase();
77
+ const originalFormat = ext.replace(".", "");
78
+ const outputFormat = format
79
+ ? format.toString().toLowerCase()
80
+ : originalFormat;
81
+ if (!/jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif/i.test(originalFormat)) {
82
+ const relativePath = generateRelativePath(filePath);
83
+ return `${baseURL}${baseRoute}/${relativePath}`;
84
+ }
85
+ const tempName = `${path_1.default.basename(filePath, ext)}_${Date.now()}${ext}`;
86
+ const tempPath = path_1.default.join(path_1.default.dirname(filePath), tempName);
87
+ try {
88
+ let transformer = (0, sharp_1.default)(filePath);
89
+ const metadata = yield transformer.metadata();
90
+ if (resizeTo && metadata.width && metadata.height) {
91
+ const targetSize = parseInt(resizeTo.toString());
92
+ const scaleFactor = targetSize / Math.min(metadata.width, metadata.height);
93
+ const newWidth = Math.round(metadata.width * scaleFactor);
94
+ const newHeight = Math.round(metadata.height * scaleFactor);
95
+ transformer = transformer.resize(newWidth, newHeight);
96
+ }
97
+ else if (width || height) {
98
+ transformer = transformer.resize(width ? parseInt(width) : null, height ? parseInt(height) : null, { fit: "inside" });
99
+ }
100
+ if (outputFormat === "webp") {
101
+ transformer = transformer.toFormat("webp");
102
+ }
103
+ else if (outputFormat === "jpeg" || outputFormat === "jpg") {
104
+ transformer = transformer.toFormat("jpeg");
105
+ }
106
+ yield transformer.toFile(tempPath);
107
+ yield fs_1.default.promises.rename(tempPath, filePath);
108
+ const relativePath = generateRelativePath(filePath);
109
+ return `${baseURL}${baseRoute}/${relativePath}`;
110
+ }
111
+ catch (error) {
112
+ try {
113
+ yield fs_1.default.promises.stat(tempPath);
114
+ yield fs_1.default.promises.unlink(tempPath);
115
+ }
116
+ catch (_a) {
117
+ }
118
+ next(error);
119
+ return null;
120
+ }
121
+ });
122
+ const processFile = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
123
+ const relativePath = generateRelativePath(filePath);
124
+ return `${baseURL}${baseRoute}/${relativePath}`;
125
+ });
126
+ let data;
127
+ if (req.files && Array.isArray(req.files)) {
128
+ if (fileType === "images") {
129
+ data = yield Promise.all(req.files.map((file) => processImage(file.path)));
130
+ }
131
+ else {
132
+ data = yield Promise.all(req.files.map((file) => processFile(file.path)));
133
+ }
134
+ data = data.filter((url) => url !== null);
135
+ }
136
+ else if (req.file) {
137
+ if (fileType === "images") {
138
+ data = yield processImage(req.file.path);
139
+ }
140
+ else {
141
+ data = yield processFile(req.file.path);
142
+ }
143
+ }
144
+ else {
145
+ return next(new app_error_1.default("No file uploaded", 400));
146
+ }
147
+ res.status(200).json({
148
+ success: true,
149
+ data,
150
+ message: Array.isArray(data)
151
+ ? `${data.length} files uploaded successfully`
152
+ : "File uploaded successfully",
153
+ });
154
+ }));
155
+ }));
156
+ exports.deleteFile = (0, catch_async_1.default)((req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
157
+ const { fileType, fileName } = req.params;
158
+ const { documentUploaderService, fileUploaderService, imageUploaderService, videoUploaderService, } = (0, file_uploader_service_1.getFileUploaderServices)();
159
+ let uploader;
160
+ switch (fileType) {
161
+ case "images":
162
+ uploader = imageUploaderService;
163
+ break;
164
+ case "videos":
165
+ uploader = videoUploaderService;
166
+ break;
167
+ case "documents":
168
+ uploader = documentUploaderService;
169
+ break;
170
+ case "files":
171
+ uploader = fileUploaderService;
172
+ break;
173
+ default:
174
+ return next(new app_error_1.default("Invalid file type", 400));
175
+ }
176
+ try {
177
+ const fullUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
178
+ yield uploader.deleteFileByUrl(fullUrl);
179
+ res.status(200).json({
180
+ success: true,
181
+ message: "File deleted successfully",
182
+ });
183
+ }
184
+ catch (error) {
185
+ return next(new app_error_1.default("File not found", 404));
186
+ }
187
+ }));
188
+ exports.streamFile = (0, catch_async_1.default)((req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
189
+ const { fileName, fileType } = req.params;
190
+ const filePath = path_1.default.join(".", "uploads", fileType, fileName);
191
+ try {
192
+ yield access(filePath);
193
+ }
194
+ catch (_a) {
195
+ return next(new app_error_1.default("File not found", 404));
196
+ }
197
+ const fileStat = yield stat(filePath);
198
+ const fileSize = fileStat.size;
199
+ const range = req.headers.range;
200
+ if (range) {
201
+ const [partialStart, partialEnd] = range.replace(/bytes=/, "").split("-");
202
+ const start = parseInt(partialStart, 10) || 0;
203
+ const end = partialEnd ? parseInt(partialEnd, 10) : fileSize - 1;
204
+ if (start >= fileSize || end >= fileSize) {
205
+ res.status(416).json({ error: "Range Not Satisfiable" });
206
+ return;
207
+ }
208
+ res.writeHead(206, {
209
+ "Content-Range": `bytes ${start}-${end}/${fileSize}`,
210
+ "Accept-Ranges": "bytes",
211
+ "Content-Length": end - start + 1,
212
+ "Content-Type": "application/octet-stream",
213
+ "Content-Disposition": `inline; filename="${fileName}"`,
214
+ });
215
+ fs_1.default.createReadStream(filePath, { start, end }).pipe(res);
216
+ }
217
+ else {
218
+ res.writeHead(200, {
219
+ "Content-Length": fileSize,
220
+ "Content-Type": "application/octet-stream",
221
+ "Content-Disposition": `inline; filename="${fileName}"`,
222
+ });
223
+ fs_1.default.createReadStream(filePath).pipe(res);
224
+ }
225
+ }));
226
+ //# sourceMappingURL=file-uploader.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-uploader.controller.js","sourceRoot":"","sources":["../../../../src/modules/file-uploader/file-uploader.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import AppError from \"../error-handler/utils/app-error\";\nimport {\n FileUploaderService,\n getFileUploaderServices,\n} from \"./file-uploader.service\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport sharp from \"sharp\";\nimport { NextFunction, Request, Response } from \"express\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport { promisify } from \"util\";\nimport { getArkosConfig } from \"../../server\";\n\nconst stat = promisify(fs.stat);\nconst unlink = promisify(fs.unlink);\nconst access = promisify(fs.access);\nconst mkdir = promisify(fs.mkdir);\n/**\n * Handles file upload requests, processes images if needed, and returns URLs\n * Supports paths outside of the project directory with '../' prefix\n * @param {Request} req - Express request object\n * @param {Response} res - Express response object\n * @param {NextFunction} next - Express next middleware function\n */\nexport const uploadFile = catchAsync(\n async (req: Request, res: Response, next: NextFunction) => {\n const { fileType } = req.params;\n const { format, width, height, resizeTo } = req.query;\n\n const {\n documentUploaderService,\n fileUploaderService,\n imageUploaderService,\n videoUploaderService,\n } = getFileUploaderServices();\n\n const { fileUpload } = getArkosConfig();\n const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n\n // Ensure upload directory exists\n const uploadPath = path.resolve(process.cwd(), baseUploadDir, fileType);\n try {\n await access(uploadPath);\n } catch (error) {\n // Create directory if it doesn't exist\n await mkdir(uploadPath, { recursive: true });\n }\n\n // Select the appropriate uploader service based on file type\n let uploader: FileUploaderService;\n switch (fileType) {\n case \"images\":\n uploader = imageUploaderService;\n break;\n case \"videos\":\n uploader = videoUploaderService;\n break;\n case \"documents\":\n uploader = documentUploaderService;\n break;\n case \"files\":\n uploader = fileUploaderService;\n break;\n default:\n return next(new AppError(\"Invalid file type\", 400));\n }\n\n // Handle the file upload\n uploader.handleMultipleUpload()(req, res, async (err) => {\n if (err) return next(err);\n\n // Determine the base URL for file access\n const protocol = req.get(\"host\")?.includes(\"localhost\")\n ? \"http\"\n : \"https\";\n const baseURL = `${protocol}://${req.get(\"host\")}`;\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n /**\n * Generates the correct relative path regardless of upload directory location\n * @param {string} filePath - Full path to the uploaded file\n * @returns {string} Relative path for URL generation\n */\n const generateRelativePath = (filePath: string) => {\n if (baseUploadDir.startsWith(\"..\")) {\n // For paths outside project directory\n return path.join(fileType, path.basename(filePath));\n } else {\n // Original approach for paths within project\n return filePath.replace(`${process.cwd()}${baseUploadDir}/`, \"\");\n }\n };\n\n /**\n * Processes image files using Sharp for resizing and format conversion\n * @param {string} filePath - Path to the uploaded image file\n * @returns {Promise<string|null>} Public URL for the processed file or null if processing failed\n */\n const processImage = async (filePath: string): Promise<string | null> => {\n const ext = path.extname(filePath).toLowerCase();\n const originalFormat = ext.replace(\".\", \"\");\n const outputFormat = format\n ? format.toString().toLowerCase()\n : originalFormat;\n\n // Skip processing for non-image files\n if (!/jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif/i.test(originalFormat)) {\n const relativePath = generateRelativePath(filePath);\n return `${baseURL}${baseRoute}/${relativePath}`;\n }\n\n // Create a temp filename with original name + random string\n const tempName = `${path.basename(filePath, ext)}_${Date.now()}${ext}`;\n const tempPath = path.join(path.dirname(filePath), tempName);\n\n try {\n let transformer = sharp(filePath);\n const metadata = await transformer.metadata();\n\n // Apply resize transformations if requested\n if (resizeTo && metadata.width && metadata.height) {\n const targetSize = parseInt(resizeTo.toString());\n const scaleFactor =\n targetSize / Math.min(metadata.width, metadata.height);\n const newWidth = Math.round(metadata.width * scaleFactor);\n const newHeight = Math.round(metadata.height * scaleFactor);\n transformer = transformer.resize(newWidth, newHeight);\n } else if (width || height) {\n transformer = transformer.resize(\n width ? parseInt(width as string) : null,\n height ? parseInt(height as string) : null,\n { fit: \"inside\" }\n );\n }\n\n // Apply format transformations if requested\n if (outputFormat === \"webp\") {\n transformer = transformer.toFormat(\"webp\");\n } else if (outputFormat === \"jpeg\" || outputFormat === \"jpg\") {\n transformer = transformer.toFormat(\"jpeg\");\n }\n\n // Save to temp file first\n await transformer.toFile(tempPath);\n\n // Rename temp file to original filename\n await fs.promises.rename(tempPath, filePath);\n\n // Return the public URL for the file\n const relativePath = generateRelativePath(filePath);\n return `${baseURL}${baseRoute}/${relativePath}`;\n } catch (error) {\n // Clean up temp file if it exists\n try {\n await fs.promises.stat(tempPath);\n await fs.promises.unlink(tempPath);\n } catch {\n // If temp file doesn't exist, no need to clean up\n }\n next(error);\n return null;\n }\n };\n\n /**\n * Handles basic file processing for non-image files\n * @param {string} filePath - Path to the uploaded file\n * @returns {Promise<string>} Public URL for the file\n */\n const processFile = async (filePath: string) => {\n const relativePath = generateRelativePath(filePath);\n return `${baseURL}${baseRoute}/${relativePath}`;\n };\n\n // Process all uploaded files\n let data;\n if (req.files && Array.isArray(req.files)) {\n if (fileType === \"images\") {\n // Process multiple image files with image transformations\n data = await Promise.all(\n req.files.map((file) => processImage(file.path))\n );\n } else {\n // Just store other file types without processing\n data = await Promise.all(\n req.files.map((file) => processFile(file.path))\n );\n }\n // Filter out any null values from failed processing\n data = data.filter((url) => url !== null);\n } else if (req.file) {\n // Process a single file\n if (fileType === \"images\") {\n data = await processImage(req.file.path);\n } else {\n data = await processFile(req.file.path);\n }\n } else {\n return next(new AppError(\"No file uploaded\", 400));\n }\n\n res.status(200).json({\n success: true,\n data,\n message: Array.isArray(data)\n ? `${data.length} files uploaded successfully`\n : \"File uploaded successfully\",\n });\n });\n }\n);\n\n/**\n * Handles file deletion requests\n * Supports paths outside of the project directory with '../' prefix\n * @param {Request} req - Express request object\n * @param {Response} res - Express response object\n * @param {NextFunction} next - Express next middleware function\n */\nexport const deleteFile = catchAsync(\n async (req: Request, res: Response, next: NextFunction) => {\n const { fileType, fileName } = req.params;\n\n // if (!fileName) {\n // return next(new AppError(\"File name is required\", 400));\n // }\n\n // if (!fileType) {\n // return next(new AppError(\"File type is required\", 400));\n // }\n\n // // Get the base upload directory from config\n // const { fileUpload } = getArkosConfig();\n // const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n\n // // Construct the actual file path using path.resolve to handle '../' paths\n // const actualFilePath = path.resolve(\n // process.cwd(),\n // baseUploadDir,\n // fileType,\n // fileName\n // );\n\n const {\n documentUploaderService,\n fileUploaderService,\n imageUploaderService,\n videoUploaderService,\n } = getFileUploaderServices();\n\n let uploader: FileUploaderService;\n switch (fileType) {\n case \"images\":\n uploader = imageUploaderService;\n break;\n case \"videos\":\n uploader = videoUploaderService;\n break;\n case \"documents\":\n uploader = documentUploaderService;\n break;\n case \"files\":\n uploader = fileUploaderService;\n break;\n default:\n return next(new AppError(\"Invalid file type\", 400));\n }\n\n try {\n // // Check if file exists\n // await access(actualFilePath, fs.constants.F_OK);\n\n // // Delete the file\n // await unlink(actualFilePath);\n\n const fullUrl = `${req.protocol}://${req.get(\"host\")}${req.originalUrl}`;\n await uploader.deleteFileByUrl(fullUrl);\n\n res.status(200).json({\n success: true,\n message: \"File deleted successfully\",\n });\n } catch (error) {\n // File doesn't exist\n return next(new AppError(\"File not found\", 404));\n }\n }\n);\n\nexport const streamFile = catchAsync(\n async (req: Request, res: Response, next: NextFunction) => {\n const { fileName, fileType } = req.params;\n\n const filePath = path.join(\".\", \"uploads\", fileType, fileName);\n try {\n await access(filePath);\n } catch {\n return next(new AppError(\"File not found\", 404));\n }\n\n const fileStat = await stat(filePath);\n const fileSize = fileStat.size;\n const range = req.headers.range;\n\n if (range) {\n const [partialStart, partialEnd] = range.replace(/bytes=/, \"\").split(\"-\");\n const start = parseInt(partialStart, 10) || 0;\n const end = partialEnd ? parseInt(partialEnd, 10) : fileSize - 1;\n\n if (start >= fileSize || end >= fileSize) {\n res.status(416).json({ error: \"Range Not Satisfiable\" });\n return;\n }\n\n res.writeHead(206, {\n \"Content-Range\": `bytes ${start}-${end}/${fileSize}`,\n \"Accept-Ranges\": \"bytes\",\n \"Content-Length\": end - start + 1,\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Disposition\": `inline; filename=\"${fileName}\"`,\n });\n\n fs.createReadStream(filePath, { start, end }).pipe(res);\n } else {\n res.writeHead(200, {\n \"Content-Length\": fileSize,\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Disposition\": `inline; filename=\"${fileName}\"`,\n });\n fs.createReadStream(filePath).pipe(res);\n }\n }\n);\n"]}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getFileUploaderRouter = getFileUploaderRouter;
16
+ const express_1 = require("express");
17
+ const models_helpers_1 = require("../../utils/helpers/models.helpers");
18
+ const auth_service_1 = __importDefault(require("../auth/auth.service"));
19
+ const file_uploader_controller_1 = require("./file-uploader.controller");
20
+ const path_1 = __importDefault(require("path"));
21
+ const express_2 = __importDefault(require("express"));
22
+ const deepmerge_helper_1 = __importDefault(require("../../utils/helpers/deepmerge.helper"));
23
+ const router = (0, express_1.Router)();
24
+ function getFileUploaderRouter(_a) {
25
+ return __awaiter(this, arguments, void 0, function* ({ fileUpload }) {
26
+ const modelModules = yield (0, models_helpers_1.importPrismaModelModules)("file-upload");
27
+ let { middlewares = {}, authConfigs = {} } = {};
28
+ if (modelModules) {
29
+ ({ middlewares = {}, authConfigs = {} } = modelModules);
30
+ }
31
+ let basePathname = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/uploads/";
32
+ if (!basePathname.startsWith("/"))
33
+ basePathname = "/" + basePathname;
34
+ if (!basePathname.endsWith("/"))
35
+ basePathname = basePathname + "/";
36
+ router.use((fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/api/uploads", auth_service_1.default.handleAuthenticationControl(authConfigs, "view", "file-upload"), auth_service_1.default.handleActionAccessControl(authConfigs, "view", "file-upload"), express_2.default.static(path_1.default.resolve(process.cwd(), (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseUploadDir) || "uploads"), (0, deepmerge_helper_1.default)({
37
+ maxAge: "1y",
38
+ etag: true,
39
+ lastModified: true,
40
+ dotfiles: "ignore",
41
+ fallthrough: true,
42
+ index: false,
43
+ cacheControl: true,
44
+ }, (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.expressStaticOptions) || {})));
45
+ router.post(`${basePathname}:fileType`, auth_service_1.default.handleAuthenticationControl(authConfigs, "create", "file-upload"), auth_service_1.default.handleActionAccessControl(authConfigs, "create", "file-upload"), file_uploader_controller_1.uploadFile);
46
+ router.delete(`${basePathname}:fileType/:fileName`, auth_service_1.default.handleAuthenticationControl(authConfigs, "delete", "file-upload"), auth_service_1.default.handleActionAccessControl(authConfigs, "create", "file-upload"), file_uploader_controller_1.deleteFile);
47
+ return router;
48
+ });
49
+ }
50
+ //# sourceMappingURL=file-uploader.router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-uploader.router.js","sourceRoot":"","sources":["../../../../src/modules/file-uploader/file-uploader.router.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAWA,sDAyDC;AApED,qCAAiC;AACjC,uEAA8E;AAC9E,wEAA+C;AAC/C,yEAAoE;AAEpE,gDAAwB;AACxB,sDAA8B;AAC9B,4FAA6D;AAE7D,MAAM,MAAM,GAAW,IAAA,gBAAM,GAAE,CAAC;AAEhC,SAAsB,qBAAqB;yDAAC,EAAE,UAAU,EAAe;QACrE,MAAM,YAAY,GAAG,MAAM,IAAA,yCAAwB,EAAC,aAAa,CAAC,CAAC;QACnE,IAAI,EAAE,WAAW,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC;QAEhD,IAAI,YAAY,EAAE,CAAC;YACjB,CAAC,EAAE,WAAW,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,YAAY,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,KAAI,WAAW,CAAC;QAExD,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,YAAY,GAAG,GAAG,GAAG,YAAY,CAAC;QACrE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,YAAY,GAAG,YAAY,GAAG,GAAG,CAAC;QAEnE,MAAM,CAAC,GAAG,CACR,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,SAAS,KAAI,cAAc,EACvC,sBAAW,CAAC,2BAA2B,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EAC3E,sBAAW,CAAC,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EACzE,iBAAO,CAAC,MAAM,CACZ,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,aAAa,KAAI,SAAS,CAAC,EACnE,IAAA,0BAAS,EACP;YACE,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,IAAI;YACV,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,IAAI;YACjB,KAAK,EAAE,KAAK;YACZ,YAAY,EAAE,IAAI;SACnB,EACD,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,oBAAoB,KAAI,EAAE,CACvC,CACF,CACF,CAAC;QAEF,MAAM,CAAC,IAAI,CACT,GAAG,YAAY,WAAW,EAC1B,sBAAW,CAAC,2BAA2B,CACrC,WAAW,EACX,QAAQ,EACR,aAAa,CACd,EACD,sBAAW,CAAC,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,EAC3E,qCAAU,CACX,CAAC;QAEF,MAAM,CAAC,MAAM,CACX,GAAG,YAAY,qBAAqB,EACpC,sBAAW,CAAC,2BAA2B,CACrC,WAAW,EACX,QAAQ,EACR,aAAa,CACd,EACD,sBAAW,CAAC,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,EAC3E,qCAAU,CACX,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;CAAA","sourcesContent":["import { Router } from \"express\";\nimport { importPrismaModelModules } from \"../../utils/helpers/models.helpers\";\nimport authService from \"../auth/auth.service\";\nimport { deleteFile, uploadFile } from \"./file-uploader.controller\";\nimport { ArkosConfig } from \"../../types/arkos-config\";\nimport path from \"path\";\nimport express from \"express\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\n\nconst router: Router = Router();\n\nexport async function getFileUploaderRouter({ fileUpload }: ArkosConfig) {\n const modelModules = await importPrismaModelModules(\"file-upload\");\n let { middlewares = {}, authConfigs = {} } = {};\n\n if (modelModules) {\n ({ middlewares = {}, authConfigs = {} } = modelModules);\n }\n\n let basePathname = fileUpload?.baseRoute || \"/uploads/\";\n\n if (!basePathname.startsWith(\"/\")) basePathname = \"/\" + basePathname;\n if (!basePathname.endsWith(\"/\")) basePathname = basePathname + \"/\";\n\n router.use(\n fileUpload?.baseRoute || \"/api/uploads\",\n authService.handleAuthenticationControl(authConfigs, \"view\", \"file-upload\"),\n authService.handleActionAccessControl(authConfigs, \"view\", \"file-upload\"),\n express.static(\n path.resolve(process.cwd(), fileUpload?.baseUploadDir || \"uploads\"),\n deepmerge(\n {\n maxAge: \"1y\",\n etag: true,\n lastModified: true,\n dotfiles: \"ignore\",\n fallthrough: true,\n index: false,\n cacheControl: true,\n },\n fileUpload?.expressStaticOptions || {}\n )\n )\n );\n\n router.post(\n `${basePathname}:fileType`,\n authService.handleAuthenticationControl(\n authConfigs,\n \"create\",\n \"file-upload\"\n ),\n authService.handleActionAccessControl(authConfigs, \"create\", \"file-upload\"),\n uploadFile\n );\n\n router.delete(\n `${basePathname}:fileType/:fileName`,\n authService.handleAuthenticationControl(\n authConfigs,\n \"delete\",\n \"file-upload\"\n ),\n authService.handleActionAccessControl(authConfigs, \"create\", \"file-upload\"),\n deleteFile\n );\n\n return router;\n}\n"]}