Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: Pull request checks

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
checks:
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
importOrderParserPlugins: ["typescript", "decorators-legacy"],
importOrderSeparation: true,
plugins: [require.resolve("@trivago/prettier-plugin-sort-imports")],
printWidth: 140,
printWidth: 120,
proseWrap: "never",
semi: true,
singleQuote: false,
Expand Down
7 changes: 6 additions & 1 deletion examples/callbacks/notify-message.callback.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { logger } from "examples/drive";

export const notifyMessageCallback = (message: string, action: string, errorName: string, callback: (response: boolean) => void) => {
export const notifyMessageCallback = (
message: string,
action: string,
errorName: string,
callback: (response: boolean) => void,
) => {
logger.info({ event: "notifyMessageCallback", message, action, errorName });
callback(true);
};
4 changes: 3 additions & 1 deletion examples/get-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ const { data } = z.object({ file: z.string() }).safeParse(argv);

if (data) {
const path = data.file;
const state = drive.getPlaceholderState(path);
const state = drive.getPlaceholderState({
path,
});
logger.info({ state });
} else {
logger.error("Por favor especifica un archivo con --file <path>");
Expand Down
5 changes: 4 additions & 1 deletion examples/handlers/handle-add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export const handleAdd = async (task: QueueItem) => {
try {
logger.info({ fn: "handleAdd", task });
const id = task.isFolder ? v4() : addInfoItem(task.path);
drive.convertToPlaceholder(task.path, id);
drive.convertToPlaceholder({
itemPath: task.path,
id,
});
} catch (error) {
logger.error("handleAdd", error);
}
Expand Down
11 changes: 9 additions & 2 deletions examples/handlers/handle-change-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ export const handleChangeSize = async (task: QueueItem) => {
try {
logger.info({ fn: "handleChangeSize", path: task.path });
const id = v4();
drive.convertToPlaceholder(task.path, id);
drive.updateFileIdentity(task.path, id, false);
drive.convertToPlaceholder({
itemPath: task.path,
id,
});
drive.updateFileIdentity({
itemPath: task.path,
id,
isDirectory: task.isFolder,
});
} catch (error) {
logger.error("handleChangeSize", error);
}
Expand Down
4 changes: 3 additions & 1 deletion examples/handlers/handle-dehydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { QueueItem } from "@/queue/queueManager";
export const handleDehydrate = async (task: QueueItem) => {
try {
logger.info({ fn: "handleDehydrate", path: task.path });
drive.dehydrateFile(task.path);
drive.dehydrateFile({
itemPath: task.path,
});
} catch (error) {
logger.error("handleDehydrate", error);
}
Expand Down
4 changes: 3 additions & 1 deletion examples/handlers/handle-hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { QueueItem } from "@/queue/queueManager";
export const handleHydrate = async (task: QueueItem) => {
try {
logger.info({ fn: "handleHydrate", path: task.path });
await drive.hydrateFile(task.path);
await drive.hydrateFile({
itemPath: task.path,
});
} catch (error) {
logger.error("handleHydrate", error);
}
Expand Down
21 changes: 15 additions & 6 deletions examples/register.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { QueueManager } from "@/queue/queue-manager";
import VirtualDrive from "@/virtual-drive";

import { cancelFetchDataCallback } from "./callbacks/cancel-fetch-data.callback";
import { notifyDeleteCallback } from "./callbacks/notify-delete.callback";
Expand All @@ -14,18 +13,28 @@ import { handleHydrate } from "./handlers/handle-hydrate";
import { initInfoItems } from "./info-items-manager";
import settings from "./settings";

const callbacks = { notifyDeleteCallback, notifyRenameCallback, fetchDataCallback, cancelFetchDataCallback, notifyMessageCallback };
const callbacks = {
notifyDeleteCallback,
notifyRenameCallback,
fetchDataCallback,
cancelFetchDataCallback,
notifyMessageCallback,
};
const handlers = { handleAdd, handleHydrate, handleDehydrate, handleChangeSize };

const notify = { onTaskSuccess: async () => undefined, onTaskProcessing: async () => undefined };
const queueManager = new QueueManager(handlers, notify, settings.queuePersistPath);
const queueManager = new QueueManager({ handlers, persistPath: settings.queuePersistPath });

drive.registerSyncRoot(settings.driveName, settings.driveVersion, callbacks, settings.iconPath);
drive.registerSyncRoot({
providerName: settings.driveName,
providerVersion: settings.driveVersion,
callbacks,
logoPath: settings.iconPath,
});
drive.connectSyncRoot();

try {
initInfoItems();
drive.watchAndWait(settings.syncRootPath, queueManager, settings.watcherLogPath);
drive.watchAndWait({ queueManager });
} catch (error) {
logger.error(error);
drive.disconnectSyncRoot();
Expand Down
20 changes: 17 additions & 3 deletions examples/utils/generate-random-file-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ async function createStructureRecursively(
const createdAt = Date.now() - (timeOffset || 0);
const updatedAt = Date.now() - (timeOffset || 0) + 2000;

drive.createFileByPath(fullPath, fileId, fileSize, createdAt, updatedAt);
drive.createFileByPath({
relativePath: fullPath,
itemId: fileId,
size: fileSize,
creationTime: createdAt,
lastWriteTime: updatedAt,
});

result[fileId] = fullPath;
}
Expand All @@ -66,13 +72,21 @@ async function createStructureRecursively(
const createdAt = Date.now() - (timeOffset || 0) - 10000; // Ejemplo
const updatedAt = Date.now() - (timeOffset || 0);

drive.createFolderByPath(newFolderPath, folderId, 1000, createdAt, updatedAt);
drive.createFolderByPath({
relativePath: newFolderPath,
itemId: folderId,
creationTime: createdAt,
lastWriteTime: updatedAt,
});

await createStructureRecursively(drive, newFolderPath, level - 1, options, result);
}
}

async function generateRandomFilesAndFolders(drive: VirtualDrive, options: GenerateOptions): Promise<Record<string, string>> {
async function generateRandomFilesAndFolders(
drive: VirtualDrive,
options: GenerateOptions,
): Promise<Record<string, string>> {
const { rootPath } = options;

const result: Record<string, string> = {};
Expand Down
32 changes: 28 additions & 4 deletions examples/utils/generate-random-tree.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,36 @@ class MockVirtualDrive implements Partial<VirtualDrive> {
private files: Record<string, any> = {};
private folders: Record<string, any> = {};

createFileByPath(path: string, id: string, size: number, createdAt: number, updatedAt: number): void {
this.files[path] = { id, size, createdAt, updatedAt };
createFileByPath({
relativePath,
itemId,
size = 0,
creationTime = Date.now(),
lastWriteTime = Date.now(),
}: {
relativePath: string;
itemId: string;
size?: number;
creationTime?: number;
lastWriteTime?: number;
}): void {
this.files[relativePath] = { itemId, size, creationTime, lastWriteTime };
}

createFolderByPath(path: string, id: string, size: number, createdAt: number, updatedAt: number): void {
this.folders[path] = { id, size, createdAt, updatedAt };
createFolderByPath({
relativePath,
itemId,
size = 0,
creationTime = Date.now(),
lastWriteTime = Date.now(),
}: {
relativePath: string;
itemId: string;
size?: number;
creationTime?: number;
lastWriteTime?: number;
}): void {
this.folders[relativePath] = { itemId, size, creationTime, lastWriteTime };
}

getFiles(): Record<string, any> {
Expand Down
13 changes: 12 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,15 @@ import { Callbacks } from "@/types/callbacks.type";
import { PinState, SyncState } from "@/types/placeholder.type";
import VirtualDrive from "@/virtual-drive";

export { Addon, VirtualDrive, QueueItem, typeQueue, HandleAction, HandleActions, QueueManager, Callbacks, PinState, SyncState };
export {
Addon,
VirtualDrive,
QueueItem,
typeQueue,
HandleAction,
HandleActions,
QueueManager,
Callbacks,
PinState,
SyncState,
};
31 changes: 22 additions & 9 deletions native-src/placeholders_interface/PlaceHolderInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,20 @@ FileHandle handleForPath(const std::wstring &wPath)
return {};
}

// Convertir std::wstring a std::string
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string path = converter.to_bytes(wPath);

LPCSTR pPath = path.c_str();

std::filesystem::path pathFs(path);
/**
* v1.0.9 Jonathan Arce
*
* We directly use the wPath parameter in handleForPath for several important reasons:
*
* 1. Performance optimization: Using wPath directly avoids unnecessary string conversions
* between wide strings and UTF-8/ANSI, which would be costly for file operations.
*
* 2. Unicode support: Windows APIs like CfOpenFileWithOplock and CreateFileW require wide
* character strings (wchar_t) to properly handle Unicode paths with international
* characters, spaces, and special symbols.
*/

std::filesystem::path pathFs(wPath);
if (!std::filesystem::exists(pathFs))
{
return {};
Expand All @@ -186,13 +193,16 @@ FileHandle handleForPath(const std::wstring &wPath)
}
else
{
// Convert only for logging purposes
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string path = converter.to_bytes(wPath);
printf("Could not CfOpenFileWithOplock for path: %s with error: %ld\n", path.c_str(), openResult);
}
}
else if (std::filesystem::is_regular_file(pathFs))
{
HANDLE handle = CreateFile(
pPath,
HANDLE handle = CreateFileW(
wPath.c_str(), // Use wide string path directly
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
Expand All @@ -206,6 +216,9 @@ FileHandle handleForPath(const std::wstring &wPath)
}
else
{
// Convert only for logging purposes
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string path = converter.to_bytes(wPath);
printf("Could not CreateFile for path: %s with error: %ld\n", path.c_str(), GetLastError());
}
}
Expand Down
4 changes: 3 additions & 1 deletion native-src/placeholders_interface/Planceholders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ bool Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std:
if (FAILED(hr))
{
// Manejar el error al convertir a marcador de posición
if (hr != 0x8007017C) {
if (hr != 0x8007017C)
{
wprintf(L"[ConvertToPlaceholder] Error converting to placeholder, ConvertToPlaceholder failed with HRESULT 0x%X\n", hr);
}

Expand Down Expand Up @@ -287,6 +288,7 @@ void Placeholders::UpdateSyncStatus(const std::wstring &filePath, bool inputSync
if (fileHandle == INVALID_HANDLE_VALUE)
{
wprintf(L"[UpdateSyncStatus] Error al abrir el archivo: %d\n", GetLastError());
CloseHandle(fileHandle);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@internxt/node-win",
"version": "1.0.8",
"version": "1.0.9",
"description": "Drive desktop node addon",
"main": "dist/index.ts",
"types": "dist/index.d.ts",
Expand Down
27 changes: 23 additions & 4 deletions src/addon-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,24 @@ export class Addon {
lastAccessTime: string;
basePath: string;
}) {
return addon.createPlaceholderFile(fileName, fileId, fileSize, fileAttributes, creationTime, lastWriteTime, lastAccessTime, basePath);
return addon.createPlaceholderFile(
fileName,
fileId,
fileSize,
fileAttributes,
creationTime,
lastWriteTime,
lastAccessTime,
basePath,
);
}

createPlaceholderDirectory({
itemName,
itemId,
isDirectory,
itemSize,
fileAttributes,
folderAttributes,
creationTime,
lastWriteTime,
lastAccessTime,
Expand All @@ -107,13 +116,23 @@ export class Addon {
itemId: string;
isDirectory: boolean;
itemSize: number;
fileAttributes: number;
folderAttributes: number;
creationTime: string;
lastWriteTime: string;
lastAccessTime: string;
path: string;
}) {
return addon.createEntry(itemName, itemId, isDirectory, itemSize, fileAttributes, creationTime, lastWriteTime, lastAccessTime, path);
return addon.createEntry(
itemName,
itemId,
isDirectory,
itemSize,
folderAttributes,
creationTime,
lastWriteTime,
lastAccessTime,
path,
);
}

/**
Expand Down
Loading