@lyxa.ai/core 1.1.105 → 1.1.107

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.
@@ -10,6 +10,7 @@ const moment_1 = __importDefault(require("moment"));
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const index_1 = require("../../index");
12
12
  const mime_types_1 = __importDefault(require("mime-types"));
13
+ const file_type_1 = __importDefault(require("file-type"));
13
14
  function makeSlug(input) {
14
15
  return input
15
16
  .toLowerCase()
@@ -35,43 +36,59 @@ class UploadService {
35
36
  return baseName + newExtension;
36
37
  }
37
38
  async uploadImage(buffer, originalFilename) {
38
- const newFilename = this.generateFilename(originalFilename);
39
- const extension = path_1.default.extname(newFilename).toLowerCase();
40
- let processedImage;
41
- let contentType;
42
- if (extension === '.png') {
43
- processedImage = (0, sharp_1.default)(buffer).png({ quality: 80 });
44
- contentType = 'image/png';
45
- }
46
- else if (extension === '.webp') {
47
- processedImage = (0, sharp_1.default)(buffer).webp({ quality: 80 });
48
- contentType = 'image/webp';
49
- }
50
- else {
51
- processedImage = (0, sharp_1.default)(buffer).jpeg({ quality: 80 });
52
- contentType = 'image/jpeg';
53
- }
54
- const file = this.bucket.file(newFilename);
55
- return new Promise((resolve, reject) => {
56
- const blobStream = file.createWriteStream({
57
- resumable: false,
58
- contentType,
59
- });
60
- blobStream.on('error', (err) => {
61
- reject(err);
62
- });
63
- blobStream.on('finish', async () => {
64
- try {
65
- await file.makePublic();
66
- const publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;
67
- resolve({ filename: file.name, url: publicUrl });
68
- }
69
- catch (err) {
39
+ let fileType;
40
+ try {
41
+ fileType = (await file_type_1.default.fileTypeFromBuffer(buffer))?.ext;
42
+ if (!fileType)
43
+ throw new Error('Unable to detect image type');
44
+ const newFilename = this.generateFilename(originalFilename);
45
+ const extension = path_1.default.extname(newFilename).toLowerCase();
46
+ let processedImage;
47
+ let contentType;
48
+ if (extension === '.png') {
49
+ processedImage = (0, sharp_1.default)(buffer).png({ quality: 80 });
50
+ contentType = 'image/png';
51
+ }
52
+ else if (extension === '.webp') {
53
+ processedImage = (0, sharp_1.default)(buffer).webp({ quality: 80 });
54
+ contentType = 'image/webp';
55
+ }
56
+ else {
57
+ processedImage = (0, sharp_1.default)(buffer).jpeg({ quality: 80 });
58
+ contentType = 'image/jpeg';
59
+ }
60
+ const file = this.bucket.file(newFilename);
61
+ return await new Promise((resolve, reject) => {
62
+ const blobStream = file.createWriteStream({
63
+ resumable: false,
64
+ contentType,
65
+ });
66
+ processedImage.on('error', (err) => {
70
67
  reject(err);
71
- }
68
+ });
69
+ blobStream.on('error', (err) => {
70
+ reject(err);
71
+ });
72
+ blobStream.on('finish', async () => {
73
+ try {
74
+ await file.makePublic();
75
+ const publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;
76
+ resolve({ filename: file.name, url: publicUrl });
77
+ }
78
+ catch (err) {
79
+ reject(err);
80
+ }
81
+ });
82
+ processedImage.pipe(blobStream);
72
83
  });
73
- processedImage.pipe(blobStream);
74
- });
84
+ }
85
+ catch (err) {
86
+ console.error('Image upload failed:', err);
87
+ if (fileType) {
88
+ throw new Error(`${fileType.toUpperCase()} format not supported. Please use JPEG, PNG, or WebP format instead.`);
89
+ }
90
+ throw new Error(`Image upload failed: ${err.message}`);
91
+ }
75
92
  }
76
93
  async transcodeImage(buffer, originalFilename, resolutions) {
77
94
  const extension = path_1.default.extname(originalFilename);
@@ -209,39 +226,51 @@ class UploadService {
209
226
  });
210
227
  }
211
228
  async uploadProcessedImageToWebp(buffer, originalFilename, options) {
212
- const newFilename = this.generateFilename(originalFilename, '.webp');
213
- let width = options?.width;
214
- let height = options?.height;
215
- const quality = options?.quality ?? 80;
216
- if (!width || !height) {
217
- const imageMetadata = await (0, sharp_1.default)(buffer).metadata();
218
- width = width || imageMetadata.width;
219
- height = height || imageMetadata.height;
220
- }
221
- const processedImage = (0, sharp_1.default)(buffer)
222
- .resize(width, height, { fit: 'inside' })
223
- .webp({ quality });
224
- const file = this.bucket.file(newFilename);
225
- return new Promise((resolve, reject) => {
226
- const blobStream = file.createWriteStream({
227
- resumable: false,
228
- contentType: 'image/webp',
229
- });
230
- blobStream.on('error', (err) => {
231
- reject(err);
232
- });
233
- blobStream.on('finish', async () => {
234
- try {
235
- await file.makePublic();
236
- const publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;
237
- resolve({ filename: file.name, url: publicUrl });
238
- }
239
- catch (err) {
229
+ let fileType;
230
+ try {
231
+ const newFilename = this.generateFilename(originalFilename, '.webp');
232
+ const quality = options?.quality ?? 80;
233
+ fileType = (await file_type_1.default.fileTypeFromBuffer(buffer))?.ext;
234
+ if (!fileType)
235
+ throw new Error('Unable to detect image type');
236
+ const metadata = await (0, sharp_1.default)(buffer).metadata();
237
+ const width = options?.width || metadata.width;
238
+ const height = options?.height || metadata.height;
239
+ const processedImage = (0, sharp_1.default)(buffer)
240
+ .resize(width, height, { fit: 'inside' })
241
+ .webp({ quality });
242
+ const file = this.bucket.file(newFilename);
243
+ return await new Promise((resolve, reject) => {
244
+ const blobStream = file.createWriteStream({
245
+ resumable: false,
246
+ contentType: 'image/webp',
247
+ });
248
+ processedImage.on('error', (err) => {
240
249
  reject(err);
241
- }
250
+ });
251
+ blobStream.on('error', (err) => {
252
+ reject(err);
253
+ });
254
+ blobStream.on('finish', async () => {
255
+ try {
256
+ await file.makePublic();
257
+ const publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;
258
+ resolve({ filename: file.name, url: publicUrl });
259
+ }
260
+ catch (err) {
261
+ reject(err);
262
+ }
263
+ });
264
+ processedImage.pipe(blobStream);
242
265
  });
243
- processedImage.pipe(blobStream);
244
- });
266
+ }
267
+ catch (err) {
268
+ console.error('Processed image upload failed:', err);
269
+ if (fileType) {
270
+ throw new Error(`${fileType.toUpperCase()} format not supported. Please use JPEG, PNG, or WebP format instead.`);
271
+ }
272
+ throw new Error(`Processed image upload failed: ${err.message}`);
273
+ }
245
274
  }
246
275
  async uploadFile(buffer, originalFilename, options) {
247
276
  const newFilename = options?.withOriginalFilename
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/upload/index.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport sharp from 'sharp';\nimport moment from 'moment';\nimport path from 'path';\nimport { getLibraries } from '../../index';\nimport mime from 'mime-types';\n\nfunction makeSlug(input: string): string {\n\treturn input\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/(^-|-$)/g, '');\n}\n\nexport class UploadService {\n\tprivate bucket;\n\tprivate readonly websiteName;\n\n\tconstructor(bucketName?: string) {\n\t\tif (!bucketName) {\n\t\t\tbucketName = 'lyxa-global';\n\t\t}\n\n\t\tthis.bucket = getLibraries().getFirebaseService().superApp.storage().bucket(bucketName);\n\t\tthis.websiteName = 'lyxa-' + getLibraries().getConfigurationService().options.tenet;\n\t}\n\n\t/**\n\t * Generates a unique filename using the original filename.\n\t */\n\tprivate generateFilename(originalFilename: string, extension?: string): string {\n\t\tconst nameWithoutExt = path.parse(originalFilename).name;\n\t\tconst newExtension = extension || path.extname(originalFilename);\n\t\tconst timestamp = moment().format('DDMMYYHmmss');\n\t\tconst randomId = Math.floor(Math.random() * 100);\n\t\tconst baseName = `${makeSlug(nameWithoutExt)}-${this.websiteName}-${timestamp}-${randomId}`;\n\t\treturn baseName + newExtension;\n\t}\n\n\t/**\n\t * Uploads an image buffer after processing it with Sharp.\n\t * An optional destinationPath can be provided (e.g., 'images/product.jpg').\n\t */\n\tasync uploadImage(buffer: Buffer, originalFilename: string): Promise<{ filename: string; url: string }> {\n\t\tconst newFilename = this.generateFilename(originalFilename);\n\t\tconst extension = path.extname(newFilename).toLowerCase();\n\t\tlet processedImage: sharp.Sharp;\n\t\tlet contentType: string;\n\t\tif (extension === '.png') {\n\t\t\tprocessedImage = sharp(buffer).png({ quality: 80 });\n\t\t\tcontentType = 'image/png';\n\t\t} else if (extension === '.webp') {\n\t\t\tprocessedImage = sharp(buffer).webp({ quality: 80 });\n\t\t\tcontentType = 'image/webp';\n\t\t} else {\n\t\t\tprocessedImage = sharp(buffer).jpeg({ quality: 80 });\n\t\t\tcontentType = 'image/jpeg';\n\t\t}\n\n\t\tconst file = this.bucket.file(newFilename);\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst blobStream = file.createWriteStream({\n\t\t\t\tresumable: false,\n\t\t\t\tcontentType,\n\t\t\t});\n\n\t\t\tblobStream.on('error', (err: Error) => {\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tblobStream.on('finish', async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait file.makePublic();\n\t\t\t\t\tconst publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t\t\t\t\tresolve({ filename: file.name, url: publicUrl });\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tprocessedImage.pipe(blobStream);\n\t\t});\n\t}\n\n\t/**\n\t * Transcodes (resizes) an image buffer into multiple resolutions.\n\t * An optional destinationPrefix can be provided to force a specific path or filename base.\n\t *\n\t * For example, if destinationPrefix is 'images/product', then the original might be\n\t * uploaded as 'images/product.jpg' and the resized versions as 'images/product-480.jpg', etc.\n\t */\n\tasync transcodeImage(\n\t\tbuffer: Buffer,\n\t\toriginalFilename: string,\n\t\tresolutions: number[]\n\t): Promise<{\n\t\toriginalUrl: string;\n\t\tresizedResults: Array<{ resolution: number; url: string }>;\n\t}> {\n\t\tconst extension = path.extname(originalFilename);\n\t\tconst contentType = `image/${extension.replace('.', '') || 'jpeg'}`;\n\t\tconst timestamp = moment().format('DDMMYYHmmss');\n\t\tconst randomId = Math.floor(Math.random() * 100);\n\n\t\tconst baseFilename = `${makeSlug(path.parse(originalFilename).name)}-${this.websiteName}-${timestamp}-${randomId}`;\n\n\t\tconst originalFileName = `${baseFilename}${extension}`;\n\t\tconst originalUrl = await this.uploadBuffer(buffer, originalFileName, contentType);\n\n\t\tconst metadata = await sharp(buffer).metadata();\n\t\tconst isLandscape = metadata.width && metadata.height ? metadata.width > metadata.height : true;\n\n\t\tconst resizedResults = await Promise.all(\n\t\t\tresolutions.map(async resolution => {\n\t\t\t\tconst resizeOptions = isLandscape ? { width: resolution } : { height: resolution };\n\t\t\t\tconst formatKey = (extension.replace('.', '') || 'jpeg') as keyof sharp.FormatEnum;\n\t\t\t\tconst resizedBuffer = await sharp(buffer)\n\t\t\t\t\t.resize({\n\t\t\t\t\t\t...resizeOptions,\n\t\t\t\t\t\twithoutEnlargement: true,\n\t\t\t\t\t})\n\t\t\t\t\t.toFormat(formatKey, { quality: 80 })\n\t\t\t\t\t.toBuffer();\n\t\t\t\tconst resizedFilename = `${baseFilename}-${resolution}${extension}`;\n\t\t\t\tconst resizedUrl = await this.uploadBuffer(resizedBuffer, resizedFilename, contentType);\n\t\t\t\treturn { resolution, url: resizedUrl };\n\t\t\t})\n\t\t);\n\n\t\treturn { originalUrl, resizedResults };\n\t}\n\n\t/**\n\t * Helper function to upload a buffer to a specified filename.\n\t */\n\tprivate async uploadBuffer(buffer: Buffer, filename: string, contentType: string): Promise<string> {\n\t\tconst file = this.bucket.file(filename);\n\t\tawait file.save(buffer, {\n\t\t\tresumable: false,\n\t\t\tcontentType,\n\t\t});\n\t\tawait file.makePublic();\n\t\treturn `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t}\n\n\tasync getListFiles(): Promise<Array<{ name: string; url: string }>> {\n\t\tconst [files] = await this.bucket.getFiles();\n\t\treturn files.map(file => ({\n\t\t\tname: file.name!,\n\t\t\turl: file.metadata.mediaLink!,\n\t\t}));\n\t}\n\n\tasync downloadFile(filename: string): Promise<Buffer> {\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [buffer] = await file.download();\n\t\treturn buffer;\n\t}\n\n\tasync deleteFile(filename: string): Promise<void> {\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [exists] = await file.exists();\n\t\tif (!exists) {\n\t\t\tthrow new Error('File does not exist.');\n\t\t}\n\t\tawait file.delete();\n\t}\n\n\tasync getPublicUrlFromFilename(filename: string): Promise<{ status: boolean; url: string }> {\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [exists] = await file.exists();\n\n\t\tif (!exists) {\n\t\t\treturn { status: false, url: '' };\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: true,\n\t\t\turl: `https://storage.googleapis.com/${this.bucket.name}/${filename}`,\n\t\t};\n\t}\n\n\tpublic extractFilenameFromUrl(url: string): string {\n\t\ttry {\n\t\t\tconst urlObj = new URL(url);\n\t\t\tconst pathParts = urlObj.pathname.split('/');\n\t\t\treturn decodeURIComponent(pathParts[pathParts.length - 1]);\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Invalid URL: ${url}`);\n\t\t}\n\t}\n\n\tasync deleteFileByUrl(url: string): Promise<void> {\n\t\tconst filename = this.extractFilenameFromUrl(url);\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [exists] = await file.exists();\n\t\tif (!exists) {\n\t\t\tthrow new Error('File does not exist.');\n\t\t}\n\t\tawait file.delete();\n\t}\n\n\tasync downloadImage(url: string): Promise<Buffer> {\n\t\ttry {\n\t\t\tconst response = await axios.get(url, { responseType: 'arraybuffer' });\n\t\t\treturn Buffer.from(response.data, 'binary');\n\t\t} catch (error: any) {\n\t\t\tif (axios.isAxiosError(error)) {\n\t\t\t\tconst status = error.response?.status;\n\t\t\t\tlet reason = 'Image download failed';\n\n\t\t\t\tif (status === 403) {\n\t\t\t\t\treason = 'Image URL is not valid or access forbidden (403)';\n\t\t\t\t} else if (status === 404) {\n\t\t\t\t\treason = 'Image not found (404)';\n\t\t\t\t} else if (status === 429) {\n\t\t\t\t\treason = 'Too many requests (429) — rate limited by server';\n\t\t\t\t} else if (status) {\n\t\t\t\t\treason = `Image download failed with status ${status}`;\n\t\t\t\t} else {\n\t\t\t\t\treason = `Network or unknown error: ${error.message}`;\n\t\t\t\t}\n\n\t\t\t\tthrow new Error(reason);\n\t\t\t}\n\n\t\t\t// Non-Axios error (timeout, DNS, etc.)\n\t\t\tthrow new Error(`Unexpected error downloading image: ${error.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Uploads a buffer to Google Cloud Storage and makes it public\n\t */\n\tprivate async uploadToGCS(\n\t\tbuffer: Buffer,\n\t\tfilename: string,\n\t\tcontentType: string\n\t): Promise<{ filename: string; url: string }> {\n\t\tconst file = this.bucket.file(filename);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Create a write stream to upload the file\n\t\t\tconst blobStream = file.createWriteStream({\n\t\t\t\tresumable: false,\n\t\t\t\tcontentType,\n\t\t\t});\n\n\t\t\tblobStream.on('error', reject);\n\n\t\t\tblobStream.on('finish', async () => {\n\t\t\t\ttry {\n\t\t\t\t\t// Make the file publicly accessible\n\t\t\t\t\tawait file.makePublic();\n\t\t\t\t\tconst publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t\t\t\t\tresolve({ filename: file.name, url: publicUrl });\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Start uploading the buffer\n\t\t\tblobStream.end(buffer);\n\t\t});\n\t}\n\n\t/**\n\t * Uploads and converts an image to WebP format, resizes if needed, and uploads to GCS\n\t */\n\tasync uploadProcessedImageToWebp(\n\t\tbuffer: Buffer,\n\t\toriginalFilename: string,\n\t\toptions?: { quality?: number; width?: number; height?: number }\n\t): Promise<{ filename: string; url: string }> {\n\t\tconst newFilename = this.generateFilename(originalFilename, '.webp');\n\n\t\tlet width = options?.width;\n\t\tlet height = options?.height;\n\t\tconst quality = options?.quality ?? 80;\n\n\t\t// Get original image dimensions if width or height is missing\n\t\tif (!width || !height) {\n\t\t\tconst imageMetadata = await sharp(buffer).metadata();\n\t\t\twidth = width || imageMetadata.width;\n\t\t\theight = height || imageMetadata.height;\n\t\t}\n\n\t\t// Convert to WebP and resize\n\t\tconst processedImage: sharp.Sharp = sharp(buffer)\n\t\t\t.resize(width, height, { fit: 'inside' })\n\t\t\t.webp({ quality });\n\n\t\tconst file = this.bucket.file(newFilename);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst blobStream = file.createWriteStream({\n\t\t\t\tresumable: false,\n\t\t\t\tcontentType: 'image/webp',\n\t\t\t});\n\n\t\t\tblobStream.on('error', (err: Error) => {\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tblobStream.on('finish', async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait file.makePublic();\n\t\t\t\t\tconst publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t\t\t\t\tresolve({ filename: file.name, url: publicUrl });\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tprocessedImage.pipe(blobStream);\n\t\t});\n\t}\n\n\t/**\n\t * Uploads any supported file type to GCS and returns its public URL\n\t */\n\tasync uploadFile(\n\t\tbuffer: Buffer,\n\t\toriginalFilename: string,\n\t\toptions?: {\n\t\t\tquality?: number;\n\t\t\twidth?: number;\n\t\t\theight?: number;\n\t\t\twithExtension?: boolean;\n\t\t\twithOriginalFilename?: boolean;\n\t\t}\n\t): Promise<{ filename: string; url: string }> {\n\t\tconst newFilename = options?.withOriginalFilename\n\t\t\t? originalFilename\n\t\t\t: this.generateFilename(originalFilename);\n\t\tconst extension = path.extname(newFilename).toLowerCase();\n\n\t\t// Guess the MIME type using the mime-types library\n\t\tconst contentType = mime.lookup(extension) || 'application/octet-stream';\n\n\t\t// Special image handling (compression)\n\t\tif (contentType.startsWith('image/')) {\n\t\t\tif (options?.withExtension) {\n\t\t\t\treturn this.uploadImage(buffer, originalFilename);\n\t\t\t} else {\n\t\t\t\treturn this.uploadProcessedImageToWebp(buffer, originalFilename, options);\n\t\t\t}\n\t\t}\n\n\t\treturn this.uploadToGCS(buffer, newFilename, contentType);\n\t}\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"/","sources":["libraries/upload/index.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport sharp from 'sharp';\nimport moment from 'moment';\nimport path from 'path';\nimport { getLibraries } from '../../index';\nimport mime from 'mime-types';\nimport FileType from 'file-type';\n\nfunction makeSlug(input: string): string {\n\treturn input\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, '-')\n\t\t.replace(/(^-|-$)/g, '');\n}\n\nexport class UploadService {\n\tprivate bucket;\n\tprivate readonly websiteName;\n\n\tconstructor(bucketName?: string) {\n\t\tif (!bucketName) {\n\t\t\tbucketName = 'lyxa-global';\n\t\t}\n\n\t\tthis.bucket = getLibraries().getFirebaseService().superApp.storage().bucket(bucketName);\n\t\tthis.websiteName = 'lyxa-' + getLibraries().getConfigurationService().options.tenet;\n\t}\n\n\t/**\n\t * Generates a unique filename using the original filename.\n\t */\n\tprivate generateFilename(originalFilename: string, extension?: string): string {\n\t\tconst nameWithoutExt = path.parse(originalFilename).name;\n\t\tconst newExtension = extension || path.extname(originalFilename);\n\t\tconst timestamp = moment().format('DDMMYYHmmss');\n\t\tconst randomId = Math.floor(Math.random() * 100);\n\t\tconst baseName = `${makeSlug(nameWithoutExt)}-${this.websiteName}-${timestamp}-${randomId}`;\n\t\treturn baseName + newExtension;\n\t}\n\n\t/**\n\t * Uploads an image buffer after processing it with Sharp.\n\t * An optional destinationPath can be provided (e.g., 'images/product.jpg').\n\t */\n\tasync uploadImage(buffer: Buffer, originalFilename: string): Promise<{ filename: string; url: string }> {\n\t\tlet fileType: string | undefined;\n\n\t\ttry {\n\t\t\t// Detect actual file type\n\t\t\tfileType = (await FileType.fileTypeFromBuffer(buffer))?.ext;\n\t\t\tif (!fileType) throw new Error('Unable to detect image type');\n\n\t\t\tconst newFilename = this.generateFilename(originalFilename);\n\t\t\tconst extension = path.extname(newFilename).toLowerCase();\n\t\t\tlet processedImage: sharp.Sharp;\n\t\t\tlet contentType: string;\n\t\t\tif (extension === '.png') {\n\t\t\t\tprocessedImage = sharp(buffer).png({ quality: 80 });\n\t\t\t\tcontentType = 'image/png';\n\t\t\t} else if (extension === '.webp') {\n\t\t\t\tprocessedImage = sharp(buffer).webp({ quality: 80 });\n\t\t\t\tcontentType = 'image/webp';\n\t\t\t} else {\n\t\t\t\tprocessedImage = sharp(buffer).jpeg({ quality: 80 });\n\t\t\t\tcontentType = 'image/jpeg';\n\t\t\t}\n\n\t\t\tconst file = this.bucket.file(newFilename);\n\t\t\treturn await new Promise((resolve, reject) => {\n\t\t\t\tconst blobStream = file.createWriteStream({\n\t\t\t\t\tresumable: false,\n\t\t\t\t\tcontentType,\n\t\t\t\t});\n\n\t\t\t\tprocessedImage.on('error', (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\n\t\t\t\tblobStream.on('error', (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\n\t\t\t\tblobStream.on('finish', async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait file.makePublic();\n\t\t\t\t\t\tconst publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t\t\t\t\t\tresolve({ filename: file.name, url: publicUrl });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tprocessedImage.pipe(blobStream);\n\t\t\t});\n\t\t} catch (err: any) {\n\t\t\tconsole.error('Image upload failed:', err);\n\t\t\tif (fileType) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${fileType.toUpperCase()} format not supported. Please use JPEG, PNG, or WebP format instead.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(`Image upload failed: ${err.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Transcodes (resizes) an image buffer into multiple resolutions.\n\t * An optional destinationPrefix can be provided to force a specific path or filename base.\n\t *\n\t * For example, if destinationPrefix is 'images/product', then the original might be\n\t * uploaded as 'images/product.jpg' and the resized versions as 'images/product-480.jpg', etc.\n\t */\n\tasync transcodeImage(\n\t\tbuffer: Buffer,\n\t\toriginalFilename: string,\n\t\tresolutions: number[]\n\t): Promise<{\n\t\toriginalUrl: string;\n\t\tresizedResults: Array<{ resolution: number; url: string }>;\n\t}> {\n\t\tconst extension = path.extname(originalFilename);\n\t\tconst contentType = `image/${extension.replace('.', '') || 'jpeg'}`;\n\t\tconst timestamp = moment().format('DDMMYYHmmss');\n\t\tconst randomId = Math.floor(Math.random() * 100);\n\n\t\tconst baseFilename = `${makeSlug(path.parse(originalFilename).name)}-${this.websiteName}-${timestamp}-${randomId}`;\n\n\t\tconst originalFileName = `${baseFilename}${extension}`;\n\t\tconst originalUrl = await this.uploadBuffer(buffer, originalFileName, contentType);\n\n\t\tconst metadata = await sharp(buffer).metadata();\n\t\tconst isLandscape = metadata.width && metadata.height ? metadata.width > metadata.height : true;\n\n\t\tconst resizedResults = await Promise.all(\n\t\t\tresolutions.map(async resolution => {\n\t\t\t\tconst resizeOptions = isLandscape ? { width: resolution } : { height: resolution };\n\t\t\t\tconst formatKey = (extension.replace('.', '') || 'jpeg') as keyof sharp.FormatEnum;\n\t\t\t\tconst resizedBuffer = await sharp(buffer)\n\t\t\t\t\t.resize({\n\t\t\t\t\t\t...resizeOptions,\n\t\t\t\t\t\twithoutEnlargement: true,\n\t\t\t\t\t})\n\t\t\t\t\t.toFormat(formatKey, { quality: 80 })\n\t\t\t\t\t.toBuffer();\n\t\t\t\tconst resizedFilename = `${baseFilename}-${resolution}${extension}`;\n\t\t\t\tconst resizedUrl = await this.uploadBuffer(resizedBuffer, resizedFilename, contentType);\n\t\t\t\treturn { resolution, url: resizedUrl };\n\t\t\t})\n\t\t);\n\n\t\treturn { originalUrl, resizedResults };\n\t}\n\n\t/**\n\t * Helper function to upload a buffer to a specified filename.\n\t */\n\tprivate async uploadBuffer(buffer: Buffer, filename: string, contentType: string): Promise<string> {\n\t\tconst file = this.bucket.file(filename);\n\t\tawait file.save(buffer, {\n\t\t\tresumable: false,\n\t\t\tcontentType,\n\t\t});\n\t\tawait file.makePublic();\n\t\treturn `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t}\n\n\tasync getListFiles(): Promise<Array<{ name: string; url: string }>> {\n\t\tconst [files] = await this.bucket.getFiles();\n\t\treturn files.map(file => ({\n\t\t\tname: file.name!,\n\t\t\turl: file.metadata.mediaLink!,\n\t\t}));\n\t}\n\n\tasync downloadFile(filename: string): Promise<Buffer> {\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [buffer] = await file.download();\n\t\treturn buffer;\n\t}\n\n\tasync deleteFile(filename: string): Promise<void> {\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [exists] = await file.exists();\n\t\tif (!exists) {\n\t\t\tthrow new Error('File does not exist.');\n\t\t}\n\t\tawait file.delete();\n\t}\n\n\tasync getPublicUrlFromFilename(filename: string): Promise<{ status: boolean; url: string }> {\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [exists] = await file.exists();\n\n\t\tif (!exists) {\n\t\t\treturn { status: false, url: '' };\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: true,\n\t\t\turl: `https://storage.googleapis.com/${this.bucket.name}/${filename}`,\n\t\t};\n\t}\n\n\tpublic extractFilenameFromUrl(url: string): string {\n\t\ttry {\n\t\t\tconst urlObj = new URL(url);\n\t\t\tconst pathParts = urlObj.pathname.split('/');\n\t\t\treturn decodeURIComponent(pathParts[pathParts.length - 1]);\n\t\t} catch (err) {\n\t\t\tthrow new Error(`Invalid URL: ${url}`);\n\t\t}\n\t}\n\n\tasync deleteFileByUrl(url: string): Promise<void> {\n\t\tconst filename = this.extractFilenameFromUrl(url);\n\t\tconst file = this.bucket.file(filename);\n\t\tconst [exists] = await file.exists();\n\t\tif (!exists) {\n\t\t\tthrow new Error('File does not exist.');\n\t\t}\n\t\tawait file.delete();\n\t}\n\n\tasync downloadImage(url: string): Promise<Buffer> {\n\t\ttry {\n\t\t\tconst response = await axios.get(url, { responseType: 'arraybuffer' });\n\t\t\treturn Buffer.from(response.data, 'binary');\n\t\t} catch (error: any) {\n\t\t\tif (axios.isAxiosError(error)) {\n\t\t\t\tconst status = error.response?.status;\n\t\t\t\tlet reason = 'Image download failed';\n\n\t\t\t\tif (status === 403) {\n\t\t\t\t\treason = 'Image URL is not valid or access forbidden (403)';\n\t\t\t\t} else if (status === 404) {\n\t\t\t\t\treason = 'Image not found (404)';\n\t\t\t\t} else if (status === 429) {\n\t\t\t\t\treason = 'Too many requests (429) — rate limited by server';\n\t\t\t\t} else if (status) {\n\t\t\t\t\treason = `Image download failed with status ${status}`;\n\t\t\t\t} else {\n\t\t\t\t\treason = `Network or unknown error: ${error.message}`;\n\t\t\t\t}\n\n\t\t\t\tthrow new Error(reason);\n\t\t\t}\n\n\t\t\t// Non-Axios error (timeout, DNS, etc.)\n\t\t\tthrow new Error(`Unexpected error downloading image: ${error.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Uploads a buffer to Google Cloud Storage and makes it public\n\t */\n\tprivate async uploadToGCS(\n\t\tbuffer: Buffer,\n\t\tfilename: string,\n\t\tcontentType: string\n\t): Promise<{ filename: string; url: string }> {\n\t\tconst file = this.bucket.file(filename);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Create a write stream to upload the file\n\t\t\tconst blobStream = file.createWriteStream({\n\t\t\t\tresumable: false,\n\t\t\t\tcontentType,\n\t\t\t});\n\n\t\t\tblobStream.on('error', reject);\n\n\t\t\tblobStream.on('finish', async () => {\n\t\t\t\ttry {\n\t\t\t\t\t// Make the file publicly accessible\n\t\t\t\t\tawait file.makePublic();\n\t\t\t\t\tconst publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t\t\t\t\tresolve({ filename: file.name, url: publicUrl });\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Start uploading the buffer\n\t\t\tblobStream.end(buffer);\n\t\t});\n\t}\n\n\t/**\n\t * Uploads and converts an image to WebP format, resizes if needed, and uploads to GCS\n\t */\n\tasync uploadProcessedImageToWebp(\n\t\tbuffer: Buffer,\n\t\toriginalFilename: string,\n\t\toptions?: { quality?: number; width?: number; height?: number }\n\t): Promise<{ filename: string; url: string }> {\n\t\tlet fileType: string | undefined;\n\n\t\ttry {\n\t\t\tconst newFilename = this.generateFilename(originalFilename, '.webp');\n\t\t\tconst quality = options?.quality ?? 80;\n\n\t\t\t// Detect actual file type\n\t\t\tfileType = (await FileType.fileTypeFromBuffer(buffer))?.ext;\n\t\t\tif (!fileType) throw new Error('Unable to detect image type');\n\n\t\t\t// Get original image dimensions if width or height is missing\n\t\t\tconst metadata = await sharp(buffer).metadata();\n\t\t\tconst width = options?.width || metadata.width;\n\t\t\tconst height = options?.height || metadata.height;\n\n\t\t\t// Convert to WebP and resize\n\t\t\tconst processedImage: sharp.Sharp = sharp(buffer)\n\t\t\t\t.resize(width, height, { fit: 'inside' })\n\t\t\t\t.webp({ quality });\n\n\t\t\tconst file = this.bucket.file(newFilename);\n\n\t\t\treturn await new Promise((resolve, reject) => {\n\t\t\t\tconst blobStream = file.createWriteStream({\n\t\t\t\t\tresumable: false,\n\t\t\t\t\tcontentType: 'image/webp',\n\t\t\t\t});\n\n\t\t\t\tprocessedImage.on('error', (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\n\t\t\t\tblobStream.on('error', (err: Error) => {\n\t\t\t\t\treject(err);\n\t\t\t\t});\n\n\t\t\t\tblobStream.on('finish', async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait file.makePublic();\n\t\t\t\t\t\tconst publicUrl = `https://storage.googleapis.com/${this.bucket.name}/${file.name}`;\n\t\t\t\t\t\tresolve({ filename: file.name, url: publicUrl });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tprocessedImage.pipe(blobStream);\n\t\t\t});\n\t\t} catch (err: any) {\n\t\t\tconsole.error('Processed image upload failed:', err);\n\t\t\tif (fileType) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${fileType.toUpperCase()} format not supported. Please use JPEG, PNG, or WebP format instead.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(`Processed image upload failed: ${err.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Uploads any supported file type to GCS and returns its public URL\n\t */\n\tasync uploadFile(\n\t\tbuffer: Buffer,\n\t\toriginalFilename: string,\n\t\toptions?: {\n\t\t\tquality?: number;\n\t\t\twidth?: number;\n\t\t\theight?: number;\n\t\t\twithExtension?: boolean;\n\t\t\twithOriginalFilename?: boolean;\n\t\t}\n\t): Promise<{ filename: string; url: string }> {\n\t\tconst newFilename = options?.withOriginalFilename\n\t\t\t? originalFilename\n\t\t\t: this.generateFilename(originalFilename);\n\t\tconst extension = path.extname(newFilename).toLowerCase();\n\n\t\t// Guess the MIME type using the mime-types library\n\t\tconst contentType = mime.lookup(extension) || 'application/octet-stream';\n\n\t\t// Special image handling (compression)\n\t\tif (contentType.startsWith('image/')) {\n\t\t\tif (options?.withExtension) {\n\t\t\t\treturn this.uploadImage(buffer, originalFilename);\n\t\t\t} else {\n\t\t\t\treturn this.uploadProcessedImageToWebp(buffer, originalFilename, options);\n\t\t\t}\n\t\t}\n\n\t\treturn this.uploadToGCS(buffer, newFilename, contentType);\n\t}\n}\n"]}
@@ -22,7 +22,7 @@ Perfect for sharing types between frontend and backend applications.
22
22
 
23
23
  ## Version
24
24
 
25
- Version: 1.1.105
25
+ Version: 1.1.107
26
26
 
27
27
  ## Dependencies
28
28
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyxa.ai/types",
3
- "version": "1.1.105",
3
+ "version": "1.1.107",
4
4
  "description": "Lyxa type definitions and validation schemas for both frontend and backend",
5
5
  "author": "elie <42282499+Internalizable@users.noreply.github.com>",
6
6
  "license": "MIT",
@@ -1,3 +1,4 @@
1
+ import dayjs from 'dayjs';
1
2
  export declare const LyxaTimezone = "Asia/Dhaka";
2
3
  export declare const convertTimeToUTC: (timeStr: string, zone?: string) => string;
3
4
  export declare const convertTimeFromUTC: (utcTimeStr: string, zone?: string) => string;
@@ -5,3 +6,7 @@ export declare function normalizeWorkingHourTimeFormat(data: any): any;
5
6
  export declare function deNormalizeWorkingHourTimeFormat(data: any): any;
6
7
  export declare function parseTime(time: string): number;
7
8
  export declare function formatTimeString(time: string): string;
9
+ export declare function getCurrentTimeInfo(): {
10
+ currentTimeStamp: dayjs.Dayjs;
11
+ timeInHHmm: number;
12
+ };
@@ -8,6 +8,7 @@ exports.normalizeWorkingHourTimeFormat = normalizeWorkingHourTimeFormat;
8
8
  exports.deNormalizeWorkingHourTimeFormat = deNormalizeWorkingHourTimeFormat;
9
9
  exports.parseTime = parseTime;
10
10
  exports.formatTimeString = formatTimeString;
11
+ exports.getCurrentTimeInfo = getCurrentTimeInfo;
11
12
  const dayjs_1 = __importDefault(require("dayjs"));
12
13
  const utc_1 = __importDefault(require("dayjs/plugin/utc"));
13
14
  const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
@@ -112,4 +113,12 @@ function formatTimeString(time) {
112
113
  }
113
114
  return time.slice(0, 2) + ":" + time.slice(2);
114
115
  }
116
+ function getCurrentTimeInfo() {
117
+ const currentTimeStamp = (0, dayjs_1.default)().tz(exports.LyxaTimezone);
118
+ const timeInHHmm = Number(currentTimeStamp.format('HHmm'));
119
+ return {
120
+ currentTimeStamp,
121
+ timeInHHmm
122
+ };
123
+ }
115
124
  //# sourceMappingURL=time.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"time.js","sourceRoot":"/","sources":["utilities/time.ts"],"names":[],"mappings":"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","sourcesContent":["import dayjs from 'dayjs';\nimport utc from 'dayjs/plugin/utc';\nimport timezone from 'dayjs/plugin/timezone';\nimport { badRequestError } from './error-common';\n\ndayjs.extend(utc);\ndayjs.extend(timezone);\n\nexport const LyxaTimezone = 'Asia/Dhaka';\n\n// input: timeStr: 1500\n// output: 1200\nexport const convertTimeToUTC = (timeStr: string, zone = 'Asia/Beirut') => {\n const hour = Number(timeStr.slice(0, 2));\n const minute = Number(timeStr.slice(2));\n return dayjs()\n .tz(zone)\n .set('hour', hour)\n .set('minute', minute)\n .set('second', 0)\n .set('millisecond', 0)\n .utc()\n .format('HHmm');\n};\n\n// input: timeStr: 1200\n// output: 1500\nexport const convertTimeFromUTC = (utcTimeStr: string, zone = 'Asia/Beirut') => {\n const hour = Number(utcTimeStr.slice(0, 2));\n const minute = Number(utcTimeStr.slice(2));\n return dayjs()\n .utc()\n .set('hour', hour)\n .set('minute', minute)\n .set('second', 0)\n .set('millisecond', 0)\n .tz(zone)\n .format('HHmm');\n};\n\n\nexport function normalizeWorkingHourTimeFormat(data: any) {\n\tconst timeRegex = /^(\\d{1,2}):(\\d{1,2})$/;\n\n\tconst convert = (timeStr: string) => {\n\t\tconst match = timeStr.match(timeRegex);\n\t\tif (!match) return timeStr;\n\t\tconst hours = match[1].padStart(2, '0');\n\t\tconst minutes = match[2].padStart(2, '0');\n\t\treturn `${hours}${minutes}`;\n\t};\n\n\tconst transform: any = (obj: any) => {\n\t\t\n\t\tif (Array.isArray(obj)) {\n\t\t\treturn obj.map(transform);\n\t\t} else if (typeof obj === 'object' && obj !== null) {\n\t\t\tfor (const key in obj) {\n\t\t\t\tif (typeof obj[key] === 'string' && timeRegex.test(obj[key])) {\n\t\t\t\t\tobj[key] = convert(obj[key]);\n\t\t\t\t} else if (typeof obj[key] === 'object') {\n\t\t\t\t\tobj[key] = transform(obj[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t};\n\n\treturn transform(JSON.parse(JSON.stringify(data))); // deep copy to avoid mutation\n}\n\nexport function deNormalizeWorkingHourTimeFormat(data: any) {\n\tconst timeRegex = /^(\\d{2})(\\d{2})$/;\n\n\tconst convert = (timeStr: string) => {\n\t\tconst match = timeStr.match(timeRegex);\n\t\tif (!match) return timeStr;\n\t\tconst hours = String(Number(match[1])); // remove leading zero\n\t\tconst minutes = String(Number(match[2])).padStart(2, '0');\n\t\treturn `${hours}:${minutes}`;\n\t};\n\n\tconst transform: any = (obj: any) => {\n\t\tif (Array.isArray(obj)) {\n\t\t\treturn obj.map(transform);\n\t\t} else if (typeof obj === 'object' && obj !== null) {\n\t\t\tfor (const key in obj) {\n\t\t\t\tif (typeof obj[key] === 'string' && timeRegex.test(obj[key])) {\n\t\t\t\t\tobj[key] = convert(obj[key]);\n\t\t\t\t} else if (typeof obj[key] === 'object') {\n\t\t\t\t\tobj[key] = transform(obj[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t};\n\t// return transform(JSON.parse((data)));\n\treturn transform(JSON.parse(JSON.stringify(data)));\n}\n\nexport function parseTime(time: string): number {\n const [hh, mm] = formatTimeString(time).split(\":\").map(Number);\n if (\n isNaN(hh) || isNaN(mm) ||\n hh < 0 || hh > 23 ||\n mm < 0 || mm > 59\n ) {\n badRequestError(`Invalid time format: ${formatTimeString(time)}`);\n }\n\n return hh * 60 + mm;\n}\n\n// i/p: 0600, o/p: 06:00 \nexport function formatTimeString(time: string): string {\n if (!/^\\d{4}$/.test(time)) {\n badRequestError(`Invalid time format: ${time}`);\n }\n return time.slice(0, 2) + \":\" + time.slice(2);\n}\n\n"]}
1
+ {"version":3,"file":"time.js","sourceRoot":"/","sources":["utilities/time.ts"],"names":[],"mappings":"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","sourcesContent":["import dayjs from 'dayjs';\nimport utc from 'dayjs/plugin/utc';\nimport timezone from 'dayjs/plugin/timezone';\nimport { badRequestError } from './error-common';\n\ndayjs.extend(utc);\ndayjs.extend(timezone);\n\nexport const LyxaTimezone = 'Asia/Dhaka';\n\n// input: timeStr: 1500\n// output: 1200\nexport const convertTimeToUTC = (timeStr: string, zone = 'Asia/Beirut') => {\n\tconst hour = Number(timeStr.slice(0, 2));\n\tconst minute = Number(timeStr.slice(2));\n\treturn dayjs()\n\t\t.tz(zone)\n\t\t.set('hour', hour)\n\t\t.set('minute', minute)\n\t\t.set('second', 0)\n\t\t.set('millisecond', 0)\n\t\t.utc()\n\t\t.format('HHmm');\n};\n\n// input: timeStr: 1200\n// output: 1500\nexport const convertTimeFromUTC = (utcTimeStr: string, zone = 'Asia/Beirut') => {\n\tconst hour = Number(utcTimeStr.slice(0, 2));\n\tconst minute = Number(utcTimeStr.slice(2));\n\treturn dayjs()\n\t\t.utc()\n\t\t.set('hour', hour)\n\t\t.set('minute', minute)\n\t\t.set('second', 0)\n\t\t.set('millisecond', 0)\n\t\t.tz(zone)\n\t\t.format('HHmm');\n};\n\n\nexport function normalizeWorkingHourTimeFormat(data: any) {\n\tconst timeRegex = /^(\\d{1,2}):(\\d{1,2})$/;\n\n\tconst convert = (timeStr: string) => {\n\t\tconst match = timeStr.match(timeRegex);\n\t\tif (!match) return timeStr;\n\t\tconst hours = match[1].padStart(2, '0');\n\t\tconst minutes = match[2].padStart(2, '0');\n\t\treturn `${hours}${minutes}`;\n\t};\n\n\tconst transform: any = (obj: any) => {\n\n\t\tif (Array.isArray(obj)) {\n\t\t\treturn obj.map(transform);\n\t\t} else if (typeof obj === 'object' && obj !== null) {\n\t\t\tfor (const key in obj) {\n\t\t\t\tif (typeof obj[key] === 'string' && timeRegex.test(obj[key])) {\n\t\t\t\t\tobj[key] = convert(obj[key]);\n\t\t\t\t} else if (typeof obj[key] === 'object') {\n\t\t\t\t\tobj[key] = transform(obj[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t};\n\n\treturn transform(JSON.parse(JSON.stringify(data))); // deep copy to avoid mutation\n}\n\nexport function deNormalizeWorkingHourTimeFormat(data: any) {\n\tconst timeRegex = /^(\\d{2})(\\d{2})$/;\n\n\tconst convert = (timeStr: string) => {\n\t\tconst match = timeStr.match(timeRegex);\n\t\tif (!match) return timeStr;\n\t\tconst hours = String(Number(match[1])); // remove leading zero\n\t\tconst minutes = String(Number(match[2])).padStart(2, '0');\n\t\treturn `${hours}:${minutes}`;\n\t};\n\n\tconst transform: any = (obj: any) => {\n\t\tif (Array.isArray(obj)) {\n\t\t\treturn obj.map(transform);\n\t\t} else if (typeof obj === 'object' && obj !== null) {\n\t\t\tfor (const key in obj) {\n\t\t\t\tif (typeof obj[key] === 'string' && timeRegex.test(obj[key])) {\n\t\t\t\t\tobj[key] = convert(obj[key]);\n\t\t\t\t} else if (typeof obj[key] === 'object') {\n\t\t\t\t\tobj[key] = transform(obj[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t};\n\t// return transform(JSON.parse((data)));\n\treturn transform(JSON.parse(JSON.stringify(data)));\n}\n\nexport function parseTime(time: string): number {\n\tconst [hh, mm] = formatTimeString(time).split(\":\").map(Number);\n\tif (\n\t\tisNaN(hh) || isNaN(mm) ||\n\t\thh < 0 || hh > 23 ||\n\t\tmm < 0 || mm > 59\n\t) {\n\t\tbadRequestError(`Invalid time format: ${formatTimeString(time)}`);\n\t}\n\n\treturn hh * 60 + mm;\n}\n\n// i/p: 0600, o/p: 06:00 \nexport function formatTimeString(time: string): string {\n\tif (!/^\\d{4}$/.test(time)) {\n\t\tbadRequestError(`Invalid time format: ${time}`);\n\t}\n\treturn time.slice(0, 2) + \":\" + time.slice(2);\n}\n\nexport function getCurrentTimeInfo() {\n\tconst currentTimeStamp = dayjs().tz(LyxaTimezone);\n\tconst timeInHHmm = Number(currentTimeStamp.format('HHmm')); // 0930\n\treturn {\n\t\tcurrentTimeStamp,\n\t\ttimeInHHmm\n\t}\n}\n\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyxa.ai/core",
3
- "version": "1.1.105",
3
+ "version": "1.1.107",
4
4
  "description": "The Core system of the Lyxa services.",
5
5
  "author": "elie <42282499+Internalizable@users.noreply.github.com>",
6
6
  "license": "MIT",
@@ -32,6 +32,7 @@
32
32
  "bcryptjs": "^3.0.2",
33
33
  "bullmq": "^5.56.0",
34
34
  "dayjs": "^1.11.13",
35
+ "file-type": "^21.0.0",
35
36
  "firebase": "^11.1.0",
36
37
  "firebase-admin": "^13.0.1",
37
38
  "ioredis": "^5.4.1",
@@ -44,7 +45,7 @@
44
45
  "pino": "9.5.0",
45
46
  "pino-mongodb": "4.3.0",
46
47
  "pino-pretty": "13.0.0",
47
- "sharp": "^0.33.5",
48
+ "sharp": "^0.34.4",
48
49
  "shortid": "^2.2.16",
49
50
  "slugify": "^1.6.6",
50
51
  "twilio": "^5.4.0",