diff --git a/package-lock.json b/package-lock.json index 924078f..5c2e4b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@internxt/drive-desktop-core", - "version": "0.1.8", + "version": "0.1.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@internxt/drive-desktop-core", - "version": "0.1.8", + "version": "0.1.9", "license": "MIT", "dependencies": { "@internxt/sdk": "^1.11.10", diff --git a/package.json b/package.json index d76af09..ef34678 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@internxt/drive-desktop-core", - "version": "0.1.8", + "version": "0.1.9", "author": "Internxt ", "license": "MIT", "files": [ diff --git a/src/backend/core/logger/log-path.test.ts b/src/backend/core/logger/log-path.test.ts new file mode 100644 index 0000000..990892c --- /dev/null +++ b/src/backend/core/logger/log-path.test.ts @@ -0,0 +1,28 @@ +import { logPath } from './log-path'; + +vi.mock(import('node:os'), () => ({ + homedir: vi.fn(() => 'C:/Users/user'), +})); + +describe('log-path', () => { + it('should replace homedir', () => { + // When + const path = logPath({ path: 'C:/Users/user/file.txt' }); + // Then + expect(path).toBe('~/file.txt'); + }); + + it('should replace sync root folder', () => { + // When + const path = logPath({ path: 'D:/Users/user/InternxtDrive - uuid/file.txt' }); + // Then + expect(path).toBe('D:/Users/user/~/file.txt'); + }); + + it('should replace homedir and sync root folder', () => { + // When + const path = logPath({ path: 'C:/Users/user/InternxtDrive - uuid/file.txt' }); + // Then + expect(path).toBe('~/~/file.txt'); + }); +}); diff --git a/src/backend/core/logger/log-path.ts b/src/backend/core/logger/log-path.ts new file mode 100644 index 0000000..ade2b4f --- /dev/null +++ b/src/backend/core/logger/log-path.ts @@ -0,0 +1,21 @@ +import { homedir } from 'node:os'; + +import { createAbsolutePath } from '@/backend/infra/file-system/file-system.types'; + +const HOME_DIR = createAbsolutePath(homedir()); +const HOME_DIR_LENGTH = HOME_DIR.length; +const INTERNXT_PATTERN = /InternxtDrive - [\w-]+/g; + +type Props = { path: string }; + +export function logPath({ path }: Props) { + if (path.startsWith(HOME_DIR)) { + path = '~' + path.slice(HOME_DIR_LENGTH); + } + + if (path.includes('InternxtDrive')) { + path = path.replace(INTERNXT_PATTERN, '~'); + } + + return path; +} diff --git a/src/backend/core/logger/logger.ts b/src/backend/core/logger/logger.ts index 37cba31..534fc15 100644 --- a/src/backend/core/logger/logger.ts +++ b/src/backend/core/logger/logger.ts @@ -1,6 +1,8 @@ import ElectronLog from 'electron-log'; import { inspect } from 'node:util'; +import { logPath } from './log-path'; + type TTag = 'AUTH' | 'BACKUPS' | 'SYNC-ENGINE' | 'ANTIVIRUS' | 'NODE-WIN' | 'PRODUCTS' | 'CLEANER'; type TLevel = 'debug' | 'warn' | 'error'; @@ -8,6 +10,7 @@ export type TLoggerBody = { tag?: TTag; msg: string; workspaceId?: string; + path?: string; context?: Record; [key: string]: unknown; }; @@ -60,7 +63,7 @@ function getTagStr(tag?: TTag): string { } function prepareBody(level: TLevel, rawBody: TLoggerBody) { - const { tag, msg, workspaceId, ...rest } = rawBody; + const { tag, msg, workspaceId, path, ...rest } = rawBody; const header = `${getLevelStr(level)} - ${getProcessStr()} - ${getTagStr(tag)}`; @@ -68,6 +71,7 @@ function prepareBody(level: TLevel, rawBody: TLoggerBody) { header, msg, ...(workspaceId && { workspaceId }), + ...(path && { path: logPath({ path }) }), ...rest, }; diff --git a/src/backend/core/utils/throw-wrapper.ts b/src/backend/core/utils/throw-wrapper.ts index ebf7cd7..22407f1 100644 --- a/src/backend/core/utils/throw-wrapper.ts +++ b/src/backend/core/utils/throw-wrapper.ts @@ -1,9 +1,17 @@ type Result = { data: NonNullable; error: undefined } | { data: undefined; error: Error }; -export function throwWrapper(fn: (...args: Args) => Promise>) { +export function throwAsyncWrapper(fn: (...args: Args) => Promise>) { return async (...args: Args) => { const { data, error } = await fn(...args); if (error) throw error; return data; }; } + +export function throwWrapper(fn: (...args: Args) => Result) { + return (...args: Args) => { + const { data, error } = fn(...args); + if (error) throw error; + return data; + }; +} diff --git a/src/backend/features/cleaner/services/delete-file-saftly.test.ts b/src/backend/features/cleaner/services/delete-file-saftly.test.ts index 6ece7e0..fce8a50 100644 --- a/src/backend/features/cleaner/services/delete-file-saftly.test.ts +++ b/src/backend/features/cleaner/services/delete-file-saftly.test.ts @@ -1,7 +1,6 @@ import { unlink } from 'node:fs/promises'; -import { FileSystemModule } from '@/backend/infra/file-system/file-system.module'; -import type { AbsolutePath } from '@/backend/infra/file-system/file-system.types'; +import { createAbsolutePath, FileSystemModule } from '@/backend/infra/file-system/file-system.module'; import { loggerMock } from '@/tests/vitest/mocks.helper.test'; import { call, deepMocked, partialSpyOn } from '@/tests/vitest/utils.helper.test'; @@ -14,7 +13,7 @@ const mockedUnlink = deepMocked(unlink); const mockedStatThrow = partialSpyOn(FileSystemModule, 'statThrow'); describe('deleteFileSafely', () => { - const testFilePath = '/test/path/file.txt' as AbsolutePath; + const testFilePath = createAbsolutePath('/test/path/file.txt'); beforeEach(() => { cleanerStore.reset(); diff --git a/src/backend/index.ts b/src/backend/index.ts index 8465881..f8591b9 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -1,8 +1,9 @@ export { logger, TLoggerBody } from './core/logger/logger'; +export { logPath } from './core/logger/log-path'; export { setupElectronLog } from './core/logger/setup-electron-log'; -export { throwWrapper } from './core/utils/throw-wrapper'; +export { throwWrapper, throwAsyncWrapper } from './core/utils/throw-wrapper'; -export { FileSystemModule, AbsolutePath, RelativePath } from './infra/file-system/file-system.module'; -export { PaymentsModule, UserAvailableProducts } from './features/payments/payments.module'; -export { CleanerModule } from './features/cleaner/cleaner.module'; -export { SyncModule } from './features/sync'; +export * from './infra/file-system/file-system.module'; +export * from './features/payments/payments.module'; +export * from './features/cleaner/cleaner.module'; +export * from './features/sync'; diff --git a/src/backend/infra/file-system/file-system.module.ts b/src/backend/infra/file-system/file-system.module.ts index 549ad4a..b6082ac 100644 --- a/src/backend/infra/file-system/file-system.module.ts +++ b/src/backend/infra/file-system/file-system.module.ts @@ -1,12 +1,13 @@ -import { throwWrapper } from '@/backend/core/utils/throw-wrapper'; +import { throwAsyncWrapper } from '@/backend/core/utils/throw-wrapper'; import { readdir } from './services/readdir'; import { stat } from './services/stat'; export type { AbsolutePath, RelativePath } from './file-system.types'; +export { createAbsolutePath, dirname } from './file-system.types'; export const FileSystemModule = { stat, - statThrow: throwWrapper(stat), + statThrow: throwAsyncWrapper(stat), readdir, - readdirThrow: throwWrapper(readdir), + readdirThrow: throwAsyncWrapper(readdir), }; diff --git a/src/backend/infra/file-system/file-system.types.ts b/src/backend/infra/file-system/file-system.types.ts index 5bb2cdd..23ccecb 100644 --- a/src/backend/infra/file-system/file-system.types.ts +++ b/src/backend/infra/file-system/file-system.types.ts @@ -1,4 +1,17 @@ +import { posix, win32 } from 'node:path'; + import { Brand } from '@/backend/core/utils/brand.types'; export type AbsolutePath = Brand; export type RelativePath = Brand; + +export function createAbsolutePath(...parts: string[]) { + let path = posix.join(...parts); + path = path.replaceAll(win32.sep, posix.sep); + path = posix.normalize(path); + return path as AbsolutePath; +} + +export function dirname(path: AbsolutePath) { + return posix.dirname(path) as AbsolutePath; +}