Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@internxt/drive-desktop-core",
"version": "0.1.8",
"version": "0.1.9",
"author": "Internxt <hello@internxt.com>",
"license": "MIT",
"files": [
Expand Down
28 changes: 28 additions & 0 deletions src/backend/core/logger/log-path.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { logPath } from './log-path';

vi.mock(import('node:os'), () => ({
homedir: vi.fn(() => 'C:/Users/user'),
}));
Copy link
Collaborator Author

@dajimenezriv-internxt dajimenezriv-internxt Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since homedir() is happening when the file loads we need to use vi.mock in this way


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');
});
});
21 changes: 21 additions & 0 deletions src/backend/core/logger/log-path.ts
Original file line number Diff line number Diff line change
@@ -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;
}
6 changes: 5 additions & 1 deletion src/backend/core/logger/logger.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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';

export type TLoggerBody = {
tag?: TTag;
msg: string;
workspaceId?: string;
path?: string;
context?: Record<string, unknown>;
[key: string]: unknown;
};
Expand Down Expand Up @@ -60,14 +63,15 @@ 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)}`;

rawBody = {
header,
msg,
...(workspaceId && { workspaceId }),
...(path && { path: logPath({ path }) }),
...rest,
};

Expand Down
10 changes: 9 additions & 1 deletion src/backend/core/utils/throw-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
type Result<T> = { data: NonNullable<T>; error: undefined } | { data: undefined; error: Error };

export function throwWrapper<Args extends unknown[], T>(fn: (...args: Args) => Promise<Result<T>>) {
export function throwAsyncWrapper<Args extends unknown[], T>(fn: (...args: Args) => Promise<Result<T>>) {
return async (...args: Args) => {
const { data, error } = await fn(...args);
if (error) throw error;
return data;
};
}

export function throwWrapper<Args extends unknown[], T>(fn: (...args: Args) => Result<T>) {
return (...args: Args) => {
const { data, error } = fn(...args);
if (error) throw error;
return data;
};
}
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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();
Expand Down
11 changes: 6 additions & 5 deletions src/backend/index.ts
Original file line number Diff line number Diff line change
@@ -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';
7 changes: 4 additions & 3 deletions src/backend/infra/file-system/file-system.module.ts
Original file line number Diff line number Diff line change
@@ -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),
};
13 changes: 13 additions & 0 deletions src/backend/infra/file-system/file-system.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
import { posix, win32 } from 'node:path';

import { Brand } from '@/backend/core/utils/brand.types';

export type AbsolutePath = Brand<string, 'AbsolutePath'>;
export type RelativePath = Brand<string, 'RelativePath'>;

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;
}
Loading