storemw-core-api 1.0.41 → 1.0.42

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.
@@ -13,6 +13,32 @@ const getRootName = (toSingular) => {
13
13
  let rootName = toSingular ? "file" : "files";
14
14
  return rootName;
15
15
  };
16
+ const getStorageProvider = () => {
17
+ const storageProviderName = configs_1.config.FILE_STORAGE_PROVIDER_NAME;
18
+ let storageProviderOptions = {};
19
+ if (storageProviderName === "local") {
20
+ storageProviderOptions = {
21
+ basePath: `${configs_1.config.FILE_STORAGE_LOCAL_BASE_PATH}`,
22
+ publicBaseUrl: `${configs_1.config.FILE_STORAGE_LOCAL_BASE_URL}`,
23
+ skipFoldernameByModuleRef: Boolean(configs_1.config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_MODULE_REF),
24
+ skipFoldernameByDate: Boolean(configs_1.config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_YEAR_MONTH)
25
+ };
26
+ }
27
+ if (storageProviderName === "gcloud") {
28
+ storageProviderOptions = {
29
+ bucketName: `${configs_1.config.FILE_STORAGE_GCLOUD_BUCKET_NAME}`,
30
+ basePath: `${configs_1.config.FILE_STORAGE_GCLOUD_BASE_PATH}`,
31
+ credentials: `${path_1.default.resolve(process.cwd(), `${configs_1.config.FILE_STORAGE_GCLOUD_CREDENTIAL_PATH}`)}`,
32
+ publicBaseUrl: `${configs_1.config.FILE_STORAGE_GCLOUD_BASE_URL}`,
33
+ skipFoldernameByModuleRef: Boolean(configs_1.config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_MODULE_REF),
34
+ skipFoldernameByDate: Boolean(configs_1.config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_YEAR_MONTH)
35
+ };
36
+ }
37
+ return {
38
+ storageProviderName,
39
+ storageProviderOptions
40
+ };
41
+ };
16
42
  /** file/:fileId : get file */
17
43
  const getFile = async (req, res, next) => {
18
44
  try {
@@ -53,26 +79,7 @@ const uploadFiles = async (req, res, next) => {
53
79
  buffer: file.buffer,
54
80
  })) : [],
55
81
  });
56
- const storageProviderName = configs_1.config.FILE_STORAGE_PROVIDER_NAME;
57
- let storageProviderOptions = {};
58
- if (storageProviderName === "local") {
59
- storageProviderOptions = {
60
- basePath: `${configs_1.config.FILE_STORAGE_LOCAL_BASE_PATH}`,
61
- publicBaseUrl: `${configs_1.config.FILE_STORAGE_LOCAL_BASE_URL}`,
62
- skipFoldernameByModuleRef: Boolean(configs_1.config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_MODULE_REF),
63
- skipFoldernameByDate: Boolean(configs_1.config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_YEAR_MONTH)
64
- };
65
- }
66
- if (storageProviderName === "gcloud") {
67
- storageProviderOptions = {
68
- bucketName: `${configs_1.config.FILE_STORAGE_GCLOUD_BUCKET_NAME}`,
69
- basePath: `${configs_1.config.FILE_STORAGE_GCLOUD_BASE_PATH}`,
70
- credentials: `${path_1.default.resolve(process.cwd(), `${configs_1.config.FILE_STORAGE_GCLOUD_CREDENTIAL_PATH}`)}`,
71
- publicBaseUrl: `${configs_1.config.FILE_STORAGE_GCLOUD_BASE_URL}`,
72
- skipFoldernameByModuleRef: Boolean(configs_1.config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_MODULE_REF),
73
- skipFoldernameByDate: Boolean(configs_1.config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_YEAR_MONTH)
74
- };
75
- }
82
+ const { storageProviderName, storageProviderOptions } = getStorageProvider();
76
83
  const imageCompressionOptions = configs_1.config.FILE_UPLOAD_IMAGE_MAX_WIDTH && configs_1.config.FILE_UPLOAD_IMAGE_QUALITY
77
84
  ? {
78
85
  maxWidth: Number(configs_1.config.FILE_UPLOAD_IMAGE_MAX_WIDTH),
@@ -192,8 +199,11 @@ const deleteFiles = async (req, res, next) => {
192
199
  const fileService = (0, services_1.FileService)({
193
200
  ...(0, utils_1.getDefaultServiceProps)(req),
194
201
  });
202
+ const { storageProviderName, storageProviderOptions } = getStorageProvider();
195
203
  const payload = {
196
- fileIds: request.payload.ids.map(i => BigInt(i))
204
+ fileIds: request.payload.ids.map(i => BigInt(i)),
205
+ storageProviderName,
206
+ storageProviderOptions
197
207
  };
198
208
  const data = await fileService.removeFiles(payload);
199
209
  return (0, utils_1.sendSuccess)(res, data, "Deleted", getRootName(false));
@@ -1 +1 @@
1
- {"version":3,"file":"fileController.js","sourceRoot":"","sources":["../../../src/controllers/file/fileController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request, Response, NextFunction } from \"express\";\n\nimport path from \"path\";\n\nimport { getDefaultServiceProps, sendSuccess, sendError, HTTP_STATUS } from \"@/utils\"\n\nimport { FileService, FileUploadProps, FileImageCompressionOptions } from \"@/services\"\nimport {\n schemaFileDeletePayload,\n schemaFileUploadPayload,\n} from \"@/schema/payload\";\n\nimport { QueryList } from \"@/schema/middleware/route\";\n\nimport { config } from \"@/configs\";\n\nconst getRootName = (toSingular: boolean) => {\n\n let rootName = toSingular ? \"file\" : \"files\";\n\n return rootName\n}\n\n/** file/:fileId : get file */\nexport const getFile = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n try {\n\n const { fileId } = req.params;\n // const requestQuery = req.query as unknown as QueryList;\n // const requestDocumentType = documentType as FileServiceProps[\"documentType\"];\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n const data = await fileService.getFile({ id: Number(fileId) })\n\n return sendSuccess(res, data, \"Retrieved successfully\", getRootName(true));\n\n } catch (error: any) {\n next(error)\n }\n}\n\n/** files : upload files */\nexport const uploadFiles = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n try {\n\n let reqBody = req.body\n let reqFiles = req.files\n\n const request = schemaFileUploadPayload.parse({\n field_ref: reqBody.field_ref,\n field_module: reqBody.field_module,\n description: reqBody.description,\n tagName: reqBody.tag_name,\n label: reqBody.label,\n refId: Number(reqBody.ref_id),\n refId2: Number(reqBody.ref_id_2),\n ...(reqBody?.ref_label ? { refLabel: reqBody.ref_label } : {}),\n ...(reqBody?.ref_label_2 ? { refLabel2: reqBody.ref_label_2 } : {}),\n ...(reqBody?.remark ? { remark: reqBody.remark } : {}),\n files: Array.isArray(reqFiles) ? reqFiles.map((file: any) => ({\n originalname: file.originalname,\n mimetype: file.mimetype,\n size: file.size,\n buffer: file.buffer,\n })) : [],\n });\n\n const storageProviderName = config.FILE_STORAGE_PROVIDER_NAME as FileUploadProps[\"storageProviderName\"]\n\n let storageProviderOptions = {}\n\n if (storageProviderName === \"local\") {\n storageProviderOptions = {\n basePath: `${config.FILE_STORAGE_LOCAL_BASE_PATH}`,\n publicBaseUrl: `${config.FILE_STORAGE_LOCAL_BASE_URL}`,\n skipFoldernameByModuleRef: Boolean(config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_MODULE_REF),\n skipFoldernameByDate: Boolean(config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_YEAR_MONTH)\n }\n }\n\n if (storageProviderName === \"gcloud\") {\n storageProviderOptions = {\n bucketName: `${config.FILE_STORAGE_GCLOUD_BUCKET_NAME}`,\n basePath: `${config.FILE_STORAGE_GCLOUD_BASE_PATH}`,\n credentials: `${path.resolve(process.cwd(), `${config.FILE_STORAGE_GCLOUD_CREDENTIAL_PATH}`)}`,\n publicBaseUrl: `${config.FILE_STORAGE_GCLOUD_BASE_URL}`,\n skipFoldernameByModuleRef: Boolean(config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_MODULE_REF),\n skipFoldernameByDate: Boolean(config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_YEAR_MONTH)\n }\n }\n\n const imageCompressionOptions: FileImageCompressionOptions | undefined\n = config.FILE_UPLOAD_IMAGE_MAX_WIDTH && config.FILE_UPLOAD_IMAGE_QUALITY\n ? {\n maxWidth: Number(config.FILE_UPLOAD_IMAGE_MAX_WIDTH),\n quality: Number(config.FILE_UPLOAD_IMAGE_QUALITY),\n }\n : undefined;\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n });\n\n const payload: FileUploadProps = {\n field_ref: reqBody.field_ref,\n field_module: reqBody.field_module,\n description: request.description,\n label: request.label,\n tagName: request.tagName ?? \"\",\n refId: request.refId ?? 0,\n refId2: request?.refId2 ?? 0,\n refLabel: request?.refLabel ?? \"\",\n refLabel2: request?.refLabel2 ?? \"\",\n remark: request?.remark ?? \"\",\n // foldernameDate: \"2025-01-01\", // empty to use current datetime\n storageProviderName,\n storageProviderOptions,\n ...(imageCompressionOptions ? { imageCompressionOptions } : {}),\n files: request.files.map(file => ({\n buffer: file.buffer,\n originalName: file.originalname,\n mimeType: file.mimetype,\n sizeBytes: file.size,\n })),\n };\n\n const response = await fileService.uploadFiles(payload);\n\n return sendSuccess(res, response, \"Files uploaded successfully\");\n\n } catch (error) {\n next(error);\n }\n};\n\n/** file/:fileId : update file */\nexport const updateFile = async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n\n const { fileId } = req.params;\n // const requestDocumentType = req.body.scope.target as FileServiceProps[\"documentType\"]\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n let response: any = {}\n\n let reqScope = req.body.scope\n let reqPayload = req.body.payload\n\n\n // const { schemaUpdate, key } = documentSalesMap[requestDocumentType as keyof typeof documentSalesMap];\n\n // const request = schemaUpdate.parse({\n // scope: { target: reqScope.target, action: reqScope.action },\n // payload: {\n // ...buildDocumentPayloadFromRequest(reqPayload),\n // profile: buildDocumentProfileFromRequest(reqPayload.profile),\n // shipping: buildDocumentProfileOtherFromRequest(reqPayload.shipping),\n // billing: buildDocumentProfileOtherFromRequest(reqPayload.billing),\n // ...(reqPayload?.items ? { items: buildDocumentItemsFromRequest(reqPayload.items) } : {}),\n // ...(reqPayload?.totals ? { totals: buildDocumentTotalsFromRequest(reqPayload.totals) } : {}),\n // },\n // });\n\n // const payload: DocumentUpdateProps = {\n // documentId: Number(documentId),\n // documentType: requestDocumentType,\n // data: {\n // ...buildDocumentPayloadToService(request.payload),\n // [key]: {\n // profile: buildDocumentProfileToService(request.payload.profile),\n // shipping: buildDocumentProfileOtherToService(request.payload.shipping),\n // billing: buildDocumentProfileOtherToService(request.payload.billing),\n // ...(request.payload?.items ? { items: buildDocumentItemsToService(request.payload.items) } : {}),\n // ...(request.payload?.totals ? { totals: buildDocumentTotalsToService(request.payload.totals) } : {}),\n // },\n // } as any,\n // };\n\n // const result = await fileService.updateFile(payload);\n\n // response = {\n // [getRootName(true)]: result,\n // };\n\n sendSuccess(res, response, `File updated successfully`)\n\n } catch (error: any) {\n next(error)\n }\n};\n\n/** files : list files */\nexport const listFiles = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n try {\n\n const requestQuery = req.query as unknown as QueryList;\n // const requestDocumentType = req.params.documentType as FileServiceProps[\"documentType\"];\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n const { data, total } = await fileService.listFiles({\n ...requestQuery,\n });\n\n let response = {\n [`${getRootName(false)}`]: data,\n total,\n }\n\n return sendSuccess(res, response, \"Retrieved successfully\");\n\n } catch (error: any) {\n next(error)\n }\n};\n\n/** files/delete : delete files */\nexport const deleteFiles = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n try {\n\n // const requestDocumentType = req.body.scope.target as FileServiceProps[\"documentType\"]\n // const requestQuery = req.query as unknown as QueryList;\n // const requestFileId = Number(req.params.fileId)\n\n const request = schemaFileDeletePayload.parse(req.body)\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n const payload = {\n fileIds: request.payload.ids.map(i => BigInt(i))\n }\n\n const data = await fileService.removeFiles(payload);\n\n return sendSuccess(res, data, \"Deleted\", getRootName(false));\n\n } catch (error: any) {\n next(error)\n }\n};\n\n/** file/data_types : get file data types */\n// export const getFileDataTypes = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n// try {\n\n// const requestQuery = req.query as unknown as QueryList;\n// // const requestDocumentType = req.params.documentType as FileServiceProps[\"documentType\"];\n\n// const fileService = FileService({\n// ...getDefaultServiceProps(req),\n// })\n\n// const data = fileService.getFileDataTypes();\n\n// let response = {\n// data_types: data\n// }\n\n// return sendSuccess(res, response, \"Retrieved successfully\");\n\n// } catch (error: any) {\n// next(error)\n// }\n// };\n"]}
1
+ {"version":3,"file":"fileController.js","sourceRoot":"","sources":["../../../src/controllers/file/fileController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request, Response, NextFunction } from \"express\";\n\nimport path from \"path\";\n\nimport { getDefaultServiceProps, sendSuccess, sendError, HTTP_STATUS } from \"@/utils\"\n\nimport { FileService, FileUploadProps, FileImageCompressionOptions } from \"@/services\"\nimport {\n schemaFileDeletePayload,\n schemaFileUploadPayload,\n} from \"@/schema/payload\";\n\nimport { QueryList } from \"@/schema/middleware/route\";\n\nimport { config } from \"@/configs\";\n\nconst getRootName = (toSingular: boolean) => {\n\n let rootName = toSingular ? \"file\" : \"files\";\n\n return rootName\n}\n\nconst getStorageProvider = () => {\n\n const storageProviderName = config.FILE_STORAGE_PROVIDER_NAME as FileUploadProps[\"storageProviderName\"]\n\n let storageProviderOptions = {}\n\n if (storageProviderName === \"local\") {\n storageProviderOptions = {\n basePath: `${config.FILE_STORAGE_LOCAL_BASE_PATH}`,\n publicBaseUrl: `${config.FILE_STORAGE_LOCAL_BASE_URL}`,\n skipFoldernameByModuleRef: Boolean(config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_MODULE_REF),\n skipFoldernameByDate: Boolean(config.FILE_STORAGE_LOCAL_SKIP_FOLDERNAME_YEAR_MONTH)\n }\n }\n\n if (storageProviderName === \"gcloud\") {\n storageProviderOptions = {\n bucketName: `${config.FILE_STORAGE_GCLOUD_BUCKET_NAME}`,\n basePath: `${config.FILE_STORAGE_GCLOUD_BASE_PATH}`,\n credentials: `${path.resolve(process.cwd(), `${config.FILE_STORAGE_GCLOUD_CREDENTIAL_PATH}`)}`,\n publicBaseUrl: `${config.FILE_STORAGE_GCLOUD_BASE_URL}`,\n skipFoldernameByModuleRef: Boolean(config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_MODULE_REF),\n skipFoldernameByDate: Boolean(config.FILE_STORAGE_GCLOUD_SKIP_FOLDERNAME_YEAR_MONTH)\n }\n }\n\n return {\n storageProviderName,\n storageProviderOptions\n }\n}\n\n/** file/:fileId : get file */\nexport const getFile = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n try {\n\n const { fileId } = req.params;\n // const requestQuery = req.query as unknown as QueryList;\n // const requestDocumentType = documentType as FileServiceProps[\"documentType\"];\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n const data = await fileService.getFile({ id: Number(fileId) })\n\n return sendSuccess(res, data, \"Retrieved successfully\", getRootName(true));\n\n } catch (error: any) {\n next(error)\n }\n}\n\n/** files : upload files */\nexport const uploadFiles = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n try {\n\n let reqBody = req.body\n let reqFiles = req.files\n\n const request = schemaFileUploadPayload.parse({\n field_ref: reqBody.field_ref,\n field_module: reqBody.field_module,\n description: reqBody.description,\n tagName: reqBody.tag_name,\n label: reqBody.label,\n refId: Number(reqBody.ref_id),\n refId2: Number(reqBody.ref_id_2),\n ...(reqBody?.ref_label ? { refLabel: reqBody.ref_label } : {}),\n ...(reqBody?.ref_label_2 ? { refLabel2: reqBody.ref_label_2 } : {}),\n ...(reqBody?.remark ? { remark: reqBody.remark } : {}),\n files: Array.isArray(reqFiles) ? reqFiles.map((file: any) => ({\n originalname: file.originalname,\n mimetype: file.mimetype,\n size: file.size,\n buffer: file.buffer,\n })) : [],\n });\n\n const {\n storageProviderName,\n storageProviderOptions\n } = getStorageProvider()\n\n const imageCompressionOptions: FileImageCompressionOptions | undefined\n = config.FILE_UPLOAD_IMAGE_MAX_WIDTH && config.FILE_UPLOAD_IMAGE_QUALITY\n ? {\n maxWidth: Number(config.FILE_UPLOAD_IMAGE_MAX_WIDTH),\n quality: Number(config.FILE_UPLOAD_IMAGE_QUALITY),\n }\n : undefined;\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n });\n\n const payload: FileUploadProps = {\n field_ref: reqBody.field_ref,\n field_module: reqBody.field_module,\n description: request.description,\n label: request.label,\n tagName: request.tagName ?? \"\",\n refId: request.refId ?? 0,\n refId2: request?.refId2 ?? 0,\n refLabel: request?.refLabel ?? \"\",\n refLabel2: request?.refLabel2 ?? \"\",\n remark: request?.remark ?? \"\",\n // foldernameDate: \"2025-01-01\", // empty to use current datetime\n storageProviderName,\n storageProviderOptions,\n ...(imageCompressionOptions ? { imageCompressionOptions } : {}),\n files: request.files.map(file => ({\n buffer: file.buffer,\n originalName: file.originalname,\n mimeType: file.mimetype,\n sizeBytes: file.size,\n })),\n };\n\n const response = await fileService.uploadFiles(payload);\n\n return sendSuccess(res, response, \"Files uploaded successfully\");\n\n } catch (error) {\n next(error);\n }\n};\n\n/** file/:fileId : update file */\nexport const updateFile = async (req: Request, res: Response, next: NextFunction): Promise<void> => {\n try {\n\n const { fileId } = req.params;\n // const requestDocumentType = req.body.scope.target as FileServiceProps[\"documentType\"]\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n let response: any = {}\n\n let reqScope = req.body.scope\n let reqPayload = req.body.payload\n\n\n // const { schemaUpdate, key } = documentSalesMap[requestDocumentType as keyof typeof documentSalesMap];\n\n // const request = schemaUpdate.parse({\n // scope: { target: reqScope.target, action: reqScope.action },\n // payload: {\n // ...buildDocumentPayloadFromRequest(reqPayload),\n // profile: buildDocumentProfileFromRequest(reqPayload.profile),\n // shipping: buildDocumentProfileOtherFromRequest(reqPayload.shipping),\n // billing: buildDocumentProfileOtherFromRequest(reqPayload.billing),\n // ...(reqPayload?.items ? { items: buildDocumentItemsFromRequest(reqPayload.items) } : {}),\n // ...(reqPayload?.totals ? { totals: buildDocumentTotalsFromRequest(reqPayload.totals) } : {}),\n // },\n // });\n\n // const payload: DocumentUpdateProps = {\n // documentId: Number(documentId),\n // documentType: requestDocumentType,\n // data: {\n // ...buildDocumentPayloadToService(request.payload),\n // [key]: {\n // profile: buildDocumentProfileToService(request.payload.profile),\n // shipping: buildDocumentProfileOtherToService(request.payload.shipping),\n // billing: buildDocumentProfileOtherToService(request.payload.billing),\n // ...(request.payload?.items ? { items: buildDocumentItemsToService(request.payload.items) } : {}),\n // ...(request.payload?.totals ? { totals: buildDocumentTotalsToService(request.payload.totals) } : {}),\n // },\n // } as any,\n // };\n\n // const result = await fileService.updateFile(payload);\n\n // response = {\n // [getRootName(true)]: result,\n // };\n\n sendSuccess(res, response, `File updated successfully`)\n\n } catch (error: any) {\n next(error)\n }\n};\n\n/** files : list files */\nexport const listFiles = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n try {\n\n const requestQuery = req.query as unknown as QueryList;\n // const requestDocumentType = req.params.documentType as FileServiceProps[\"documentType\"];\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n const { data, total } = await fileService.listFiles({\n ...requestQuery,\n });\n\n let response = {\n [`${getRootName(false)}`]: data,\n total,\n }\n\n return sendSuccess(res, response, \"Retrieved successfully\");\n\n } catch (error: any) {\n next(error)\n }\n};\n\n/** files/delete : delete files */\nexport const deleteFiles = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n try {\n\n // const requestDocumentType = req.body.scope.target as FileServiceProps[\"documentType\"]\n // const requestQuery = req.query as unknown as QueryList;\n // const requestFileId = Number(req.params.fileId)\n\n const request = schemaFileDeletePayload.parse(req.body)\n\n const fileService = FileService({\n ...getDefaultServiceProps(req),\n })\n\n const {\n storageProviderName,\n storageProviderOptions\n } = getStorageProvider()\n\n const payload = {\n fileIds: request.payload.ids.map(i => BigInt(i)),\n storageProviderName,\n storageProviderOptions\n }\n\n const data = await fileService.removeFiles(payload);\n\n return sendSuccess(res, data, \"Deleted\", getRootName(false));\n\n } catch (error: any) {\n next(error)\n }\n};\n\n/** file/data_types : get file data types */\n// export const getFileDataTypes = async (req: Request, res: Response, next: NextFunction): Promise<any> => {\n\n// try {\n\n// const requestQuery = req.query as unknown as QueryList;\n// // const requestDocumentType = req.params.documentType as FileServiceProps[\"documentType\"];\n\n// const fileService = FileService({\n// ...getDefaultServiceProps(req),\n// })\n\n// const data = fileService.getFileDataTypes();\n\n// let response = {\n// data_types: data\n// }\n\n// return sendSuccess(res, response, \"Retrieved successfully\");\n\n// } catch (error: any) {\n// next(error)\n// }\n// };\n"]}
@@ -15,4 +15,5 @@ export declare const FileGoogleCloudStorageProvider: (options: FileGoogleCloudPr
15
15
  foldernameDate?: string;
16
16
  fileName: string;
17
17
  }) => Promise<FileStorageProviderResult>;
18
+ removeFile: (assetUrl: string, credentials: any) => Promise<[import("teeny-request").Response<any>]>;
18
19
  };
@@ -8,10 +8,29 @@ const storage_1 = require("@google-cloud/storage");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const crypto_1 = require("crypto");
10
10
  const utils_1 = require("../../utils");
11
+ function extractBucketName(url) {
12
+ try {
13
+ const match = url.match(/^https?:\/\/storage\.googleapis\.com\/([^/]+)/);
14
+ return match ? match[1] : null;
15
+ }
16
+ catch (err) {
17
+ console.error("Invalid URL:", err);
18
+ return null;
19
+ }
20
+ }
21
+ function extractFilePathFromUrl(url, bucketName) {
22
+ // Remove everything up to and including the bucket name
23
+ const prefix = `https://storage.googleapis.com/${bucketName}/`;
24
+ return url.startsWith(prefix) ? url.slice(prefix.length) : null;
25
+ }
11
26
  const FileGoogleCloudStorageProvider = (options) => {
12
27
  const { bucketName, basePath = "", skipFoldernameByModuleRef = false, skipFoldernameByDate = false, publicBaseUrl, credentials, } = options;
13
- const storage = new storage_1.Storage(credentials ? { keyFilename: credentials } : undefined);
14
- const bucket = storage.bucket(bucketName);
28
+ let storage;
29
+ let bucket;
30
+ if (bucketName) {
31
+ storage = new storage_1.Storage(credentials ? { keyFilename: credentials } : undefined);
32
+ bucket = storage.bucket(bucketName);
33
+ }
15
34
  /**
16
35
  * Upload file to Google Cloud Storage.
17
36
  * Files will be stored under: basePath/ref/module/YYYY/MM/DD/
@@ -68,7 +87,21 @@ const FileGoogleCloudStorageProvider = (options) => {
68
87
  } : {})
69
88
  };
70
89
  };
71
- return { uploadFile };
90
+ const removeFile = async (assetUrl, credentials) => {
91
+ const bucketName = extractBucketName(assetUrl);
92
+ if (!bucketName) {
93
+ throw new Error(`Could not extract bucket name from: ${assetUrl}`);
94
+ }
95
+ const storage = new storage_1.Storage(credentials ? { keyFilename: credentials } : undefined);
96
+ const filePath = extractFilePathFromUrl(assetUrl, bucketName);
97
+ if (!filePath) {
98
+ throw new Error(`Could not extract file path from: ${assetUrl}`);
99
+ }
100
+ const bucket = storage.bucket(bucketName);
101
+ // console.log(`Deleted from GCloud: gs://${bucketName}/${filePath}`);
102
+ return await bucket.file(filePath).delete();
103
+ };
104
+ return { uploadFile, removeFile };
72
105
  };
73
106
  exports.FileGoogleCloudStorageProvider = FileGoogleCloudStorageProvider;
74
107
  //# sourceMappingURL=FileGoogleCloudStorageProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileGoogleCloudStorageProvider.js","sourceRoot":"","sources":["../../../src/services/file/FileGoogleCloudStorageProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { Storage } from \"@google-cloud/storage\";\nimport path from \"path\";\nimport { randomUUID } from \"crypto\";\n\nimport { dayjs } from \"@/utils\";\n\nimport { FileModuleRef } from \"./FileService\";\n\nimport { FileStorageProviderResult } from \"./FileStorageProviderRegistry\"\n\nexport interface FileGoogleCloudProviderOptions {\n bucketName: string;\n basePath?: string; // e.g. \"uploads\"\n skipFoldernameByModuleRef?: boolean; // skip the folder [ref]/[module]\n skipFoldernameByDate?: boolean; // skip the yyyy/mm/dd folder structure\n publicBaseUrl?: string; // e.g. \"[https://storage.googleapis.com/](https://storage.googleapis.com/)<bucket>\"\n credentials?: string; // path to service account key JSON\n}\n\nexport const FileGoogleCloudStorageProvider = (options: FileGoogleCloudProviderOptions) => {\n\n const {\n bucketName,\n basePath = \"\",\n skipFoldernameByModuleRef = false,\n skipFoldernameByDate = false,\n publicBaseUrl,\n credentials,\n } = options;\n\n const storage = new Storage(credentials ? { keyFilename: credentials } : undefined);\n const bucket = storage.bucket(bucketName);\n\n /**\n * Upload file to Google Cloud Storage.\n * Files will be stored under: basePath/ref/module/YYYY/MM/DD/\n */\n const uploadFile = async <\n T extends FileModuleRef\n >({\n field_ref,\n field_module,\n buffer,\n mimeType,\n foldernameDate,\n fileName,\n }: T & {\n buffer: Buffer;\n mimeType: string;\n foldernameDate?: string; // organize the foldername y/m/d using this date\n fileName: string;\n }): Promise<FileStorageProviderResult> => {\n\n const now = dayjs(foldernameDate).isValid() ? dayjs(foldernameDate) : dayjs();\n const year = now.format(\"YYYY\");\n const month = now.format(\"MM\");\n const day = now.format(\"DD\");\n\n // let finalPublicBaseUrl = `https://storage.googleapis.com/${bucketName}`\n let finalPublicBaseUrl = `${publicBaseUrl}`\n let dirParts = []\n\n if (skipFoldernameByModuleRef === false) {\n dirParts.push(field_ref, field_module)\n }\n\n if (skipFoldernameByDate === false) {\n dirParts.push(year, month, day)\n }\n\n let finalBasePath = path.join(basePath, ...dirParts)\n\n // basePath is empty & dirParts are nothing\n if (!basePath && dirParts.length <= 0) {\n finalBasePath = ``\n }\n\n finalPublicBaseUrl = [finalPublicBaseUrl, basePath, ...dirParts].filter(Boolean).join('/');\n\n const ext = path.extname(fileName);\n const uniqueName = `${randomUUID()}${ext}`; // `${base}-${randomUUID()}${ext}`;\n let objectPath = finalBasePath ? `${finalBasePath}/${uniqueName}` : `${uniqueName}`\n\n const file = bucket.file(objectPath);\n\n await file.save(buffer, {\n resumable: false,\n metadata: {\n contentType: mimeType || \"application/octet-stream\",\n },\n });\n\n try {\n await file.makePublic();\n } catch (err) {\n console.warn(\"⚠️ Failed to make file public:\", err);\n }\n\n const assetPath = objectPath;\n const assetUrl = `${finalPublicBaseUrl}/${uniqueName}`;\n\n return {\n assetPath,\n assetUrl,\n filename: uniqueName,\n basePath: finalBasePath,\n ...(skipFoldernameByDate === false ? {\n folderName: {\n day: Number(day),\n month: Number(month),\n year: Number(year)\n }\n } : {})\n };\n };\n\n return { uploadFile };\n\n};\n"]}
1
+ {"version":3,"file":"FileGoogleCloudStorageProvider.js","sourceRoot":"","sources":["../../../src/services/file/FileGoogleCloudStorageProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { Storage } from \"@google-cloud/storage\";\nimport path from \"path\";\nimport { randomUUID } from \"crypto\";\n\nimport { dayjs } from \"@/utils\";\n\nimport { FileModuleRef } from \"./FileService\";\n\nimport { FileStorageProviderResult } from \"./FileStorageProviderRegistry\"\n\nexport interface FileGoogleCloudProviderOptions {\n bucketName: string;\n basePath?: string; // e.g. \"uploads\"\n skipFoldernameByModuleRef?: boolean; // skip the folder [ref]/[module]\n skipFoldernameByDate?: boolean; // skip the yyyy/mm/dd folder structure\n publicBaseUrl?: string; // e.g. \"[https://storage.googleapis.com/](https://storage.googleapis.com/)<bucket>\"\n credentials?: string; // path to service account key JSON\n}\n\nfunction extractBucketName(url: string) {\n try {\n const match = url.match(/^https?:\\/\\/storage\\.googleapis\\.com\\/([^/]+)/);\n return match ? match[1] : null;\n } catch (err) {\n console.error(\"Invalid URL:\", err);\n return null;\n }\n}\n\nfunction extractFilePathFromUrl(url: string, bucketName: string): string | null {\n // Remove everything up to and including the bucket name\n const prefix = `https://storage.googleapis.com/${bucketName}/`;\n return url.startsWith(prefix) ? url.slice(prefix.length) : null;\n}\n\nexport const FileGoogleCloudStorageProvider = (options: FileGoogleCloudProviderOptions) => {\n\n const {\n bucketName,\n basePath = \"\",\n skipFoldernameByModuleRef = false,\n skipFoldernameByDate = false,\n publicBaseUrl,\n credentials,\n } = options;\n\n let storage: any\n let bucket: any\n\n if (bucketName) {\n storage = new Storage(credentials ? { keyFilename: credentials } : undefined);\n bucket = storage.bucket(bucketName);\n }\n\n /**\n * Upload file to Google Cloud Storage.\n * Files will be stored under: basePath/ref/module/YYYY/MM/DD/\n */\n const uploadFile = async <\n T extends FileModuleRef\n >({\n field_ref,\n field_module,\n buffer,\n mimeType,\n foldernameDate,\n fileName,\n }: T & {\n buffer: Buffer;\n mimeType: string;\n foldernameDate?: string; // organize the foldername y/m/d using this date\n fileName: string;\n }): Promise<FileStorageProviderResult> => {\n\n const now = dayjs(foldernameDate).isValid() ? dayjs(foldernameDate) : dayjs();\n const year = now.format(\"YYYY\");\n const month = now.format(\"MM\");\n const day = now.format(\"DD\");\n\n // let finalPublicBaseUrl = `https://storage.googleapis.com/${bucketName}`\n let finalPublicBaseUrl = `${publicBaseUrl}`\n let dirParts = []\n\n if (skipFoldernameByModuleRef === false) {\n dirParts.push(field_ref, field_module)\n }\n\n if (skipFoldernameByDate === false) {\n dirParts.push(year, month, day)\n }\n\n let finalBasePath = path.join(basePath, ...dirParts)\n\n // basePath is empty & dirParts are nothing\n if (!basePath && dirParts.length <= 0) {\n finalBasePath = ``\n }\n\n finalPublicBaseUrl = [finalPublicBaseUrl, basePath, ...dirParts].filter(Boolean).join('/');\n\n const ext = path.extname(fileName);\n const uniqueName = `${randomUUID()}${ext}`; // `${base}-${randomUUID()}${ext}`;\n let objectPath = finalBasePath ? `${finalBasePath}/${uniqueName}` : `${uniqueName}`\n\n const file = bucket.file(objectPath);\n\n await file.save(buffer, {\n resumable: false,\n metadata: {\n contentType: mimeType || \"application/octet-stream\",\n },\n });\n\n try {\n await file.makePublic();\n } catch (err) {\n console.warn(\"⚠️ Failed to make file public:\", err);\n }\n\n const assetPath = objectPath;\n const assetUrl = `${finalPublicBaseUrl}/${uniqueName}`;\n\n return {\n assetPath,\n assetUrl,\n filename: uniqueName,\n basePath: finalBasePath,\n ...(skipFoldernameByDate === false ? {\n folderName: {\n day: Number(day),\n month: Number(month),\n year: Number(year)\n }\n } : {})\n };\n };\n\n const removeFile = async (assetUrl: string, credentials: any) => {\n\n const bucketName = extractBucketName(assetUrl);\n\n if (!bucketName) {\n throw new Error(`Could not extract bucket name from: ${assetUrl}`)\n }\n\n const storage = new Storage(credentials ? { keyFilename: credentials } : undefined);\n\n const filePath = extractFilePathFromUrl(assetUrl, bucketName);\n\n if (!filePath) {\n throw new Error(`Could not extract file path from: ${assetUrl}`)\n }\n\n const bucket = storage.bucket(bucketName);\n\n // console.log(`Deleted from GCloud: gs://${bucketName}/${filePath}`);\n\n return await bucket.file(filePath).delete();\n\n }\n\n return { uploadFile, removeFile };\n\n};\n"]}
@@ -13,4 +13,5 @@ export declare const FileLocalStorageProvider: (options: FileLocalProviderOption
13
13
  foldernameDate?: string;
14
14
  fileName: string;
15
15
  }) => Promise<FileStorageProviderResult>;
16
+ removeFile: (assetPath: string) => Promise<void>;
16
17
  };
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.FileLocalStorageProvider = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
+ const promises_1 = __importDefault(require("fs/promises"));
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const utils_1 = require("../../utils");
10
11
  const crypto_1 = require("crypto");
@@ -55,7 +56,19 @@ const FileLocalStorageProvider = (options) => {
55
56
  } : {})
56
57
  };
57
58
  };
58
- return { uploadFile };
59
+ const removeFile = async (assetPath) => {
60
+ if (assetPath) {
61
+ try {
62
+ const filePath = path_1.default.resolve(process.cwd(), assetPath);
63
+ await promises_1.default.unlink(filePath);
64
+ }
65
+ catch (err) {
66
+ // Log error but continue deleting others
67
+ console.error(`Failed to delete file ${assetPath}:`, err);
68
+ }
69
+ }
70
+ };
71
+ return { uploadFile, removeFile };
59
72
  };
60
73
  exports.FileLocalStorageProvider = FileLocalStorageProvider;
61
74
  //# sourceMappingURL=FileLocalStorageProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileLocalStorageProvider.js","sourceRoot":"","sources":["../../../src/services/file/FileLocalStorageProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport { dayjs } from \"@/utils\";\n\nimport { randomUUID } from \"crypto\";\n\nimport { FileModuleRef } from \"./FileService\";\n\nimport { FileStorageProviderResult } from \"./FileStorageProviderRegistry\"\n\nexport interface FileLocalProviderOptions {\n basePath?: string; // e.g. \"uploads\"\n skipFoldernameByModuleRef?: boolean; // skip the folder [ref]/[module]\n skipFoldernameByDate?: boolean; // skip the yyyy/mm/dd folder structure\n publicBaseUrl?: string; // e.g. \"/uploads\" or \"[http://localhost:3000/uploads](http://localhost:3000/uploads)\"\n}\n\nexport const FileLocalStorageProvider = (options: FileLocalProviderOptions) => {\n\n const {\n basePath = options?.basePath ?? path.join(process.cwd(), \"uploads\"),\n skipFoldernameByModuleRef = false,\n skipFoldernameByDate = false,\n publicBaseUrl = options?.publicBaseUrl ?? `/uploads`,\n } = options;\n\n const ensureDir = (dir: string) => {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n };\n\n /**\n * Upload file to local storage.\n * Files will be stored under: basePath/ref/module/YYYY/MM/DD/\n */\n const uploadFile = async <\n T extends FileModuleRef\n >({\n field_ref,\n field_module,\n buffer,\n mimeType,\n foldernameDate,\n fileName,\n }: T & {\n buffer: Buffer;\n mimeType: string;\n foldernameDate?: string; // organize the foldername y/m/d using this date\n fileName: string;\n }): Promise<FileStorageProviderResult> => {\n\n\n const now = dayjs(foldernameDate).isValid() ? dayjs(foldernameDate) : dayjs();\n const year = now.format(\"YYYY\");\n const month = now.format(\"MM\");\n const day = now.format(\"DD\");\n\n let finalPublicBaseUrl = `${publicBaseUrl}`\n let dirParts = []\n\n if (skipFoldernameByModuleRef === false) {\n dirParts.push(field_ref, field_module)\n }\n\n if (skipFoldernameByDate === false) {\n dirParts.push(year, month, day)\n }\n\n const finalBasePath = path.join(basePath, ...dirParts)\n const dir = finalBasePath\n finalPublicBaseUrl = [finalPublicBaseUrl, ...dirParts].filter(Boolean).join('/');\n\n ensureDir(dir);\n\n const ext = path.extname(fileName);\n const uniqueName = `${randomUUID()}${ext}`; // `${base}-${randomUUID()}${ext}`;\n const filePath = path.join(dir, uniqueName);\n\n await fs.promises.writeFile(filePath, buffer);\n\n const assetPath = path.relative(process.cwd(), filePath);\n const assetUrl = `${finalPublicBaseUrl}/${uniqueName}`;\n\n return {\n assetPath,\n assetUrl,\n filename: uniqueName,\n basePath: finalBasePath,\n ...(skipFoldernameByDate === false ? {\n folderName: {\n day: Number(day),\n month: Number(month),\n year: Number(year)\n }\n } : {})\n };\n };\n\n return { uploadFile };\n\n};\n"]}
1
+ {"version":3,"file":"FileLocalStorageProvider.js","sourceRoot":"","sources":["../../../src/services/file/FileLocalStorageProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport fsPromises from \"fs/promises\";\nimport path from \"path\";\n\nimport { dayjs } from \"@/utils\";\n\nimport { randomUUID } from \"crypto\";\n\nimport { FileModuleRef } from \"./FileService\";\n\nimport { FileStorageProviderResult } from \"./FileStorageProviderRegistry\"\n\nexport interface FileLocalProviderOptions {\n basePath?: string; // e.g. \"uploads\"\n skipFoldernameByModuleRef?: boolean; // skip the folder [ref]/[module]\n skipFoldernameByDate?: boolean; // skip the yyyy/mm/dd folder structure\n publicBaseUrl?: string; // e.g. \"/uploads\" or \"[http://localhost:3000/uploads](http://localhost:3000/uploads)\"\n}\n\nexport const FileLocalStorageProvider = (options: FileLocalProviderOptions) => {\n\n const {\n basePath = options?.basePath ?? path.join(process.cwd(), \"uploads\"),\n skipFoldernameByModuleRef = false,\n skipFoldernameByDate = false,\n publicBaseUrl = options?.publicBaseUrl ?? `/uploads`,\n } = options;\n\n const ensureDir = (dir: string) => {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n };\n\n /**\n * Upload file to local storage.\n * Files will be stored under: basePath/ref/module/YYYY/MM/DD/\n */\n const uploadFile = async <\n T extends FileModuleRef\n >({\n field_ref,\n field_module,\n buffer,\n mimeType,\n foldernameDate,\n fileName,\n }: T & {\n buffer: Buffer;\n mimeType: string;\n foldernameDate?: string; // organize the foldername y/m/d using this date\n fileName: string;\n }): Promise<FileStorageProviderResult> => {\n\n\n const now = dayjs(foldernameDate).isValid() ? dayjs(foldernameDate) : dayjs();\n const year = now.format(\"YYYY\");\n const month = now.format(\"MM\");\n const day = now.format(\"DD\");\n\n let finalPublicBaseUrl = `${publicBaseUrl}`\n let dirParts = []\n\n if (skipFoldernameByModuleRef === false) {\n dirParts.push(field_ref, field_module)\n }\n\n if (skipFoldernameByDate === false) {\n dirParts.push(year, month, day)\n }\n\n const finalBasePath = path.join(basePath, ...dirParts)\n const dir = finalBasePath\n finalPublicBaseUrl = [finalPublicBaseUrl, ...dirParts].filter(Boolean).join('/');\n\n ensureDir(dir);\n\n const ext = path.extname(fileName);\n const uniqueName = `${randomUUID()}${ext}`; // `${base}-${randomUUID()}${ext}`;\n const filePath = path.join(dir, uniqueName);\n\n await fs.promises.writeFile(filePath, buffer);\n\n const assetPath = path.relative(process.cwd(), filePath);\n const assetUrl = `${finalPublicBaseUrl}/${uniqueName}`;\n\n return {\n assetPath,\n assetUrl,\n filename: uniqueName,\n basePath: finalBasePath,\n ...(skipFoldernameByDate === false ? {\n folderName: {\n day: Number(day),\n month: Number(month),\n year: Number(year)\n }\n } : {})\n };\n };\n\n const removeFile = async (assetPath: string) => {\n\n if (assetPath) {\n try {\n const filePath = path.resolve(process.cwd(), assetPath);\n await fsPromises.unlink(filePath);\n } catch (err) {\n // Log error but continue deleting others\n console.error(`Failed to delete file ${assetPath}:`, err);\n }\n }\n\n }\n\n return { uploadFile, removeFile };\n\n};\n"]}
@@ -18,6 +18,7 @@ export type FileGetProps = Omit<QueryGet, "datatypes"> & {
18
18
  export type FileListProps = Omit<QueryList, "datatypes"> & {};
19
19
  export type FileRemoveProps = {
20
20
  fileIds: BigInt[];
21
+ storageProviderOptions: any;
21
22
  };
22
23
  export type File = {
23
24
  tagName: string;
@@ -83,7 +84,7 @@ export declare const FileService: (props: FileServiceProps) => {
83
84
  data: any;
84
85
  total: number;
85
86
  }>;
86
- removeFiles: ({ fileIds }: FileRemoveProps) => Promise<{
87
+ removeFiles: ({ fileIds, storageProviderOptions }: FileRemoveProps) => Promise<{
87
88
  createdatetime: Date | null;
88
89
  createuserid: bigint;
89
90
  updatedatetime: Date | null;
@@ -1,13 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.FileService = exports.compressImageBuffer = exports.fileDataTypes = void 0;
7
4
  const utils_1 = require("../../utils");
8
- const path_1 = __importDefault(require("path"));
9
- const promises_1 = __importDefault(require("fs/promises"));
10
5
  const models_1 = require("../../models");
6
+ const FileLocalStorageProvider_1 = require("./FileLocalStorageProvider");
7
+ const FileGoogleCloudStorageProvider_1 = require("./FileGoogleCloudStorageProvider");
11
8
  const FileStorageProviderRegistry_1 = require("./FileStorageProviderRegistry");
12
9
  const lib_1 = require("../../lib");
13
10
  const lib_2 = require("../../lib");
@@ -99,6 +96,11 @@ exports.compressImageBuffer = compressImageBuffer;
99
96
  const FileService = (props) => {
100
97
  const { prisma, accountId = 0, actionUserId = 0, } = props;
101
98
  const fileModel = (0, models_1.FileModel)({ prisma, accountId, actionUserId });
99
+ const fileGoogleCloudStorageProvider = (0, FileGoogleCloudStorageProvider_1.FileGoogleCloudStorageProvider)({
100
+ basePath: ``,
101
+ bucketName: ``
102
+ });
103
+ const fileLocalStorageProvider = (0, FileLocalStorageProvider_1.FileLocalStorageProvider)({});
102
104
  const initBatchCode = () => {
103
105
  return `${Date.now()}_${utils_1._.random(0, 999)}`;
104
106
  };
@@ -264,7 +266,7 @@ const FileService = (props) => {
264
266
  };
265
267
  return response;
266
268
  };
267
- const removeFiles = async ({ fileIds }) => {
269
+ const removeFiles = async ({ fileIds, storageProviderOptions }) => {
268
270
  if (!fileIds.length)
269
271
  (0, utils_1.throwError)('fileIds is required');
270
272
  const filesToDelete = await fileModel.list({
@@ -275,15 +277,24 @@ const FileService = (props) => {
275
277
  // console.log('filesToDelete', filesToDelete)
276
278
  // 2️⃣ Delete the physical files
277
279
  for (const file of filesToDelete) {
280
+ // check the provider to choose delete method
281
+ const storageProviderName = file.storage_provider_name;
282
+ const assetUrl = file.asset_url;
278
283
  const assetPath = file.asset_path;
279
- if (assetPath) {
284
+ if (storageProviderName === "local" && assetPath) {
285
+ try {
286
+ let res = fileLocalStorageProvider.removeFile(assetPath);
287
+ }
288
+ catch (err) {
289
+ console.error(`Failed to delete from GCloud: ${assetUrl}`, err);
290
+ }
291
+ }
292
+ if (storageProviderName === "gcloud" && assetUrl) {
280
293
  try {
281
- const filePath = path_1.default.resolve(process.cwd(), assetPath);
282
- await promises_1.default.unlink(filePath);
294
+ let res = fileGoogleCloudStorageProvider.removeFile(assetUrl, storageProviderOptions.credentials);
283
295
  }
284
296
  catch (err) {
285
- // Log error but continue deleting others
286
- console.error(`Failed to delete file ${assetPath}:`, err);
297
+ console.error(`Failed to delete from GCloud: ${assetUrl}`, err);
287
298
  }
288
299
  }
289
300
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FileService.js","sourceRoot":"","sources":["../../../src/services/file/FileService.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAyD;AACzD,gDAAwB;AACxB,2DAA6B;AAE7B,qCAGkB;AAIlB,+EAAgG;AAQhG,+BAAuH;AAEvH,+BAGe;AAEF,QAAA,aAAa,GAAG;AACzB,uDAAuD;CAC1D,CAAA;AAqFD,6BAA6B;AAC7B,cAAc;AACd,6BAA6B;AAC7B,kCAAkC;AAClC,wBAAwB;AACxB,QAAQ;AACR,IAAI;AAEJ,kCAAkC;AAClC,0BAA0B;AAC1B,iBAAiB;AACjB,IAAI;AAEJ,IAAI,aAAa,GAAG,IAAA,4BAAsB,GAAE,CAAA;AAC5C,IAAI,gBAAgB,GAAG,IAAA,+BAAyB,GAAE,CAAA;AAElD,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,IAAA,4BAAsB,EAAC,EAAE,CAAC,CAAA;AAEpE,MAAM,gBAAgB,GAAG,CAAC,IAA6B,EAAE,EAAE;IAEvD,OAAO;QACH,4CAA4C;QAC5C,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC/C,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACrD,CAAC,GAAG,wBAAe,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACrD,CAAC,GAAG,wBAAe,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC/C,CAAC,GAAG,wBAAe,CAAC,oBAAoB,EAAE,CAAC,EAAE,IAAI,CAAC,kBAAkB;QACpE,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC/C,CAAC,GAAG,wBAAe,CAAC,eAAe,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa;QAC1D,CAAC,GAAG,wBAAe,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO;QAC7C,CAAC,GAAG,wBAAe,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACpD,CAAC,GAAG,wBAAe,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;QACjE,CAAC,GAAG,wBAAe,CAAC,gBAAgB,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;QACrE,CAAC,GAAG,wBAAe,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;QACnE,CAAC,GAAG,wBAAe,CAAC,eAAe,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa;QAC1D,CAAC,GAAG,wBAAe,CAAC,qBAAqB,EAAE,CAAC,EAAE,IAAI,CAAC,kBAAkB;QACrE,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAChD,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAChD,CAAC,GAAG,wBAAe,CAAC,aAAa,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACtD,CAAC,GAAG,wBAAe,CAAC,aAAa,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACtD,CAAC,GAAG,wBAAe,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM;QAC1C,CAAC,GAAG,wBAAe,CAAC,qBAAqB,EAAE,CAAC,EAAE,IAAI,CAAC,mBAAmB;KACzE,CAAA;AAEL,CAAC,CAAA;AAEM,MAAM,mBAAmB,GAAG,KAAK,EACpC,MAAc,EACd,QAAgB,EAChB,UAAuC,EAAE,EAK1C,EAAE;IAED,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAElD,MAAM,qBAAqB,GAAG;QAC1B,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,YAAY;QACZ,WAAW;KACd,CAAC;IAEF,0BAA0B;IAC1B,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;IACxE,CAAC;IAED,IAAI,QAAQ,GAAG,IAAA,aAAK,EAAC,MAAM,CAAC,CAAC;IAE7B,IAAI,QAAQ,EAAE,CAAC;QACX,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,gBAAwB,CAAC;IAE7B,QAAQ,QAAQ,EAAE,CAAC;QACf,KAAK,WAAW;YACZ,gBAAgB,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC9D,MAAM;QACV,KAAK,YAAY;YACb,gBAAgB,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC/D,MAAM;QACV,KAAK,YAAY,CAAC;QAClB,KAAK,YAAY,CAAC;QAClB,KAAK,WAAW,CAAC;QACjB;YACI,gBAAgB,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC/D,MAAM;IACd,CAAC;IAED,OAAO;QACH,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QACvC,MAAM,EAAE,gBAAgB;QACxB,SAAS,EAAE,gBAAgB,CAAC,UAAU;KACzC,CAAC;AAEN,CAAC,CAAC;AAtDW,QAAA,mBAAmB,uBAsD9B;AAEK,MAAM,WAAW,GAAG,CAAC,KAAuB,EAAE,EAAE;IAEnD,MAAM,EACF,MAAM,EACN,SAAS,GAAG,CAAC,EACb,YAAY,GAAG,CAAC,GACnB,GAAG,KAAK,CAAA;IAET,MAAM,SAAS,GAAG,IAAA,kBAAS,EAAC,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAA;IAEhE,MAAM,aAAa,GAAG,GAAG,EAAE;QACvB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,SAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IAC/C,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,EACvB,SAAS,GAAG,MAAM,EAClB,YAAY,GAAG,MAAM,EACrB,OAAO,EACP,KAAK,EACL,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,MAAM,EACN,WAAW,EACX,cAAc,EACd,mBAAmB,GAAG,OAAO,EAC7B,sBAAsB,EACtB,KAAK,GAAG,EAAE,EACV,uBAAuB,EACT,EAAE,EAAE;QAElB,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,IAAA,oDAAsB,EAAC,mBAAmB,EAAE,sBAAsB,CAAC,CAAC;QAErF,MAAM,YAAY,GAAG,EAAE,CAAA;QAEvB,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAElC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE,CAAA;QAC7B,MAAM,QAAQ,GAAG,KAAK,IAAI,CAAC,CAAA;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,CAAA;QAC5B,MAAM,WAAW,GAAG,QAAQ,IAAI,EAAE,CAAA;QAClC,MAAM,WAAW,GAAG,SAAS,IAAI,EAAE,CAAA;QACnC,MAAM,UAAU,GAAG,MAAM,IAAI,EAAE,CAAA;QAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAEvB,IAAI,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;YACjC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAA;YAClC,IAAI,SAAS,GAAG,IAAI,EAAE,SAAS,CAAA;YAC/B,IAAI,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC;YAEzC,IAAI,eAAe,GAAG,SAAS,CAAA,CAAC,mBAAmB;YACnD,IAAI,kBAAkB,GAAG,EAAE,CAAA,CAAC,wBAAwB;YAEpD,wEAAwE;YAExE,8CAA8C;YAC9C,IAAI,uBAAuB,EAAE,CAAC;gBAC1B,MAAM,UAAU,GAAG,MAAM,IAAA,2BAAmB,EACxC,cAAc,EACd,QAAQ,EACR,uBAAuB,CAC1B,CAAC;gBAEF,kBAAkB,GAAG,UAAU,CAAC,cAAc;oBAC1C,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;gBACvC,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,uBAAuB;YACnE,CAAC;YAED,qCAAqC;YACrC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;gBAC3C,SAAS;gBACT,YAAY;gBACZ,MAAM,EAAE,cAAc;gBACtB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,QAAQ;gBACR,QAAQ,EAAE,gBAAgB;aAC6C,CAAC,CAAC;YAE7E,MAAM,QAAQ,GAAG,SAAS,CAAA;YAC1B,MAAM,WAAW,GAAG,YAAY,CAAA;YAEhC,MAAM,QAAQ,GAAG,YAAY,EAAE,QAAQ,IAAI,EAAE,CAAA;YAC7C,MAAM,WAAW,GAAG,QAAQ,IAAI,EAAE,CAAA;YAClC,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,IAAI,EAAE,CAAA;YAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAA;YAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,IAAI,EAAE,CAAA;YAE9C,MAAM,SAAS,GAAG,QAAQ,CAAA;YAC1B,MAAM,kBAAkB,GAAG,SAAS,IAAI,CAAC,CAAA;YACzC,MAAM,aAAa,GAAG,gBAAgB,IAAI,EAAE,CAAA;YAE5C,MAAM,aAAa,GAAG,eAAe,IAAI,CAAC,CAAA;YAC1C,gCAAgC;YAEhC,MAAM,aAAa,GAAG,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,CAAA;YACzD,MAAM,eAAe,GAAG,YAAY,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,CAAA;YAC7D,MAAM,cAAc,GAAG,YAAY,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAA;YAE3D,MAAM,OAAO,GAAoB;gBAC7B,IAAI,EAAE;oBACF,QAAQ;oBACR,WAAW;oBACX,OAAO;oBACP,WAAW;oBACX,MAAM,EAAE,UAAU;oBAClB,UAAU;oBACV,QAAQ;oBACR,SAAS;oBACT,SAAS;oBACT,QAAQ;oBACR,WAAW;oBACX,SAAS;oBACT,kBAAkB;oBAClB,aAAa;oBACb,aAAa;oBACb,kBAAkB;oBAClB,mBAAmB;oBACnB,aAAa;oBACb,eAAe;oBACf,cAAc;oBACd,SAAS;oBACT,QAAQ;oBACR,QAAQ;oBACR,WAAW;oBACX,WAAW;iBACa;aAC/B,CAAC;YAEF,IAAI,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;YAEzC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC/B,CAAC;QAED,OAAO,YAAY,CAAA;IAEvB,CAAC,CAAA;IAED,UAAU;IACV,MAAM,UAAU,GAAG,KAAK,EAAE,EAAE,IAAI,EAAmB,EAAE,EAAE;QAEnD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAExD,MAAM,SAAS,GAAG,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAA;QAEzC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAEtE,CAAC,CAAA;IAED,wEAAwE;IAExE,+CAA+C;IAC/C,IAAI;IAEJ,MAAM,OAAO,GAAG,KAAK,EAAE,EAAE,EAAE,EAAgB,EAAE,EAAE;QAE3C,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC;YAC3B,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,wBAAe,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAC5E,SAAS,EAAE,GAAG,wBAAe,CAAC,OAAO,EAAE;YACvC,SAAS,EAAE,KAAK;SACnB,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAE3B,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,EAAE,EACrB,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,SAAS,GACG,EAAE,EAAE;QAEhB,IAAI,SAAS,GAAa,EAAE,CAAA;QAC5B,IAAI,WAAW,GAAa,EAAE,CAAA;QAC9B,IAAI,UAAU,GAAa,EAAE,CAAA;QAE7B,IAAI,YAAY,GAAa,EAAE,CAAA;QAC/B,IAAI,cAAc,GAAa,EAAE,CAAA;QAEjC,SAAS,GAAG;YACR,IAAA,oBAAc,EAAC,EAAE,EAAE,aAAa,CAAC;YACjC,IAAA,oBAAc,EAAC,EAAE,EAAE,gBAAgB,CAAC;SACvC,CAAA;QAED,WAAW,GAAG;YACV,eAAe,CAAC,OAAO;YACvB,eAAe,CAAC,OAAO;SAC1B,CAAA;QAED,sBAAsB;QAEtB,UAAU,GAAG;YACT,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC7B,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;SACnC,CAAA;QAED,IAAI,aAAa,GAAG;YAChB,GAAG,aAAa;YAChB,GAAG,gBAAgB;SACtB,CAAA;QAED,IAAI,QAAQ,GAAG;YACX,2BAA2B;YAC3B,0BAA0B;YAC1B,2DAA2D;SAC9D,CAAA;QAED,IAAI,UAAU,GAAG,IAAA,qBAAe,EAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACtD,IAAI,cAAc,GAAG,IAAA,yBAAmB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAEvD,+BAA+B;QAC/B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAA,sBAAgB,EAAC;YAC3C,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,UAAU;YACrB,QAAQ,EAAE,GAAG,wBAAe,CAAC,OAAO,EAAE;YACtC,SAAS;YACT,eAAe;YACf,OAAO;YACP,aAAa;YACb,SAAS;YACT,YAAY;YACZ,WAAW;YACX,cAAc;YACd,QAAQ;YACR,UAAU;YACV,UAAU;YACV,cAAc;SACjB,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG;YACb,IAAI;YACJ,KAAK;SACR,CAAA;QAED,OAAO,QAAQ,CAAA;IAEnB,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,EAAE,EAAE,OAAO,EAAmB,EAAE,EAAE;QAEvD,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,IAAA,kBAAU,EAAC,qBAAqB,CAAC,CAAC;QAEvD,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC;YACvC,KAAK,EAAE;gBACH,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;aAC3B;SACJ,CAAC,CAAC;QAEH,8CAA8C;QAE9C,gCAAgC;QAChC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAA;YAEjC,IAAI,SAAS,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACD,MAAM,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;oBACxD,MAAM,kBAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC9B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACX,yCAAyC;oBACzC,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC9D,CAAC;YACL,CAAC;QACL,CAAC;QAED,eAAe;QACf,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,wBAAe,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAExG,OAAO,QAAQ,CAAA;IACnB,CAAC,CAAC;IAEF,+BAA+B;IAC/B,2CAA2C;IAC3C,IAAI;IAEJ,OAAO;QACH,WAAW;QACX,cAAc;QACd,cAAc;QACd,OAAO;QACP,SAAS;QACT,WAAW;QACX,eAAe;KAClB,CAAA;AAEL,CAAC,CAAA;AA3SY,QAAA,WAAW,eA2SvB","sourcesContent":["import { _, sharp, logError, throwError } from \"@/utils\";\nimport path from \"path\";\nimport fs from \"fs/promises\";\n\nimport {\n FileModel,\n ModelFileFields,\n} from \"@/models\";\n\nimport { FileLocalProviderOptions } from \"./FileLocalStorageProvider\"\nimport { FileGoogleCloudProviderOptions } from \"./FileGoogleCloudStorageProvider\"\nimport { getFileStorageProvider, FileStorageProviderType } from \"./FileStorageProviderRegistry\";\n\nimport { InjectionFieldModuleRef } from \"@/services\"\n\nimport { QueryList, QueryGet } from \"@/schema/common\";\n\nimport { DefaultServiceProps } from \"@/utils\";\n\nimport { getFileSqlRelationMaps, buildSqlSelect, buildSqlLimitOffset, buildSqlOrderBy, getListWithCount } from \"@/lib\";\n\nimport {\n buildFileMainSqlSelect,\n buildFileDefaultSqlSelect\n} from \"@/lib\";\n\nexport const fileDataTypes = {\n // salesOrderInjectionFields: \"sales_injection_fields\",\n}\n\nexport type FileModuleRef = InjectionFieldModuleRef\n\nexport type FileDataType = keyof typeof fileDataTypes;\n\nexport type FileServiceProps = DefaultServiceProps & {\n};\n\nexport type FileImageCompressionOptions = {\n maxWidth?: number;\n quality?: number;\n}\n\nexport type FileGetProps = Omit<QueryGet, \"datatypes\"> & {\n id: number,\n // datatypes: FileDataType[]\n};\n\nexport type FileListProps = Omit<QueryList, \"datatypes\"> & {\n // datatypes: FileDataType[]\n}\n\nexport type FileRemoveProps = {\n fileIds: BigInt[]\n};\n\nexport type File = {\n tagName: string;\n description: string;\n folderPath: string;\n assetUrl: string;\n assetPath: string;\n fileLabel: string;\n fileName: string;\n contentType: string;\n inputType: string;\n inputFileSizeBytes: number;\n inputFileName: string;\n fileSizeBytes: number;\n fileCompressFormat: string;\n storageProviderName: string;\n foldernameDay: number;\n foldernameMonth: number;\n foldernameYear: number;\n batchCode: string;\n referId1: number;\n referId2: number;\n referLabel1: string;\n referLabel2: string;\n remark: string;\n}\n\nexport type FileUploadItem = {\n buffer: Buffer; // Raw file data\n originalName: string; // Client filename\n mimeType: string; // e.g. \"image/png\"\n sizeBytes: number; // File size in bytes\n // providerName?: FileStorageProviderType; // optional: override global provider\n};\n\n\nexport type FileCreateProps = {\n data: File & {\n fieldRef: FileModuleRef[\"field_ref\"],\n fieldModule: FileModuleRef[\"field_module\"]\n }\n}\n\nexport type FileUploadProps = FileModuleRef & {\n description?: string,\n tagName?: string,\n label?: string,\n refId: number\n refId2?: number\n refLabel?: string\n refLabel2?: string\n remark: string\n foldernameDate?: string,\n storageProviderName?: FileStorageProviderType;\n storageProviderOptions?: FileLocalProviderOptions | FileGoogleCloudProviderOptions;\n files: FileUploadItem[]\n imageCompressionOptions?: FileImageCompressionOptions\n}\n\n// let a: FileCreateProps = {\n// data: {\n// field_ref: \"user\",\n// field_module: \"driver\",\n// fileLabel: ''\n// }\n// }\n\n// export type FileUpdateProps = {\n// documentId: number,\n// data: File\n// }\n\nlet mainSqlSelect = buildFileMainSqlSelect()\nlet defaultSqlSelect = buildFileDefaultSqlSelect()\n\nconst { relationKeys, sqlRelationMaps } = getFileSqlRelationMaps(``)\n\nconst getCreatePayload = (data: FileCreateProps[\"data\"]) => {\n\n return {\n // [`${ModelFileFields.file_id}`]: fileType,\n [`${ModelFileFields.asset_path}`]: data.assetPath,\n [`${ModelFileFields.asset_url}`]: data.assetUrl,\n [`${ModelFileFields.batch_code}`]: data.batchCode,\n [`${ModelFileFields.content_type}`]: data.contentType,\n [`${ModelFileFields.field_module}`]: data.fieldModule,\n [`${ModelFileFields.field_ref}`]: data.fieldRef,\n [`${ModelFileFields.file_compress_format}`]: data.fileCompressFormat,\n [`${ModelFileFields.file_label}`]: data.fileLabel,\n [`${ModelFileFields.file_name}`]: data.fileName,\n [`${ModelFileFields.file_size_bytes}`]: data.fileSizeBytes,\n [`${ModelFileFields.tag_name}`]: data.tagName,\n [`${ModelFileFields.description}`]: data.description,\n [`${ModelFileFields.foldername_day}`]: Number(data.foldernameDay),\n [`${ModelFileFields.foldername_month}`]: Number(data.foldernameMonth),\n [`${ModelFileFields.foldername_year}`]: Number(data.foldernameYear),\n [`${ModelFileFields.input_file_name}`]: data.inputFileName,\n [`${ModelFileFields.input_file_size_bytes}`]: data.inputFileSizeBytes,\n [`${ModelFileFields.input_type}`]: data.inputType,\n [`${ModelFileFields.refer_id_1}`]: data.referId1,\n [`${ModelFileFields.refer_id_2}`]: data.referId2,\n [`${ModelFileFields.refer_label_1}`]: data.referLabel1,\n [`${ModelFileFields.refer_label_2}`]: data.referLabel2,\n [`${ModelFileFields.remark}`]: data.remark,\n [`${ModelFileFields.storage_provider_name}`]: data.storageProviderName,\n }\n\n}\n\nexport const compressImageBuffer = async (\n buffer: Buffer,\n mimeType: string,\n options: FileImageCompressionOptions = {}\n): Promise<{\n compressFormat: string;\n buffer: Buffer;\n sizeBytes: number;\n}> => {\n\n const { maxWidth = 1024, quality = 80 } = options;\n\n const SUPPORTED_IMAGE_MIMES = [\n \"image/jpeg\",\n \"image/png\",\n \"image/webp\",\n \"image/tiff\",\n \"image/bmp\",\n ];\n\n // Skip unsupported images\n if (!SUPPORTED_IMAGE_MIMES.includes(mimeType)) {\n return { compressFormat: '', buffer, sizeBytes: buffer.byteLength };\n }\n\n let pipeline = sharp(buffer);\n\n if (maxWidth) {\n pipeline = pipeline.resize({ width: maxWidth });\n }\n\n let compressedBuffer: Buffer;\n\n switch (mimeType) {\n case \"image/png\":\n compressedBuffer = await pipeline.png({ quality }).toBuffer();\n break;\n case \"image/webp\":\n compressedBuffer = await pipeline.webp({ quality }).toBuffer();\n break;\n case \"image/jpeg\":\n case \"image/tiff\":\n case \"image/bmp\":\n default:\n compressedBuffer = await pipeline.jpeg({ quality }).toBuffer();\n break;\n }\n\n return {\n compressFormat: JSON.stringify(options),\n buffer: compressedBuffer,\n sizeBytes: compressedBuffer.byteLength\n };\n\n};\n\nexport const FileService = (props: FileServiceProps) => {\n\n const {\n prisma,\n accountId = 0,\n actionUserId = 0,\n } = props\n\n const fileModel = FileModel({ prisma, accountId, actionUserId })\n\n const initBatchCode = () => {\n return `${Date.now()}_${_.random(0, 999)}`;\n }\n\n const uploadFiles = async ({\n field_ref = \"item\",\n field_module = \"item\",\n tagName,\n label,\n refId,\n refId2,\n refLabel,\n refLabel2,\n remark,\n description,\n foldernameDate,\n storageProviderName = \"local\",\n storageProviderOptions,\n files = [],\n imageCompressionOptions\n }: FileUploadProps) => {\n\n // get the correct provider\n const provider = getFileStorageProvider(storageProviderName, storageProviderOptions);\n\n const allResponses = []\n\n const batchCode = initBatchCode();\n\n const fileLabel = label ?? \"\"\n const referId1 = refId ?? 0\n const referId2 = refId2 ?? 0\n const referLabel1 = refLabel ?? \"\"\n const referLabel2 = refLabel2 ?? \"\"\n const fileRemark = remark ?? \"\"\n\n for (const file of files) {\n\n let bufferToUpload = file.buffer;\n let mimeType = file.mimeType ?? \"\"\n let sizeBytes = file?.sizeBytes\n let fileOriginalName = file.originalName;\n\n let outputSizeBytes = sizeBytes // output file size\n let fileCompressFormat = `` // output image compress\n\n // const ext = file.originalName?.split(\".\").pop()?.toLowerCase() ?? \"\";\n\n // Only compress if image and options provided\n if (imageCompressionOptions) {\n const compressed = await compressImageBuffer(\n bufferToUpload,\n mimeType,\n imageCompressionOptions\n );\n\n fileCompressFormat = compressed.compressFormat,\n bufferToUpload = compressed.buffer;\n outputSizeBytes = compressed.sizeBytes; // update the file size\n }\n\n // upload using the provider - buffer\n const uploadResult = await provider.uploadFile({\n field_ref,\n field_module,\n buffer: bufferToUpload,\n ...(foldernameDate ? { foldernameDate } : {}),\n mimeType,\n fileName: fileOriginalName\n } as FileModuleRef & { buffer: Buffer; mimeType: string; fileName: string });\n\n const fieldRef = field_ref\n const fieldModule = field_module\n\n const fileName = uploadResult?.filename ?? \"\"\n const contentType = mimeType ?? \"\"\n const folderPath = uploadResult.assetPath ?? \"\"\n const assetUrl = uploadResult.assetUrl ?? \"\"\n const assetPath = uploadResult.assetPath ?? \"\"\n\n const inputType = `buffer`\n const inputFileSizeBytes = sizeBytes ?? 0\n const inputFileName = fileOriginalName ?? \"\"\n\n const fileSizeBytes = outputSizeBytes ?? 0\n // const fileCompressFormat = ``\n\n const foldernameDay = uploadResult?.folderName?.day ?? \"\"\n const foldernameMonth = uploadResult?.folderName?.month ?? \"\"\n const foldernameYear = uploadResult?.folderName?.year ?? \"\"\n\n const payload: FileCreateProps = {\n data: {\n fieldRef,\n fieldModule,\n tagName,\n description,\n remark: fileRemark,\n folderPath,\n assetUrl,\n assetPath,\n fileLabel,\n fileName,\n contentType,\n inputType,\n inputFileSizeBytes,\n inputFileName,\n fileSizeBytes,\n fileCompressFormat,\n storageProviderName,\n foldernameDay,\n foldernameMonth,\n foldernameYear,\n batchCode,\n referId1,\n referId2,\n referLabel1,\n referLabel2\n } as FileCreateProps[\"data\"],\n };\n\n let response = await createFile(payload);\n\n allResponses.push(response)\n }\n\n return allResponses\n\n }\n\n // private\n const createFile = async ({ data }: FileCreateProps) => {\n\n const _data = getCreatePayload(data)\n\n if (!_data) {\n throw new Error(`Invalid create file payload: ${JSON.stringify(_data)}`);\n }\n\n const response = await fileModel.create({ data: _data })\n\n const newFileId = response?.file_id ?? \"\"\n\n return newFileId ? await getFile({ id: Number(newFileId) }) : null\n\n }\n\n // const updateFile = async ({ documentId, data }: FileUpdateProps) => {\n\n // return await getFile({ id: documentId })\n // }\n\n const getFile = async ({ id }: FileGetProps) => {\n\n let { data } = await listFiles({\n limit: 1,\n offset: 0,\n filters: [{ field: `${ModelFileFields.file_id}`, operator: \"=\", value: id }],\n sortfield: `${ModelFileFields.file_id}`,\n sortorder: \"ASC\"\n })\n\n return data[0] ?? null;\n\n };\n\n const listFiles = async ({\n limit,\n offset,\n filters,\n sortfield,\n sortorder,\n }: FileListProps) => {\n\n let sqlSelect: string[] = []\n let sqlRelation: string[] = []\n let sqlGroupBy: string[] = []\n\n let sqlSelectAgg: string[] = []\n let sqlRelationAgg: string[] = []\n\n sqlSelect = [\n buildSqlSelect(``, mainSqlSelect),\n buildSqlSelect(``, defaultSqlSelect)\n ]\n\n sqlRelation = [\n sqlRelationMaps.creator,\n sqlRelationMaps.updater\n ]\n\n // sqlRelationAgg = []\n\n sqlGroupBy = [\n ...Object.keys(mainSqlSelect),\n ...Object.keys(defaultSqlSelect)\n ]\n\n let filterColumns = {\n ...mainSqlSelect,\n ...defaultSqlSelect\n }\n\n let sqlWhere = [\n `mainfile.isdelete = false`,\n `mainfile.istrash = false`,\n // `LOWER(mainfile.doc_type) = LOWER('${documentTypeKey}')`\n ]\n\n let sqlOrderby = buildSqlOrderBy(sortfield, sortorder)\n let sqlLimitOffset = buildSqlLimitOffset(limit, offset)\n\n // get the listing data & count\n const { data, total } = await getListWithCount({\n model: fileModel,\n tableName: \"files\",\n mainAlias: \"mainfile\",\n countKey: `${ModelFileFields.file_id}`,\n accountId,\n sqlRelationMaps,\n filters,\n filterColumns,\n sqlSelect,\n sqlSelectAgg,\n sqlRelation,\n sqlRelationAgg,\n sqlWhere,\n sqlGroupBy,\n sqlOrderby,\n sqlLimitOffset\n })\n\n const response = {\n data,\n total\n }\n\n return response\n\n };\n\n const removeFiles = async ({ fileIds }: FileRemoveProps) => {\n\n if (!fileIds.length) throwError('fileIds is required');\n\n const filesToDelete = await fileModel.list({\n where: {\n file_id: { in: fileIds }\n }\n });\n\n // console.log('filesToDelete', filesToDelete)\n\n // 2️⃣ Delete the physical files\n for (const file of filesToDelete) {\n\n const assetPath = file.asset_path\n\n if (assetPath) {\n try {\n const filePath = path.resolve(process.cwd(), assetPath);\n await fs.unlink(filePath);\n } catch (err) {\n // Log error but continue deleting others\n console.error(`Failed to delete file ${assetPath}:`, err);\n }\n }\n }\n\n // remove files\n const response = await fileModel.remove({ where: { [`${ModelFileFields.file_id}`]: { in: fileIds } } });\n\n return response\n };\n\n // const getDataTypes = () => {\n // return Object.values(fileDataTypes);\n // }\n\n return {\n uploadFiles,\n // createFile,\n // updateFile,\n getFile,\n listFiles,\n removeFiles,\n // getDataTypes\n }\n\n}\n\n"]}
1
+ {"version":3,"file":"FileService.js","sourceRoot":"","sources":["../../../src/services/file/FileService.ts"],"names":[],"mappings":";;;AAAA,mCAAyD;AAIzD,qCAGkB;AAElB,yEAA+F;AAC/F,qFAAiH;AACjH,+EAAgG;AAQhG,+BAAuH;AAEvH,+BAGe;AAEF,QAAA,aAAa,GAAG;AACzB,uDAAuD;CAC1D,CAAA;AAsFD,6BAA6B;AAC7B,cAAc;AACd,6BAA6B;AAC7B,kCAAkC;AAClC,wBAAwB;AACxB,QAAQ;AACR,IAAI;AAEJ,kCAAkC;AAClC,0BAA0B;AAC1B,iBAAiB;AACjB,IAAI;AAEJ,IAAI,aAAa,GAAG,IAAA,4BAAsB,GAAE,CAAA;AAC5C,IAAI,gBAAgB,GAAG,IAAA,+BAAyB,GAAE,CAAA;AAElD,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,IAAA,4BAAsB,EAAC,EAAE,CAAC,CAAA;AAEpE,MAAM,gBAAgB,GAAG,CAAC,IAA6B,EAAE,EAAE;IAEvD,OAAO;QACH,4CAA4C;QAC5C,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC/C,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACrD,CAAC,GAAG,wBAAe,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACrD,CAAC,GAAG,wBAAe,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC/C,CAAC,GAAG,wBAAe,CAAC,oBAAoB,EAAE,CAAC,EAAE,IAAI,CAAC,kBAAkB;QACpE,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAC/C,CAAC,GAAG,wBAAe,CAAC,eAAe,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa;QAC1D,CAAC,GAAG,wBAAe,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO;QAC7C,CAAC,GAAG,wBAAe,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACpD,CAAC,GAAG,wBAAe,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;QACjE,CAAC,GAAG,wBAAe,CAAC,gBAAgB,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;QACrE,CAAC,GAAG,wBAAe,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;QACnE,CAAC,GAAG,wBAAe,CAAC,eAAe,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa;QAC1D,CAAC,GAAG,wBAAe,CAAC,qBAAqB,EAAE,CAAC,EAAE,IAAI,CAAC,kBAAkB;QACrE,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS;QACjD,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAChD,CAAC,GAAG,wBAAe,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ;QAChD,CAAC,GAAG,wBAAe,CAAC,aAAa,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACtD,CAAC,GAAG,wBAAe,CAAC,aAAa,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW;QACtD,CAAC,GAAG,wBAAe,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM;QAC1C,CAAC,GAAG,wBAAe,CAAC,qBAAqB,EAAE,CAAC,EAAE,IAAI,CAAC,mBAAmB;KACzE,CAAA;AAEL,CAAC,CAAA;AAEM,MAAM,mBAAmB,GAAG,KAAK,EACpC,MAAc,EACd,QAAgB,EAChB,UAAuC,EAAE,EAK1C,EAAE;IAED,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAElD,MAAM,qBAAqB,GAAG;QAC1B,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,YAAY;QACZ,WAAW;KACd,CAAC;IAEF,0BAA0B;IAC1B,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;IACxE,CAAC;IAED,IAAI,QAAQ,GAAG,IAAA,aAAK,EAAC,MAAM,CAAC,CAAC;IAE7B,IAAI,QAAQ,EAAE,CAAC;QACX,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,gBAAwB,CAAC;IAE7B,QAAQ,QAAQ,EAAE,CAAC;QACf,KAAK,WAAW;YACZ,gBAAgB,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC9D,MAAM;QACV,KAAK,YAAY;YACb,gBAAgB,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC/D,MAAM;QACV,KAAK,YAAY,CAAC;QAClB,KAAK,YAAY,CAAC;QAClB,KAAK,WAAW,CAAC;QACjB;YACI,gBAAgB,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC/D,MAAM;IACd,CAAC;IAED,OAAO;QACH,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QACvC,MAAM,EAAE,gBAAgB;QACxB,SAAS,EAAE,gBAAgB,CAAC,UAAU;KACzC,CAAC;AAEN,CAAC,CAAC;AAtDW,QAAA,mBAAmB,uBAsD9B;AAEK,MAAM,WAAW,GAAG,CAAC,KAAuB,EAAE,EAAE;IAEnD,MAAM,EACF,MAAM,EACN,SAAS,GAAG,CAAC,EACb,YAAY,GAAG,CAAC,GACnB,GAAG,KAAK,CAAA;IAET,MAAM,SAAS,GAAG,IAAA,kBAAS,EAAC,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAA;IAEhE,MAAM,8BAA8B,GAAG,IAAA,+DAA8B,EAAC;QAClE,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,EAAE;KACjB,CAAC,CAAA;IAEF,MAAM,wBAAwB,GAAG,IAAA,mDAAwB,EAAC,EAAE,CAAC,CAAA;IAE7D,MAAM,aAAa,GAAG,GAAG,EAAE;QACvB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,SAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IAC/C,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,EACvB,SAAS,GAAG,MAAM,EAClB,YAAY,GAAG,MAAM,EACrB,OAAO,EACP,KAAK,EACL,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,MAAM,EACN,WAAW,EACX,cAAc,EACd,mBAAmB,GAAG,OAAO,EAC7B,sBAAsB,EACtB,KAAK,GAAG,EAAE,EACV,uBAAuB,EACT,EAAE,EAAE;QAElB,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,IAAA,oDAAsB,EAAC,mBAAmB,EAAE,sBAAsB,CAAC,CAAC;QAErF,MAAM,YAAY,GAAG,EAAE,CAAA;QAEvB,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAElC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE,CAAA;QAC7B,MAAM,QAAQ,GAAG,KAAK,IAAI,CAAC,CAAA;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,CAAA;QAC5B,MAAM,WAAW,GAAG,QAAQ,IAAI,EAAE,CAAA;QAClC,MAAM,WAAW,GAAG,SAAS,IAAI,EAAE,CAAA;QACnC,MAAM,UAAU,GAAG,MAAM,IAAI,EAAE,CAAA;QAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAEvB,IAAI,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;YACjC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAA;YAClC,IAAI,SAAS,GAAG,IAAI,EAAE,SAAS,CAAA;YAC/B,IAAI,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC;YAEzC,IAAI,eAAe,GAAG,SAAS,CAAA,CAAC,mBAAmB;YACnD,IAAI,kBAAkB,GAAG,EAAE,CAAA,CAAC,wBAAwB;YAEpD,wEAAwE;YAExE,8CAA8C;YAC9C,IAAI,uBAAuB,EAAE,CAAC;gBAC1B,MAAM,UAAU,GAAG,MAAM,IAAA,2BAAmB,EACxC,cAAc,EACd,QAAQ,EACR,uBAAuB,CAC1B,CAAC;gBAEF,kBAAkB,GAAG,UAAU,CAAC,cAAc;oBAC1C,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;gBACvC,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,uBAAuB;YACnE,CAAC;YAED,qCAAqC;YACrC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;gBAC3C,SAAS;gBACT,YAAY;gBACZ,MAAM,EAAE,cAAc;gBACtB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,QAAQ;gBACR,QAAQ,EAAE,gBAAgB;aAC6C,CAAC,CAAC;YAE7E,MAAM,QAAQ,GAAG,SAAS,CAAA;YAC1B,MAAM,WAAW,GAAG,YAAY,CAAA;YAEhC,MAAM,QAAQ,GAAG,YAAY,EAAE,QAAQ,IAAI,EAAE,CAAA;YAC7C,MAAM,WAAW,GAAG,QAAQ,IAAI,EAAE,CAAA;YAClC,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,IAAI,EAAE,CAAA;YAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAA;YAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,IAAI,EAAE,CAAA;YAE9C,MAAM,SAAS,GAAG,QAAQ,CAAA;YAC1B,MAAM,kBAAkB,GAAG,SAAS,IAAI,CAAC,CAAA;YACzC,MAAM,aAAa,GAAG,gBAAgB,IAAI,EAAE,CAAA;YAE5C,MAAM,aAAa,GAAG,eAAe,IAAI,CAAC,CAAA;YAC1C,gCAAgC;YAEhC,MAAM,aAAa,GAAG,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,CAAA;YACzD,MAAM,eAAe,GAAG,YAAY,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,CAAA;YAC7D,MAAM,cAAc,GAAG,YAAY,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAA;YAE3D,MAAM,OAAO,GAAoB;gBAC7B,IAAI,EAAE;oBACF,QAAQ;oBACR,WAAW;oBACX,OAAO;oBACP,WAAW;oBACX,MAAM,EAAE,UAAU;oBAClB,UAAU;oBACV,QAAQ;oBACR,SAAS;oBACT,SAAS;oBACT,QAAQ;oBACR,WAAW;oBACX,SAAS;oBACT,kBAAkB;oBAClB,aAAa;oBACb,aAAa;oBACb,kBAAkB;oBAClB,mBAAmB;oBACnB,aAAa;oBACb,eAAe;oBACf,cAAc;oBACd,SAAS;oBACT,QAAQ;oBACR,QAAQ;oBACR,WAAW;oBACX,WAAW;iBACa;aAC/B,CAAC;YAEF,IAAI,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;YAEzC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC/B,CAAC;QAED,OAAO,YAAY,CAAA;IAEvB,CAAC,CAAA;IAED,UAAU;IACV,MAAM,UAAU,GAAG,KAAK,EAAE,EAAE,IAAI,EAAmB,EAAE,EAAE;QAEnD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;QAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAExD,MAAM,SAAS,GAAG,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAA;QAEzC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAEtE,CAAC,CAAA;IAED,wEAAwE;IAExE,+CAA+C;IAC/C,IAAI;IAEJ,MAAM,OAAO,GAAG,KAAK,EAAE,EAAE,EAAE,EAAgB,EAAE,EAAE;QAE3C,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC;YAC3B,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,wBAAe,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAC5E,SAAS,EAAE,GAAG,wBAAe,CAAC,OAAO,EAAE;YACvC,SAAS,EAAE,KAAK;SACnB,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAE3B,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,EAAE,EACrB,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,SAAS,GACG,EAAE,EAAE;QAEhB,IAAI,SAAS,GAAa,EAAE,CAAA;QAC5B,IAAI,WAAW,GAAa,EAAE,CAAA;QAC9B,IAAI,UAAU,GAAa,EAAE,CAAA;QAE7B,IAAI,YAAY,GAAa,EAAE,CAAA;QAC/B,IAAI,cAAc,GAAa,EAAE,CAAA;QAEjC,SAAS,GAAG;YACR,IAAA,oBAAc,EAAC,EAAE,EAAE,aAAa,CAAC;YACjC,IAAA,oBAAc,EAAC,EAAE,EAAE,gBAAgB,CAAC;SACvC,CAAA;QAED,WAAW,GAAG;YACV,eAAe,CAAC,OAAO;YACvB,eAAe,CAAC,OAAO;SAC1B,CAAA;QAED,sBAAsB;QAEtB,UAAU,GAAG;YACT,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC7B,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;SACnC,CAAA;QAED,IAAI,aAAa,GAAG;YAChB,GAAG,aAAa;YAChB,GAAG,gBAAgB;SACtB,CAAA;QAED,IAAI,QAAQ,GAAG;YACX,2BAA2B;YAC3B,0BAA0B;YAC1B,2DAA2D;SAC9D,CAAA;QAED,IAAI,UAAU,GAAG,IAAA,qBAAe,EAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACtD,IAAI,cAAc,GAAG,IAAA,yBAAmB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAEvD,+BAA+B;QAC/B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAA,sBAAgB,EAAC;YAC3C,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,UAAU;YACrB,QAAQ,EAAE,GAAG,wBAAe,CAAC,OAAO,EAAE;YACtC,SAAS;YACT,eAAe;YACf,OAAO;YACP,aAAa;YACb,SAAS;YACT,YAAY;YACZ,WAAW;YACX,cAAc;YACd,QAAQ;YACR,UAAU;YACV,UAAU;YACV,cAAc;SACjB,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG;YACb,IAAI;YACJ,KAAK;SACR,CAAA;QAED,OAAO,QAAQ,CAAA;IAEnB,CAAC,CAAC;IAGF,MAAM,WAAW,GAAG,KAAK,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAmB,EAAE,EAAE;QAE/E,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,IAAA,kBAAU,EAAC,qBAAqB,CAAC,CAAC;QAEvD,MAAM,aAAa,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC;YACvC,KAAK,EAAE;gBACH,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;aAC3B;SACJ,CAAC,CAAC;QAEH,8CAA8C;QAE9C,gCAAgC;QAChC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YAE/B,6CAA6C;YAC7C,MAAM,mBAAmB,GAAG,IAAI,CAAC,qBAAgD,CAAA;YACjF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAA;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAA;YAEjC,IAAI,mBAAmB,KAAK,OAAO,IAAI,SAAS,EAAE,CAAC;gBAE/C,IAAI,CAAC;oBACD,IAAI,GAAG,GAAG,wBAAwB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;gBAC5D,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;gBACpE,CAAC;YAEL,CAAC;YAED,IAAI,mBAAmB,KAAK,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBAE/C,IAAI,CAAC;oBACD,IAAI,GAAG,GAAG,8BAA8B,CAAC,UAAU,CAAC,QAAQ,EAAE,sBAAsB,CAAC,WAAW,CAAC,CAAA;gBACrG,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,iCAAiC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;gBACpE,CAAC;YAEL,CAAC;QAEL,CAAC;QAED,eAAe;QACf,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,wBAAe,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAExG,OAAO,QAAQ,CAAA;IACnB,CAAC,CAAC;IAEF,+BAA+B;IAC/B,2CAA2C;IAC3C,IAAI;IAEJ,OAAO;QACH,WAAW;QACX,cAAc;QACd,cAAc;QACd,OAAO;QACP,SAAS;QACT,WAAW;QACX,eAAe;KAClB,CAAA;AAEL,CAAC,CAAA;AAjUY,QAAA,WAAW,eAiUvB","sourcesContent":["import { _, sharp, logError, throwError } from \"@/utils\";\nimport path from \"path\";\nimport fs from \"fs/promises\";\n\nimport {\n FileModel,\n ModelFileFields,\n} from \"@/models\";\n\nimport { FileLocalProviderOptions, FileLocalStorageProvider } from \"./FileLocalStorageProvider\"\nimport { FileGoogleCloudProviderOptions, FileGoogleCloudStorageProvider } from \"./FileGoogleCloudStorageProvider\"\nimport { getFileStorageProvider, FileStorageProviderType } from \"./FileStorageProviderRegistry\";\n\nimport { InjectionFieldModuleRef } from \"@/services\"\n\nimport { QueryList, QueryGet } from \"@/schema/common\";\n\nimport { DefaultServiceProps } from \"@/utils\";\n\nimport { getFileSqlRelationMaps, buildSqlSelect, buildSqlLimitOffset, buildSqlOrderBy, getListWithCount } from \"@/lib\";\n\nimport {\n buildFileMainSqlSelect,\n buildFileDefaultSqlSelect\n} from \"@/lib\";\n\nexport const fileDataTypes = {\n // salesOrderInjectionFields: \"sales_injection_fields\",\n}\n\nexport type FileModuleRef = InjectionFieldModuleRef\n\nexport type FileDataType = keyof typeof fileDataTypes;\n\nexport type FileServiceProps = DefaultServiceProps & {\n};\n\nexport type FileImageCompressionOptions = {\n maxWidth?: number;\n quality?: number;\n}\n\nexport type FileGetProps = Omit<QueryGet, \"datatypes\"> & {\n id: number,\n // datatypes: FileDataType[]\n};\n\nexport type FileListProps = Omit<QueryList, \"datatypes\"> & {\n // datatypes: FileDataType[]\n}\n\nexport type FileRemoveProps = {\n fileIds: BigInt[],\n storageProviderOptions: any\n};\n\nexport type File = {\n tagName: string;\n description: string;\n folderPath: string;\n assetUrl: string;\n assetPath: string;\n fileLabel: string;\n fileName: string;\n contentType: string;\n inputType: string;\n inputFileSizeBytes: number;\n inputFileName: string;\n fileSizeBytes: number;\n fileCompressFormat: string;\n storageProviderName: string;\n foldernameDay: number;\n foldernameMonth: number;\n foldernameYear: number;\n batchCode: string;\n referId1: number;\n referId2: number;\n referLabel1: string;\n referLabel2: string;\n remark: string;\n}\n\nexport type FileUploadItem = {\n buffer: Buffer; // Raw file data\n originalName: string; // Client filename\n mimeType: string; // e.g. \"image/png\"\n sizeBytes: number; // File size in bytes\n // providerName?: FileStorageProviderType; // optional: override global provider\n};\n\n\nexport type FileCreateProps = {\n data: File & {\n fieldRef: FileModuleRef[\"field_ref\"],\n fieldModule: FileModuleRef[\"field_module\"]\n }\n}\n\nexport type FileUploadProps = FileModuleRef & {\n description?: string,\n tagName?: string,\n label?: string,\n refId: number\n refId2?: number\n refLabel?: string\n refLabel2?: string\n remark: string\n foldernameDate?: string,\n storageProviderName?: FileStorageProviderType;\n storageProviderOptions?: FileLocalProviderOptions | FileGoogleCloudProviderOptions;\n files: FileUploadItem[]\n imageCompressionOptions?: FileImageCompressionOptions\n}\n\n// let a: FileCreateProps = {\n// data: {\n// field_ref: \"user\",\n// field_module: \"driver\",\n// fileLabel: ''\n// }\n// }\n\n// export type FileUpdateProps = {\n// documentId: number,\n// data: File\n// }\n\nlet mainSqlSelect = buildFileMainSqlSelect()\nlet defaultSqlSelect = buildFileDefaultSqlSelect()\n\nconst { relationKeys, sqlRelationMaps } = getFileSqlRelationMaps(``)\n\nconst getCreatePayload = (data: FileCreateProps[\"data\"]) => {\n\n return {\n // [`${ModelFileFields.file_id}`]: fileType,\n [`${ModelFileFields.asset_path}`]: data.assetPath,\n [`${ModelFileFields.asset_url}`]: data.assetUrl,\n [`${ModelFileFields.batch_code}`]: data.batchCode,\n [`${ModelFileFields.content_type}`]: data.contentType,\n [`${ModelFileFields.field_module}`]: data.fieldModule,\n [`${ModelFileFields.field_ref}`]: data.fieldRef,\n [`${ModelFileFields.file_compress_format}`]: data.fileCompressFormat,\n [`${ModelFileFields.file_label}`]: data.fileLabel,\n [`${ModelFileFields.file_name}`]: data.fileName,\n [`${ModelFileFields.file_size_bytes}`]: data.fileSizeBytes,\n [`${ModelFileFields.tag_name}`]: data.tagName,\n [`${ModelFileFields.description}`]: data.description,\n [`${ModelFileFields.foldername_day}`]: Number(data.foldernameDay),\n [`${ModelFileFields.foldername_month}`]: Number(data.foldernameMonth),\n [`${ModelFileFields.foldername_year}`]: Number(data.foldernameYear),\n [`${ModelFileFields.input_file_name}`]: data.inputFileName,\n [`${ModelFileFields.input_file_size_bytes}`]: data.inputFileSizeBytes,\n [`${ModelFileFields.input_type}`]: data.inputType,\n [`${ModelFileFields.refer_id_1}`]: data.referId1,\n [`${ModelFileFields.refer_id_2}`]: data.referId2,\n [`${ModelFileFields.refer_label_1}`]: data.referLabel1,\n [`${ModelFileFields.refer_label_2}`]: data.referLabel2,\n [`${ModelFileFields.remark}`]: data.remark,\n [`${ModelFileFields.storage_provider_name}`]: data.storageProviderName,\n }\n\n}\n\nexport const compressImageBuffer = async (\n buffer: Buffer,\n mimeType: string,\n options: FileImageCompressionOptions = {}\n): Promise<{\n compressFormat: string;\n buffer: Buffer;\n sizeBytes: number;\n}> => {\n\n const { maxWidth = 1024, quality = 80 } = options;\n\n const SUPPORTED_IMAGE_MIMES = [\n \"image/jpeg\",\n \"image/png\",\n \"image/webp\",\n \"image/tiff\",\n \"image/bmp\",\n ];\n\n // Skip unsupported images\n if (!SUPPORTED_IMAGE_MIMES.includes(mimeType)) {\n return { compressFormat: '', buffer, sizeBytes: buffer.byteLength };\n }\n\n let pipeline = sharp(buffer);\n\n if (maxWidth) {\n pipeline = pipeline.resize({ width: maxWidth });\n }\n\n let compressedBuffer: Buffer;\n\n switch (mimeType) {\n case \"image/png\":\n compressedBuffer = await pipeline.png({ quality }).toBuffer();\n break;\n case \"image/webp\":\n compressedBuffer = await pipeline.webp({ quality }).toBuffer();\n break;\n case \"image/jpeg\":\n case \"image/tiff\":\n case \"image/bmp\":\n default:\n compressedBuffer = await pipeline.jpeg({ quality }).toBuffer();\n break;\n }\n\n return {\n compressFormat: JSON.stringify(options),\n buffer: compressedBuffer,\n sizeBytes: compressedBuffer.byteLength\n };\n\n};\n\nexport const FileService = (props: FileServiceProps) => {\n\n const {\n prisma,\n accountId = 0,\n actionUserId = 0,\n } = props\n\n const fileModel = FileModel({ prisma, accountId, actionUserId })\n\n const fileGoogleCloudStorageProvider = FileGoogleCloudStorageProvider({\n basePath: ``,\n bucketName: ``\n })\n\n const fileLocalStorageProvider = FileLocalStorageProvider({})\n\n const initBatchCode = () => {\n return `${Date.now()}_${_.random(0, 999)}`;\n }\n\n const uploadFiles = async ({\n field_ref = \"item\",\n field_module = \"item\",\n tagName,\n label,\n refId,\n refId2,\n refLabel,\n refLabel2,\n remark,\n description,\n foldernameDate,\n storageProviderName = \"local\",\n storageProviderOptions,\n files = [],\n imageCompressionOptions\n }: FileUploadProps) => {\n\n // get the correct provider\n const provider = getFileStorageProvider(storageProviderName, storageProviderOptions);\n\n const allResponses = []\n\n const batchCode = initBatchCode();\n\n const fileLabel = label ?? \"\"\n const referId1 = refId ?? 0\n const referId2 = refId2 ?? 0\n const referLabel1 = refLabel ?? \"\"\n const referLabel2 = refLabel2 ?? \"\"\n const fileRemark = remark ?? \"\"\n\n for (const file of files) {\n\n let bufferToUpload = file.buffer;\n let mimeType = file.mimeType ?? \"\"\n let sizeBytes = file?.sizeBytes\n let fileOriginalName = file.originalName;\n\n let outputSizeBytes = sizeBytes // output file size\n let fileCompressFormat = `` // output image compress\n\n // const ext = file.originalName?.split(\".\").pop()?.toLowerCase() ?? \"\";\n\n // Only compress if image and options provided\n if (imageCompressionOptions) {\n const compressed = await compressImageBuffer(\n bufferToUpload,\n mimeType,\n imageCompressionOptions\n );\n\n fileCompressFormat = compressed.compressFormat,\n bufferToUpload = compressed.buffer;\n outputSizeBytes = compressed.sizeBytes; // update the file size\n }\n\n // upload using the provider - buffer\n const uploadResult = await provider.uploadFile({\n field_ref,\n field_module,\n buffer: bufferToUpload,\n ...(foldernameDate ? { foldernameDate } : {}),\n mimeType,\n fileName: fileOriginalName\n } as FileModuleRef & { buffer: Buffer; mimeType: string; fileName: string });\n\n const fieldRef = field_ref\n const fieldModule = field_module\n\n const fileName = uploadResult?.filename ?? \"\"\n const contentType = mimeType ?? \"\"\n const folderPath = uploadResult.assetPath ?? \"\"\n const assetUrl = uploadResult.assetUrl ?? \"\"\n const assetPath = uploadResult.assetPath ?? \"\"\n\n const inputType = `buffer`\n const inputFileSizeBytes = sizeBytes ?? 0\n const inputFileName = fileOriginalName ?? \"\"\n\n const fileSizeBytes = outputSizeBytes ?? 0\n // const fileCompressFormat = ``\n\n const foldernameDay = uploadResult?.folderName?.day ?? \"\"\n const foldernameMonth = uploadResult?.folderName?.month ?? \"\"\n const foldernameYear = uploadResult?.folderName?.year ?? \"\"\n\n const payload: FileCreateProps = {\n data: {\n fieldRef,\n fieldModule,\n tagName,\n description,\n remark: fileRemark,\n folderPath,\n assetUrl,\n assetPath,\n fileLabel,\n fileName,\n contentType,\n inputType,\n inputFileSizeBytes,\n inputFileName,\n fileSizeBytes,\n fileCompressFormat,\n storageProviderName,\n foldernameDay,\n foldernameMonth,\n foldernameYear,\n batchCode,\n referId1,\n referId2,\n referLabel1,\n referLabel2\n } as FileCreateProps[\"data\"],\n };\n\n let response = await createFile(payload);\n\n allResponses.push(response)\n }\n\n return allResponses\n\n }\n\n // private\n const createFile = async ({ data }: FileCreateProps) => {\n\n const _data = getCreatePayload(data)\n\n if (!_data) {\n throw new Error(`Invalid create file payload: ${JSON.stringify(_data)}`);\n }\n\n const response = await fileModel.create({ data: _data })\n\n const newFileId = response?.file_id ?? \"\"\n\n return newFileId ? await getFile({ id: Number(newFileId) }) : null\n\n }\n\n // const updateFile = async ({ documentId, data }: FileUpdateProps) => {\n\n // return await getFile({ id: documentId })\n // }\n\n const getFile = async ({ id }: FileGetProps) => {\n\n let { data } = await listFiles({\n limit: 1,\n offset: 0,\n filters: [{ field: `${ModelFileFields.file_id}`, operator: \"=\", value: id }],\n sortfield: `${ModelFileFields.file_id}`,\n sortorder: \"ASC\"\n })\n\n return data[0] ?? null;\n\n };\n\n const listFiles = async ({\n limit,\n offset,\n filters,\n sortfield,\n sortorder,\n }: FileListProps) => {\n\n let sqlSelect: string[] = []\n let sqlRelation: string[] = []\n let sqlGroupBy: string[] = []\n\n let sqlSelectAgg: string[] = []\n let sqlRelationAgg: string[] = []\n\n sqlSelect = [\n buildSqlSelect(``, mainSqlSelect),\n buildSqlSelect(``, defaultSqlSelect)\n ]\n\n sqlRelation = [\n sqlRelationMaps.creator,\n sqlRelationMaps.updater\n ]\n\n // sqlRelationAgg = []\n\n sqlGroupBy = [\n ...Object.keys(mainSqlSelect),\n ...Object.keys(defaultSqlSelect)\n ]\n\n let filterColumns = {\n ...mainSqlSelect,\n ...defaultSqlSelect\n }\n\n let sqlWhere = [\n `mainfile.isdelete = false`,\n `mainfile.istrash = false`,\n // `LOWER(mainfile.doc_type) = LOWER('${documentTypeKey}')`\n ]\n\n let sqlOrderby = buildSqlOrderBy(sortfield, sortorder)\n let sqlLimitOffset = buildSqlLimitOffset(limit, offset)\n\n // get the listing data & count\n const { data, total } = await getListWithCount({\n model: fileModel,\n tableName: \"files\",\n mainAlias: \"mainfile\",\n countKey: `${ModelFileFields.file_id}`,\n accountId,\n sqlRelationMaps,\n filters,\n filterColumns,\n sqlSelect,\n sqlSelectAgg,\n sqlRelation,\n sqlRelationAgg,\n sqlWhere,\n sqlGroupBy,\n sqlOrderby,\n sqlLimitOffset\n })\n\n const response = {\n data,\n total\n }\n\n return response\n\n };\n\n\n const removeFiles = async ({ fileIds, storageProviderOptions }: FileRemoveProps) => {\n\n if (!fileIds.length) throwError('fileIds is required');\n\n const filesToDelete = await fileModel.list({\n where: {\n file_id: { in: fileIds }\n }\n });\n\n // console.log('filesToDelete', filesToDelete)\n\n // 2️⃣ Delete the physical files\n for (const file of filesToDelete) {\n\n // check the provider to choose delete method\n const storageProviderName = file.storage_provider_name as FileStorageProviderType\n const assetUrl = file.asset_url\n const assetPath = file.asset_path\n\n if (storageProviderName === \"local\" && assetPath) {\n\n try {\n let res = fileLocalStorageProvider.removeFile(assetPath)\n } catch (err) {\n console.error(`Failed to delete from GCloud: ${assetUrl}`, err);\n }\n\n }\n\n if (storageProviderName === \"gcloud\" && assetUrl) {\n\n try {\n let res = fileGoogleCloudStorageProvider.removeFile(assetUrl, storageProviderOptions.credentials)\n } catch (err) {\n console.error(`Failed to delete from GCloud: ${assetUrl}`, err);\n }\n\n }\n\n }\n\n // remove files\n const response = await fileModel.remove({ where: { [`${ModelFileFields.file_id}`]: { in: fileIds } } });\n\n return response\n };\n\n // const getDataTypes = () => {\n // return Object.values(fileDataTypes);\n // }\n\n return {\n uploadFiles,\n // createFile,\n // updateFile,\n getFile,\n listFiles,\n removeFiles,\n // getDataTypes\n }\n\n}\n\n"]}
@@ -24,6 +24,7 @@ declare const FileStorageProviderRegistry: {
24
24
  foldernameDate?: string;
25
25
  fileName: string;
26
26
  }) => Promise<FileStorageProviderResult>;
27
+ removeFile: (assetPath: string) => Promise<void>;
27
28
  };
28
29
  gcloud: (options: FileGoogleCloudProviderOptions) => {
29
30
  uploadFile: <T extends import("./FileService").FileModuleRef>({ field_ref, field_module, buffer, mimeType, foldernameDate, fileName, }: T & {
@@ -32,6 +33,7 @@ declare const FileStorageProviderRegistry: {
32
33
  foldernameDate?: string;
33
34
  fileName: string;
34
35
  }) => Promise<FileStorageProviderResult>;
36
+ removeFile: (assetUrl: string, credentials: any) => Promise<[import("teeny-request").Response<any>]>;
35
37
  };
36
38
  };
37
39
  export declare const getFileStorageProvider: <T extends FileStorageProviderType>(provider: T, options?: FileStorageProviderOptionsMap[T]) => {
@@ -41,5 +43,14 @@ export declare const getFileStorageProvider: <T extends FileStorageProviderType>
41
43
  foldernameDate?: string;
42
44
  fileName: string;
43
45
  }) => Promise<FileStorageProviderResult>;
46
+ removeFile: (assetUrl: string, credentials: any) => Promise<[import("teeny-request").Response<any>]>;
47
+ } | {
48
+ uploadFile: <T_1 extends import("./FileService").FileModuleRef>({ field_ref, field_module, buffer, mimeType, foldernameDate, fileName, }: T_1 & {
49
+ buffer: Buffer;
50
+ mimeType: string;
51
+ foldernameDate?: string;
52
+ fileName: string;
53
+ }) => Promise<FileStorageProviderResult>;
54
+ removeFile: (assetPath: string) => Promise<void>;
44
55
  };
45
56
  export { FileStorageProviderRegistry };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storemw-core-api",
3
- "version": "1.0.41",
3
+ "version": "1.0.42",
4
4
  "description": "STOREMW Core API",
5
5
  "main": "dist/app.js",
6
6
  "types": "dist/app.d.ts",