From 8a5c1a25e194b7106e1d771a20c6b60f68222eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Wed, 29 Oct 2025 20:39:40 +0100 Subject: [PATCH 1/3] Create path --- .eslintrc.js | 1 + package-lock.json | 4 +-- package.json | 2 +- src/backend/core/logger/log-path.test.ts | 28 +++++++++++++++++++ src/backend/core/logger/log-path.ts | 21 ++++++++++++++ src/backend/core/logger/logger.ts | 6 +++- src/backend/core/utils/throw-wrapper.ts | 10 ++++++- .../services/delete-file-saftly.test.ts | 5 ++-- src/backend/index.ts | 11 ++++---- .../infra/file-system/file-system.module.ts | 9 +++--- .../infra/file-system/file-system.types.ts | 14 ++++++++++ 11 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 src/backend/core/logger/log-path.test.ts create mode 100644 src/backend/core/logger/log-path.ts diff --git a/.eslintrc.js b/.eslintrc.js index 184e1d5..b8d789b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -54,6 +54,7 @@ module.exports = { 'sonarjs/no-commented-code': 'off', 'sonarjs/no-empty-test-file': 'off', 'sonarjs/no-redundant-optional': 'off', + 'sonarjs/redundant-type-aliases': 'off', 'sonarjs/todo-tag': 'off', 'unicorn/catch-error-name': 'error', 'unicorn/filename-case': ['error', { case: 'kebabCase' }], 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..ca6464a --- /dev/null +++ b/src/backend/core/logger/log-path.ts @@ -0,0 +1,21 @@ +import { homedir } from 'node:os'; + +import { createPath } from '@/backend/infra/file-system/file-system.types'; + +const HOME_DIR = createPath(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..4b4b0ce 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 { createPath, 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 = createPath('/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..03df73d 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 type { AbsolutePath, Path, RelativePath } from './file-system.types'; +export { createPath, 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..09f1974 100644 --- a/src/backend/infra/file-system/file-system.types.ts +++ b/src/backend/infra/file-system/file-system.types.ts @@ -1,4 +1,18 @@ +import { posix, win32 } from 'node:path'; + import { Brand } from '@/backend/core/utils/brand.types'; export type AbsolutePath = Brand; +export type Path = AbsolutePath; export type RelativePath = Brand; + +export function createPath(...parts: string[]) { + let path = posix.join(...parts); + path = path.replaceAll(win32.sep, posix.sep); + path = posix.normalize(path); + return path as Path; +} + +export function dirname(path: Path) { + return posix.dirname(path) as Path; +} From 5ca4bbed150cb66daa875a6e29c30b79efb86da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Thu, 30 Oct 2025 09:57:30 +0100 Subject: [PATCH 2/3] Commit --- .eslintrc.js | 1 - src/backend/infra/file-system/file-system.module.ts | 4 ++-- src/backend/infra/file-system/file-system.types.ts | 9 ++++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b8d789b..184e1d5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -54,7 +54,6 @@ module.exports = { 'sonarjs/no-commented-code': 'off', 'sonarjs/no-empty-test-file': 'off', 'sonarjs/no-redundant-optional': 'off', - 'sonarjs/redundant-type-aliases': 'off', 'sonarjs/todo-tag': 'off', 'unicorn/catch-error-name': 'error', 'unicorn/filename-case': ['error', { case: 'kebabCase' }], diff --git a/src/backend/infra/file-system/file-system.module.ts b/src/backend/infra/file-system/file-system.module.ts index 03df73d..b6082ac 100644 --- a/src/backend/infra/file-system/file-system.module.ts +++ b/src/backend/infra/file-system/file-system.module.ts @@ -3,8 +3,8 @@ import { throwAsyncWrapper } from '@/backend/core/utils/throw-wrapper'; import { readdir } from './services/readdir'; import { stat } from './services/stat'; -export type { AbsolutePath, Path, RelativePath } from './file-system.types'; -export { createPath, dirname } from './file-system.types'; +export type { AbsolutePath, RelativePath } from './file-system.types'; +export { createAbsolutePath, dirname } from './file-system.types'; export const FileSystemModule = { stat, statThrow: throwAsyncWrapper(stat), diff --git a/src/backend/infra/file-system/file-system.types.ts b/src/backend/infra/file-system/file-system.types.ts index 09f1974..23ccecb 100644 --- a/src/backend/infra/file-system/file-system.types.ts +++ b/src/backend/infra/file-system/file-system.types.ts @@ -3,16 +3,15 @@ import { posix, win32 } from 'node:path'; import { Brand } from '@/backend/core/utils/brand.types'; export type AbsolutePath = Brand; -export type Path = AbsolutePath; export type RelativePath = Brand; -export function createPath(...parts: string[]) { +export function createAbsolutePath(...parts: string[]) { let path = posix.join(...parts); path = path.replaceAll(win32.sep, posix.sep); path = posix.normalize(path); - return path as Path; + return path as AbsolutePath; } -export function dirname(path: Path) { - return posix.dirname(path) as Path; +export function dirname(path: AbsolutePath) { + return posix.dirname(path) as AbsolutePath; } From f09beb3c00a77b6050bc2820869f16bd37c12805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jim=C3=A9nez=20Rivera?= Date: Thu, 30 Oct 2025 09:58:41 +0100 Subject: [PATCH 3/3] Commit --- src/backend/core/logger/log-path.ts | 4 ++-- .../features/cleaner/services/delete-file-saftly.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/core/logger/log-path.ts b/src/backend/core/logger/log-path.ts index ca6464a..ade2b4f 100644 --- a/src/backend/core/logger/log-path.ts +++ b/src/backend/core/logger/log-path.ts @@ -1,8 +1,8 @@ import { homedir } from 'node:os'; -import { createPath } from '@/backend/infra/file-system/file-system.types'; +import { createAbsolutePath } from '@/backend/infra/file-system/file-system.types'; -const HOME_DIR = createPath(homedir()); +const HOME_DIR = createAbsolutePath(homedir()); const HOME_DIR_LENGTH = HOME_DIR.length; const INTERNXT_PATTERN = /InternxtDrive - [\w-]+/g; 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 4b4b0ce..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,6 +1,6 @@ import { unlink } from 'node:fs/promises'; -import { createPath, FileSystemModule } from '@/backend/infra/file-system/file-system.module'; +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'; @@ -13,7 +13,7 @@ const mockedUnlink = deepMocked(unlink); const mockedStatThrow = partialSpyOn(FileSystemModule, 'statThrow'); describe('deleteFileSafely', () => { - const testFilePath = createPath('/test/path/file.txt'); + const testFilePath = createAbsolutePath('/test/path/file.txt'); beforeEach(() => { cleanerStore.reset();