From 703613416dc9683016dd1f0c92d0b02dab37fa35 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Thu, 4 Sep 2025 12:08:04 +0200 Subject: [PATCH 1/2] fix: refactor sharp dependency handling and update thumbnail processing logic --- package.json | 4 +++- src/services/thumbnail.service.ts | 39 +++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index d771e279..b53f0105 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "pm2": "6.0.10", "range-parser": "1.2.1", "selfsigned": "3.0.1", - "sharp": "0.34.3", "tty-table": "4.2.3", "winston": "3.17.0" }, @@ -83,6 +82,9 @@ "vitest": "3.2.4", "vitest-mock-express": "2.2.0" }, + "optionalDependencies": { + "sharp": "0.34.3" + }, "engines": { "node": ">=22.12.0" }, diff --git a/src/services/thumbnail.service.ts b/src/services/thumbnail.service.ts index 898331ab..a0ed8c9e 100644 --- a/src/services/thumbnail.service.ts +++ b/src/services/thumbnail.service.ts @@ -3,7 +3,19 @@ import { DriveFileService } from './drive/drive-file.service'; import { StorageTypes } from '@internxt/sdk/dist/drive'; import { NetworkFacade } from './network/network-facade.service'; import { isImageThumbnailable, ThumbnailConfig } from '../utils/thumbnail.utils'; -import sharp from 'sharp'; + +let sharpDependency: typeof import('sharp') | null = null; + +const getSharp = async () => { + if (!sharpDependency) { + try { + sharpDependency = (await import('sharp')).default; + } catch { + return null; + } + } + return sharpDependency; +}; export class ThumbnailService { public static readonly instance: ThumbnailService = new ThumbnailService(); @@ -51,16 +63,19 @@ export class ThumbnailService { } }; - private readonly getThumbnailFromImageBuffer = (buffer: Buffer): Promise => { - return sharp(buffer) - .resize({ - height: ThumbnailConfig.MaxHeight, - width: ThumbnailConfig.MaxWidth, - fit: 'inside', - }) - .png({ - quality: ThumbnailConfig.Quality, - }) - .toBuffer(); + private readonly getThumbnailFromImageBuffer = async (buffer: Buffer): Promise => { + const sharp = await getSharp(); + if (sharp) { + return sharp(buffer, { failOnError: false }) + .resize({ + height: ThumbnailConfig.MaxHeight, + width: ThumbnailConfig.MaxWidth, + fit: 'inside', + }) + .png({ + quality: ThumbnailConfig.Quality, + }) + .toBuffer(); + } }; } From 566fe4f7dd6c31c527b2daab6166e411b29abbe8 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Thu, 4 Sep 2025 13:39:29 +0200 Subject: [PATCH 2/2] fix: add AsyncUtils sleep to prevent folder creation delay issue --- src/commands/create-folder.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/commands/create-folder.ts b/src/commands/create-folder.ts index 4adddda3..348fe709 100644 --- a/src/commands/create-folder.ts +++ b/src/commands/create-folder.ts @@ -4,6 +4,7 @@ import { DriveFolderService } from '../services/drive/drive-folder.service'; import { ConfigService } from '../services/config.service'; import { ValidationService } from '../services/validation.service'; import { EmptyFolderNameError, MissingCredentialsError, NotValidFolderUuidError } from '../types/command.types'; +import { AsyncUtils } from '../utils/async.utils'; export default class CreateFolder extends Command { static readonly args = {}; @@ -53,6 +54,9 @@ export default class CreateFolder extends Command { }); const newFolder = await createNewFolder; + // This aims to prevent this issue: https://inxt.atlassian.net/browse/PB-1446 + await AsyncUtils.sleep(500); + CLIUtils.done(flags['json']); // eslint-disable-next-line max-len const message = `Folder ${newFolder.plainName} created successfully, view it at ${ConfigService.instance.get('DRIVE_WEB_URL')}/folder/${newFolder.uuid}`;