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
@@ -8,14 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import nodemailer from "nodemailer";
11
- import { BaseService } from "../base/base.service";
12
11
  import { convert } from "html-to-text";
13
- export class EmailService extends BaseService {
12
+ import { getArkosConfig } from "../../server";
13
+ import AppError from "../error-handler/utils/app-error";
14
+ export class EmailService {
14
15
  constructor(host = process.env.EMAIL_HOST, auth = {
15
16
  user: process.env.EMAIL_FROM,
16
17
  pass: process.env.EMAIL_PASSWORD,
17
18
  }, port = parseInt(process.env.EMAIL_PORT || "465")) {
18
- super("email");
19
19
  this.defaultHost = host;
20
20
  this.defaultPort = port;
21
21
  this.defaultAuth = auth;
@@ -86,10 +86,15 @@ export class EmailService extends BaseService {
86
86
  });
87
87
  }
88
88
  static create(options) {
89
- return new EmailService(options.host || process.env.EMAIL_HOST, options.auth || {
90
- user: process.env.EMAIL_FROM,
91
- pass: process.env.EMAIL_PASSWORD,
92
- }, options.port || parseInt(process.env.EMAIL_PORT || "465"));
89
+ const { email: emailConfigs } = getArkosConfig();
90
+ if (!emailConfigs)
91
+ throw new AppError("You are trying to use emailService without setting arkosConfig.email configurations", 500, {
92
+ docs: "Read more about emailService at https://www.arkosjs.com/docs/core-concepts/sending-emails",
93
+ });
94
+ return new EmailService(options.host || emailConfigs.host, options.auth || {
95
+ user: emailConfigs.from,
96
+ pass: emailConfigs.password,
97
+ }, options.port || parseInt(String(emailConfigs.port) || "465"));
93
98
  }
94
99
  }
95
100
  const emailService = new EmailService();
@@ -1 +1 @@
1
- {"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../../../src/modules/email/email.service.ts"],"names":[],"mappings":"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","sourcesContent":["import nodemailer, { Transporter } from \"nodemailer\";\nimport { BaseService } from \"../base/base.service\";\nimport { convert } from \"html-to-text\";\n\n/**\n * Defines the options for sending an email.\n */\nexport type EmailOptions = {\n from?: string; // Sender's email address (optional).\n to: string | string[]; // Recipient's email address or an array of email addresses.\n subject: string; // Subject of the email.\n text?: string; // Plain text body of the email (optional).\n html: string; // HTML body of the email.\n};\n\n/**\n * Defines the authentication options for SMTP.\n */\nexport type SMTPAuthOptions = {\n user: string;\n pass: string;\n};\n\n/**\n * Defines the connection options for SMTP server.\n */\nexport type SMTPConnectionOptions = {\n host?: string;\n port?: number;\n secure?: boolean;\n auth?: SMTPAuthOptions;\n};\n\n/**\n * A service class to handle email-related tasks, including sending emails.\n */\nexport class EmailService extends BaseService {\n private transporter: Transporter;\n private defaultHost: string;\n private defaultPort: number;\n private defaultAuth: SMTPAuthOptions;\n\n /**\n * Creates an instance of the EmailService class.\n *\n * @param {string} [host] - The SMTP host (defaults to the environment variable `EMAIL_HOST`).\n * @param {SMTPAuthOptions} [auth] - The authentication object containing `user` and `pass` for the email account.\n * @param {number} [port] - The SMTP port (defaults to 465).\n */\n constructor(\n host: string = process.env.EMAIL_HOST!,\n auth: SMTPAuthOptions = {\n user: process.env.EMAIL_FROM!,\n pass: process.env.EMAIL_PASSWORD!,\n },\n port: number = parseInt(process.env.EMAIL_PORT || \"465\")\n ) {\n super(\"email\");\n this.defaultHost = host;\n this.defaultPort = port;\n this.defaultAuth = auth;\n\n // Initialize the default transporter\n this.transporter = nodemailer.createTransport({\n host: this.defaultHost,\n port: this.defaultPort,\n secure: true,\n auth: this.defaultAuth,\n });\n }\n\n /**\n * Verifies the connection to the email server.\n * @param {Transporter} [transporterToVerify] - Optional transporter to verify instead of the default one.\n * @returns {Promise<boolean>} A promise that resolves to true if connection is valid.\n */\n public async verifyConnection(\n transporterToVerify?: Transporter\n ): Promise<boolean> {\n try {\n const transporter = transporterToVerify || this.transporter;\n await transporter.verify();\n return true;\n } catch (error) {\n console.error(\"Email Server Connection Failed\", 500);\n return false;\n }\n }\n\n /**\n * Sends an email with the provided options.\n * Can use either the default configuration or custom connection options.\n *\n * @param {EmailOptions} options - The options for the email to be sent.\n * @param {SMTPConnectionOptions} [connectionOptions] - Optional custom connection settings.\n * @returns {Promise<{ success: boolean; messageId?: string; error?: any }>} A promise that resolves with the result of the email send attempt.\n * @throws {Error} Throws an error if the email sending fails.\n */\n public async send(\n options: EmailOptions,\n connectionOptions?: SMTPConnectionOptions\n ): Promise<{ success: boolean; messageId?: string; error?: any }> {\n try {\n let transporter = this.transporter;\n let fromAddress = options?.from || process.env.EMAIL_FROM;\n\n // If custom connection options are provided, create a temporary transporter\n if (connectionOptions) {\n const tempTransporter = nodemailer.createTransport({\n host: connectionOptions.host || this.defaultHost,\n port: connectionOptions.port || this.defaultPort,\n secure:\n connectionOptions.secure !== undefined\n ? connectionOptions.secure\n : true,\n auth: connectionOptions.auth || this.defaultAuth,\n });\n\n // Verify the temporary connection\n await this.verifyConnection(tempTransporter);\n\n // Use the temporary transporter and update from address if auth user is provided\n transporter = tempTransporter;\n if (connectionOptions.auth?.user) {\n fromAddress = options?.from || connectionOptions.auth.user;\n }\n } else {\n // Verify the default connection\n await this.verifyConnection();\n }\n\n // Send the email\n const info = await transporter.sendMail({\n ...options,\n from: fromAddress,\n text: options?.text || convert(options.html),\n });\n\n return { success: true, messageId: info.messageId };\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Updates the default configuration for the email service.\n *\n * @param {SMTPConnectionOptions} options - The new connection options.\n */\n public updateDefaultConfig(options: SMTPConnectionOptions): void {\n if (options.host) this.defaultHost = options.host;\n if (options.port) this.defaultPort = options.port;\n if (options.auth) this.defaultAuth = options.auth;\n\n // Update the default transporter\n this.transporter = nodemailer.createTransport({\n host: this.defaultHost,\n port: this.defaultPort,\n secure: options.secure !== undefined ? options.secure : true,\n auth: this.defaultAuth,\n });\n }\n\n /**\n * Creates a new instance of EmailService with custom configuration.\n *\n * @param {SMTPConnectionOptions} options - The connection options.\n * @returns {EmailService} A new email service instance.\n */\n public static create(options: SMTPConnectionOptions): EmailService {\n return new EmailService(\n options.host || process.env.EMAIL_HOST!,\n options.auth || {\n user: process.env.EMAIL_FROM!,\n pass: process.env.EMAIL_PASSWORD!,\n },\n options.port || parseInt(process.env.EMAIL_PORT || \"465\")\n );\n }\n}\n\n// Create default instance\nconst emailService = new EmailService();\nexport default emailService;\n"]}
1
+ {"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../../../src/modules/email/email.service.ts"],"names":[],"mappings":"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","sourcesContent":["import nodemailer, { Transporter } from \"nodemailer\";\nimport { BaseService } from \"../base/base.service\";\nimport { convert } from \"html-to-text\";\nimport { getArkosConfig } from \"../../server\";\nimport AppError from \"../error-handler/utils/app-error\";\n\n/**\n * Defines the options for sending an email.\n */\nexport type EmailOptions = {\n from?: string; // Sender's email address (optional).\n to: string | string[]; // Recipient's email address or an array of email addresses.\n subject: string; // Subject of the email.\n text?: string; // Plain text body of the email (optional).\n html: string; // HTML body of the email.\n};\n\n/**\n * Defines the authentication options for SMTP.\n */\nexport type SMTPAuthOptions = {\n user: string;\n pass: string;\n};\n\n/**\n * Defines the connection options for SMTP server.\n */\nexport type SMTPConnectionOptions = {\n host?: string;\n port?: number;\n secure?: boolean;\n auth?: SMTPAuthOptions;\n};\n\n/**\n * A service class to handle email-related tasks, including sending emails.\n */\nexport class EmailService {\n private transporter: Transporter;\n private defaultHost: string;\n private defaultPort: number;\n private defaultAuth: SMTPAuthOptions;\n\n /**\n * Creates an instance of the EmailService class.\n *\n * @param {string} [host] - The SMTP host (defaults to the environment variable `EMAIL_HOST`).\n * @param {SMTPAuthOptions} [auth] - The authentication object containing `user` and `pass` for the email account.\n * @param {number} [port] - The SMTP port (defaults to 465).\n *\n * See the api reference [www.arkosjs.com/docs/api-reference/the-email-service-class](https://www.arkosjs.com/docs/api-reference/the-email-service-class)\n */\n constructor(\n host: string = process.env.EMAIL_HOST!,\n auth: SMTPAuthOptions = {\n user: process.env.EMAIL_FROM!,\n pass: process.env.EMAIL_PASSWORD!,\n },\n port: number = parseInt(process.env.EMAIL_PORT || \"465\")\n ) {\n this.defaultHost = host;\n this.defaultPort = port;\n this.defaultAuth = auth;\n\n // Initialize the default transporter\n this.transporter = nodemailer.createTransport({\n host: this.defaultHost,\n port: this.defaultPort,\n secure: true,\n auth: this.defaultAuth,\n });\n }\n\n /**\n * Verifies the connection to the email server.\n * @param {Transporter} [transporterToVerify] - Optional transporter to verify instead of the default one.\n * @returns {Promise<boolean>} A promise that resolves to true if connection is valid.\n */\n public async verifyConnection(\n transporterToVerify?: Transporter\n ): Promise<boolean> {\n try {\n const transporter = transporterToVerify || this.transporter;\n await transporter.verify();\n return true;\n } catch (error) {\n console.error(\"Email Server Connection Failed\", 500);\n return false;\n }\n }\n\n /**\n * Sends an email with the provided options.\n * Can use either the default configuration or custom connection options.\n *\n * @param {EmailOptions} options - The options for the email to be sent.\n * @param {SMTPConnectionOptions} [connectionOptions] - Optional custom connection settings.\n * @returns {Promise<{ success: boolean; messageId?: string; error?: any }>} A promise that resolves with the result of the email send attempt.\n * @throws {Error} Throws an error if the email sending fails.\n */\n public async send(\n options: EmailOptions,\n connectionOptions?: SMTPConnectionOptions\n ): Promise<{ success: boolean; messageId?: string; error?: any }> {\n try {\n let transporter = this.transporter;\n let fromAddress = options?.from || process.env.EMAIL_FROM;\n\n // If custom connection options are provided, create a temporary transporter\n if (connectionOptions) {\n const tempTransporter = nodemailer.createTransport({\n host: connectionOptions.host || this.defaultHost,\n port: connectionOptions.port || this.defaultPort,\n secure:\n connectionOptions.secure !== undefined\n ? connectionOptions.secure\n : true,\n auth: connectionOptions.auth || this.defaultAuth,\n });\n\n // Verify the temporary connection\n await this.verifyConnection(tempTransporter);\n\n // Use the temporary transporter and update from address if auth user is provided\n transporter = tempTransporter;\n if (connectionOptions.auth?.user) {\n fromAddress = options?.from || connectionOptions.auth.user;\n }\n } else {\n // Verify the default connection\n await this.verifyConnection();\n }\n\n // Send the email\n const info = await transporter.sendMail({\n ...options,\n from: fromAddress,\n text: options?.text || convert(options.html),\n });\n\n return { success: true, messageId: info.messageId };\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Updates the default configuration for the email service.\n *\n * @param {SMTPConnectionOptions} options - The new connection options.\n */\n public updateDefaultConfig(options: SMTPConnectionOptions): void {\n if (options.host) this.defaultHost = options.host;\n if (options.port) this.defaultPort = options.port;\n if (options.auth) this.defaultAuth = options.auth;\n\n // Update the default transporter\n this.transporter = nodemailer.createTransport({\n host: this.defaultHost,\n port: this.defaultPort,\n secure: options.secure !== undefined ? options.secure : true,\n auth: this.defaultAuth,\n });\n }\n\n /**\n * Creates a new instance of EmailService with custom configuration.\n *\n * @param {SMTPConnectionOptions} options - The connection options.\n * @returns {EmailService} A new email service instance.\n */\n public static create(options: SMTPConnectionOptions): EmailService {\n const { email: emailConfigs } = getArkosConfig();\n\n if (!emailConfigs)\n throw new AppError(\n \"You are trying to use emailService without setting arkosConfig.email configurations\",\n 500,\n {\n docs: \"Read more about emailService at https://www.arkosjs.com/docs/core-concepts/sending-emails\",\n }\n );\n\n return new EmailService(\n options.host || emailConfigs.host,\n options.auth || {\n user: emailConfigs.from,\n pass: emailConfigs.password,\n },\n options.port || parseInt(String(emailConfigs.port) || \"465\")\n );\n }\n}\n\n// Create default instance\nconst emailService = new EmailService();\nexport default emailService;\n"]}
@@ -0,0 +1,220 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import AppError from "../error-handler/utils/app-error";
11
+ import { getFileUploaderServices, } from "./file-uploader.service";
12
+ import path from "path";
13
+ import fs from "fs";
14
+ import sharp from "sharp";
15
+ import catchAsync from "../error-handler/utils/catch-async";
16
+ import { promisify } from "util";
17
+ import { getArkosConfig } from "../../server";
18
+ const stat = promisify(fs.stat);
19
+ const unlink = promisify(fs.unlink);
20
+ const access = promisify(fs.access);
21
+ const mkdir = promisify(fs.mkdir);
22
+ export const uploadFile = catchAsync((req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
23
+ const { fileType } = req.params;
24
+ const { format, width, height, resizeTo } = req.query;
25
+ const { documentUploaderService, fileUploaderService, imageUploaderService, videoUploaderService, } = getFileUploaderServices();
26
+ const { fileUpload } = getArkosConfig();
27
+ const baseUploadDir = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseUploadDir) || "/uploads";
28
+ const uploadPath = path.resolve(process.cwd(), baseUploadDir, fileType);
29
+ try {
30
+ yield access(uploadPath);
31
+ }
32
+ catch (error) {
33
+ yield mkdir(uploadPath, { recursive: true });
34
+ }
35
+ let uploader;
36
+ switch (fileType) {
37
+ case "images":
38
+ uploader = imageUploaderService;
39
+ break;
40
+ case "videos":
41
+ uploader = videoUploaderService;
42
+ break;
43
+ case "documents":
44
+ uploader = documentUploaderService;
45
+ break;
46
+ case "files":
47
+ uploader = fileUploaderService;
48
+ break;
49
+ default:
50
+ return next(new AppError("Invalid file type", 400));
51
+ }
52
+ uploader.handleMultipleUpload()(req, res, (err) => __awaiter(void 0, void 0, void 0, function* () {
53
+ var _a;
54
+ if (err)
55
+ return next(err);
56
+ const protocol = ((_a = req.get("host")) === null || _a === void 0 ? void 0 : _a.includes("localhost"))
57
+ ? "http"
58
+ : "https";
59
+ const baseURL = `${protocol}://${req.get("host")}`;
60
+ const baseRoute = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/api/uploads";
61
+ const generateRelativePath = (filePath) => {
62
+ if (baseUploadDir.startsWith("..")) {
63
+ return path.join(fileType, path.basename(filePath));
64
+ }
65
+ else {
66
+ return filePath.replace(`${process.cwd()}${baseUploadDir}/`, "");
67
+ }
68
+ };
69
+ const processImage = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
70
+ const ext = path.extname(filePath).toLowerCase();
71
+ const originalFormat = ext.replace(".", "");
72
+ const outputFormat = format
73
+ ? format.toString().toLowerCase()
74
+ : originalFormat;
75
+ if (!/jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif/i.test(originalFormat)) {
76
+ const relativePath = generateRelativePath(filePath);
77
+ return `${baseURL}${baseRoute}/${relativePath}`;
78
+ }
79
+ const tempName = `${path.basename(filePath, ext)}_${Date.now()}${ext}`;
80
+ const tempPath = path.join(path.dirname(filePath), tempName);
81
+ try {
82
+ let transformer = sharp(filePath);
83
+ const metadata = yield transformer.metadata();
84
+ if (resizeTo && metadata.width && metadata.height) {
85
+ const targetSize = parseInt(resizeTo.toString());
86
+ const scaleFactor = targetSize / Math.min(metadata.width, metadata.height);
87
+ const newWidth = Math.round(metadata.width * scaleFactor);
88
+ const newHeight = Math.round(metadata.height * scaleFactor);
89
+ transformer = transformer.resize(newWidth, newHeight);
90
+ }
91
+ else if (width || height) {
92
+ transformer = transformer.resize(width ? parseInt(width) : null, height ? parseInt(height) : null, { fit: "inside" });
93
+ }
94
+ if (outputFormat === "webp") {
95
+ transformer = transformer.toFormat("webp");
96
+ }
97
+ else if (outputFormat === "jpeg" || outputFormat === "jpg") {
98
+ transformer = transformer.toFormat("jpeg");
99
+ }
100
+ yield transformer.toFile(tempPath);
101
+ yield fs.promises.rename(tempPath, filePath);
102
+ const relativePath = generateRelativePath(filePath);
103
+ return `${baseURL}${baseRoute}/${relativePath}`;
104
+ }
105
+ catch (error) {
106
+ try {
107
+ yield fs.promises.stat(tempPath);
108
+ yield fs.promises.unlink(tempPath);
109
+ }
110
+ catch (_a) {
111
+ }
112
+ next(error);
113
+ return null;
114
+ }
115
+ });
116
+ const processFile = (filePath) => __awaiter(void 0, void 0, void 0, function* () {
117
+ const relativePath = generateRelativePath(filePath);
118
+ return `${baseURL}${baseRoute}/${relativePath}`;
119
+ });
120
+ let data;
121
+ if (req.files && Array.isArray(req.files)) {
122
+ if (fileType === "images") {
123
+ data = yield Promise.all(req.files.map((file) => processImage(file.path)));
124
+ }
125
+ else {
126
+ data = yield Promise.all(req.files.map((file) => processFile(file.path)));
127
+ }
128
+ data = data.filter((url) => url !== null);
129
+ }
130
+ else if (req.file) {
131
+ if (fileType === "images") {
132
+ data = yield processImage(req.file.path);
133
+ }
134
+ else {
135
+ data = yield processFile(req.file.path);
136
+ }
137
+ }
138
+ else {
139
+ return next(new AppError("No file uploaded", 400));
140
+ }
141
+ res.status(200).json({
142
+ success: true,
143
+ data,
144
+ message: Array.isArray(data)
145
+ ? `${data.length} files uploaded successfully`
146
+ : "File uploaded successfully",
147
+ });
148
+ }));
149
+ }));
150
+ export const deleteFile = catchAsync((req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
151
+ const { fileType, fileName } = req.params;
152
+ const { documentUploaderService, fileUploaderService, imageUploaderService, videoUploaderService, } = getFileUploaderServices();
153
+ let uploader;
154
+ switch (fileType) {
155
+ case "images":
156
+ uploader = imageUploaderService;
157
+ break;
158
+ case "videos":
159
+ uploader = videoUploaderService;
160
+ break;
161
+ case "documents":
162
+ uploader = documentUploaderService;
163
+ break;
164
+ case "files":
165
+ uploader = fileUploaderService;
166
+ break;
167
+ default:
168
+ return next(new AppError("Invalid file type", 400));
169
+ }
170
+ try {
171
+ const fullUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
172
+ yield uploader.deleteFileByUrl(fullUrl);
173
+ res.status(200).json({
174
+ success: true,
175
+ message: "File deleted successfully",
176
+ });
177
+ }
178
+ catch (error) {
179
+ return next(new AppError("File not found", 404));
180
+ }
181
+ }));
182
+ export const streamFile = catchAsync((req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
183
+ const { fileName, fileType } = req.params;
184
+ const filePath = path.join(".", "uploads", fileType, fileName);
185
+ try {
186
+ yield access(filePath);
187
+ }
188
+ catch (_a) {
189
+ return next(new AppError("File not found", 404));
190
+ }
191
+ const fileStat = yield stat(filePath);
192
+ const fileSize = fileStat.size;
193
+ const range = req.headers.range;
194
+ if (range) {
195
+ const [partialStart, partialEnd] = range.replace(/bytes=/, "").split("-");
196
+ const start = parseInt(partialStart, 10) || 0;
197
+ const end = partialEnd ? parseInt(partialEnd, 10) : fileSize - 1;
198
+ if (start >= fileSize || end >= fileSize) {
199
+ res.status(416).json({ error: "Range Not Satisfiable" });
200
+ return;
201
+ }
202
+ res.writeHead(206, {
203
+ "Content-Range": `bytes ${start}-${end}/${fileSize}`,
204
+ "Accept-Ranges": "bytes",
205
+ "Content-Length": end - start + 1,
206
+ "Content-Type": "application/octet-stream",
207
+ "Content-Disposition": `inline; filename="${fileName}"`,
208
+ });
209
+ fs.createReadStream(filePath, { start, end }).pipe(res);
210
+ }
211
+ else {
212
+ res.writeHead(200, {
213
+ "Content-Length": fileSize,
214
+ "Content-Type": "application/octet-stream",
215
+ "Content-Disposition": `inline; filename="${fileName}"`,
216
+ });
217
+ fs.createReadStream(filePath).pipe(res);
218
+ }
219
+ }));
220
+ //# 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,44 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Router } from "express";
11
+ import { importPrismaModelModules } from "../../utils/helpers/models.helpers";
12
+ import authService from "../auth/auth.service";
13
+ import { deleteFile, uploadFile } from "./file-uploader.controller";
14
+ import path from "path";
15
+ import express from "express";
16
+ import deepmerge from "../../utils/helpers/deepmerge.helper";
17
+ const router = Router();
18
+ export function getFileUploaderRouter(_a) {
19
+ return __awaiter(this, arguments, void 0, function* ({ fileUpload }) {
20
+ const modelModules = yield importPrismaModelModules("file-upload");
21
+ let { middlewares = {}, authConfigs = {} } = {};
22
+ if (modelModules) {
23
+ ({ middlewares = {}, authConfigs = {} } = modelModules);
24
+ }
25
+ let basePathname = (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/uploads/";
26
+ if (!basePathname.startsWith("/"))
27
+ basePathname = "/" + basePathname;
28
+ if (!basePathname.endsWith("/"))
29
+ basePathname = basePathname + "/";
30
+ router.use((fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseRoute) || "/api/uploads", authService.handleAuthenticationControl(authConfigs, "view", "file-upload"), authService.handleActionAccessControl(authConfigs, "view", "file-upload"), express.static(path.resolve(process.cwd(), (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.baseUploadDir) || "uploads"), deepmerge({
31
+ maxAge: "1y",
32
+ etag: true,
33
+ lastModified: true,
34
+ dotfiles: "ignore",
35
+ fallthrough: true,
36
+ index: false,
37
+ cacheControl: true,
38
+ }, (fileUpload === null || fileUpload === void 0 ? void 0 : fileUpload.expressStaticOptions) || {})));
39
+ router.post(`${basePathname}:fileType`, authService.handleAuthenticationControl(authConfigs, "create", "file-upload"), authService.handleActionAccessControl(authConfigs, "create", "file-upload"), uploadFile);
40
+ router.delete(`${basePathname}:fileType/:fileName`, authService.handleAuthenticationControl(authConfigs, "delete", "file-upload"), authService.handleActionAccessControl(authConfigs, "create", "file-upload"), deleteFile);
41
+ return router;
42
+ });
43
+ }
44
+ //# 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":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEpE,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,SAAS,MAAM,sCAAsC,CAAC;AAE7D,MAAM,MAAM,GAAW,MAAM,EAAE,CAAC;AAEhC,MAAM,UAAgB,qBAAqB;yDAAC,EAAE,UAAU,EAAe;QACrE,MAAM,YAAY,GAAG,MAAM,wBAAwB,CAAC,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,WAAW,CAAC,2BAA2B,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EAC3E,WAAW,CAAC,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EACzE,OAAO,CAAC,MAAM,CACZ,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,aAAa,KAAI,SAAS,CAAC,EACnE,SAAS,CACP;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,WAAW,CAAC,2BAA2B,CACrC,WAAW,EACX,QAAQ,EACR,aAAa,CACd,EACD,WAAW,CAAC,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,EAC3E,UAAU,CACX,CAAC;QAEF,MAAM,CAAC,MAAM,CACX,GAAG,YAAY,qBAAqB,EACpC,WAAW,CAAC,2BAA2B,CACrC,WAAW,EACX,QAAQ,EACR,aAAa,CACd,EACD,WAAW,CAAC,yBAAyB,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,EAC3E,UAAU,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"]}