diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 577b479e..ac8f9a85 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,7 +5,7 @@ on: types: [published] jobs: - publish_npm: + publish: runs-on: ubuntu-latest timeout-minutes: 1 @@ -24,7 +24,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "@internxt:registry=https://npm.pkg.github.com/" > .npmrc - echo "//npm.pkg.github.com/:_authToken=$GITHUB_TOKEN >> .npmrc + echo "//npm.pkg.github.com/:_authToken=$GITHUB_TOKEN" >> .npmrc - name: Publish package to github run: npm publish --scope=@internxt --access public diff --git a/dist/addon.node b/dist/addon.node index b69609a6..4fe99071 100644 Binary files a/dist/addon.node and b/dist/addon.node differ diff --git a/include/placeholders_interface/Placeholders.h b/include/placeholders_interface/Placeholders.h index 66aaddb6..e61ba72c 100644 --- a/include/placeholders_interface/Placeholders.h +++ b/include/placeholders_interface/Placeholders.h @@ -3,37 +3,13 @@ #include #include -struct PlaceholderResult { - bool success; - std::wstring errorMessage; -}; - class Placeholders { public: - static PlaceholderResult CreateOne( - const wchar_t *fileName, - const wchar_t *fileIdentity, - int64_t fileSize, - LARGE_INTEGER creationTime, - LARGE_INTEGER lastWriteTime, - LARGE_INTEGER lastAccessTime, - const wchar_t *destPath); - static void MaintainIdentity(std::wstring &fullPath, PCWSTR fileIdentity, bool isDirectory); - - static PlaceholderResult CreateEntry( - const wchar_t *itemName, - const wchar_t *itemIdentity, - LARGE_INTEGER creationTime, - LARGE_INTEGER lastWriteTime, - LARGE_INTEGER lastAccessTime, - const wchar_t *destPath); - static void ForceShellRefresh(const std::wstring &path); static void UpdateSyncStatus(const std::wstring &filePath, bool syncState, bool isDirectory); static HRESULT UpdatePinState(const std::wstring &path, const PinState state); - static PlaceholderResult ConvertToPlaceholder(const std::wstring &fullPath, const std::wstring &serverIdentity); static std::string GetFileIdentity(const std::wstring &filePath); static void UpdateFileIdentity(const std::wstring &filePath, const std::wstring &fileIdentity, bool isDirectory); static FileState GetPlaceholderInfo(const std::wstring &directoryPath); diff --git a/include/virtual_drive/Wrappers.h b/include/virtual_drive/Wrappers.h index 89b1a850..07f269e7 100644 --- a/include/virtual_drive/Wrappers.h +++ b/include/virtual_drive/Wrappers.h @@ -2,12 +2,12 @@ #include -napi_value CreatePlaceholderFile(napi_env env, napi_callback_info args); +napi_value CreateFilePlaceholderWrapper(napi_env env, napi_callback_info args); +napi_value CreateFolderPlaceholderWrapper(napi_env env, napi_callback_info args); napi_value UnregisterSyncRootWrapper(napi_env env, napi_callback_info args); napi_value RegisterSyncRootWrapper(napi_env env, napi_callback_info args); napi_value GetRegisteredSyncRootsWrapper(napi_env env, napi_callback_info args); napi_value ConnectSyncRootWrapper(napi_env env, napi_callback_info args); -napi_value CreateEntryWrapper(napi_env env, napi_callback_info args); napi_value DisconnectSyncRootWrapper(napi_env env, napi_callback_info args); napi_value GetFileIdentityWrapper(napi_env env, napi_callback_info args); napi_value addLoggerPathWrapper(napi_env env, napi_callback_info args); diff --git a/include/virtual_drive/convert_to_placeholder.h b/include/virtual_drive/convert_to_placeholder.h index f9c610ff..164cc507 100644 --- a/include/virtual_drive/convert_to_placeholder.h +++ b/include/virtual_drive/convert_to_placeholder.h @@ -2,4 +2,5 @@ #include -napi_value convert_to_placeholder_impl(napi_env env, napi_callback_info args); +napi_value convert_to_placeholder_wrapper(napi_env env, napi_callback_info args); +void convert_to_placeholder(const std::wstring &path, const std::wstring &placeholderId); diff --git a/native-src/main.cpp b/native-src/main.cpp index d48873a4..e7d6f488 100644 --- a/native-src/main.cpp +++ b/native-src/main.cpp @@ -4,9 +4,9 @@ napi_value init(napi_env env, napi_value exports) { napi_property_descriptor desc = { - "createPlaceholderFile", + "createFilePlaceholder", nullptr, - CreatePlaceholderFile, + CreateFilePlaceholderWrapper, nullptr, nullptr, nullptr, @@ -88,20 +88,20 @@ napi_value init(napi_env env, napi_value exports) return nullptr; } - napi_property_descriptor createEntryDesc = { - "createEntry", + napi_property_descriptor createFolderPlaceholderDesc = { + "createFolderPlaceholder", nullptr, - CreateEntryWrapper, + CreateFolderPlaceholderWrapper, nullptr, nullptr, nullptr, napi_default, nullptr}; - napi_status defineCreateEntryStatus = napi_define_properties(env, exports, 1, &createEntryDesc); - if (defineCreateEntryStatus != napi_ok) + napi_status defineCreateFolderPlaceholderStatus = napi_define_properties(env, exports, 1, &createFolderPlaceholderDesc); + if (defineCreateFolderPlaceholderStatus != napi_ok) { - napi_throw_error(env, nullptr, "Failed to define createEntry function"); + napi_throw_error(env, nullptr, "Failed to define createFolderPlaceholder function"); return nullptr; } diff --git a/native-src/placeholders_interface/Planceholders.cpp b/native-src/placeholders_interface/Planceholders.cpp index 8c75966b..e12946e4 100644 --- a/native-src/placeholders_interface/Planceholders.cpp +++ b/native-src/placeholders_interface/Planceholders.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "convert_to_placeholder.h" using namespace std; @@ -22,81 +23,6 @@ namespace fs = std::filesystem; #pragma comment(lib, "shlwapi.lib") -bool DirectoryExists(const wchar_t *path) -{ - DWORD attributes = GetFileAttributesW(path); - return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY); -} - -PlaceholderResult Placeholders::CreateOne( - const wchar_t *fileName, - const wchar_t *fileIdentity, - int64_t fileSize, - LARGE_INTEGER creationTime, - LARGE_INTEGER lastWriteTime, - LARGE_INTEGER lastAccessTime, - const wchar_t *destPath) -{ - PlaceholderResult result = {false, L""}; - - try - { - CF_PLACEHOLDER_CREATE_INFO cloudEntry = {}; - - std::wstring fullDestPath = std::wstring(destPath) + L'\\'; - - wstring fullPath = std::wstring(destPath) + L'\\' + fileName; - - if (std::filesystem::exists(fullPath)) - { - Placeholders::ConvertToPlaceholder(fullPath, fileIdentity); - Placeholders::MaintainIdentity(fullPath, fileIdentity, false); - result.success = true; - return result; - } - - std::wstring relativeName(fileIdentity); - - cloudEntry.FileIdentity = relativeName.c_str(); - cloudEntry.FileIdentityLength = static_cast((relativeName.size() + 1) * sizeof(WCHAR)); - - cloudEntry.RelativeFileName = fileName; - cloudEntry.Flags = CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC; - - cloudEntry.FsMetadata.FileSize.QuadPart = fileSize; - cloudEntry.FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; - cloudEntry.FsMetadata.BasicInfo.CreationTime = creationTime; - cloudEntry.FsMetadata.BasicInfo.LastWriteTime = lastWriteTime; - cloudEntry.FsMetadata.BasicInfo.LastAccessTime = lastAccessTime; - cloudEntry.FsMetadata.BasicInfo.ChangeTime = lastWriteTime; - - try - { - winrt::check_hresult(CfCreatePlaceholders(fullDestPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL)); - Placeholders::UpdatePinState(fullPath, PinState::OnlineOnly); - result.success = true; - } - catch (const winrt::hresult_error &error) - { - result.errorMessage = error.message().c_str(); - wprintf(L"[CreatePlaceholder] error: %s", error.message().c_str()); - } - winrt::StorageProviderItemProperty prop; - prop.Id(1); - prop.Value(L"Value1"); - prop.IconResource(L"shell32.dll,-44"); - - // UpdateSyncStatus(fullDestPath, true, false); - } - catch (...) - { - result.errorMessage = L"Failed to create or customize placeholder"; - wprintf(L"[CreatePlaceholder] Failed to create or customize placeholder with %08x\n", static_cast(winrt::to_hresult())); - } - - return result; -} - std::string cleanString(const std::string &str) { std::string cleanedStr; @@ -136,133 +62,6 @@ void Placeholders::MaintainIdentity(std::wstring &fullPath, PCWSTR itemIdentity, } } -PlaceholderResult Placeholders::CreateEntry( - const wchar_t *itemName, - const wchar_t *itemIdentity, - LARGE_INTEGER creationTime, - LARGE_INTEGER lastWriteTime, - LARGE_INTEGER lastAccessTime, - const wchar_t *destPath) -{ - PlaceholderResult result = {false, L""}; - - std::wstring fullDestPath = std::wstring(destPath) + L"\\" + std::wstring(itemName); - CF_PLACEHOLDER_CREATE_INFO cloudEntry = {}; - std::wstring relativeName(itemIdentity); - cloudEntry.FileIdentity = relativeName.c_str(); - cloudEntry.FileIdentityLength = static_cast((relativeName.size() + 1) * sizeof(WCHAR)); - cloudEntry.RelativeFileName = itemName; - cloudEntry.Flags = CF_PLACEHOLDER_CREATE_FLAG_DISABLE_ON_DEMAND_POPULATION; // -> desactive download on demand - cloudEntry.FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_DIRECTORY; - cloudEntry.FsMetadata.BasicInfo.CreationTime = creationTime; - cloudEntry.FsMetadata.BasicInfo.LastWriteTime = lastWriteTime; - cloudEntry.FsMetadata.BasicInfo.LastAccessTime = lastAccessTime; - - try - { - // TODO: si existe o es placeholder return - if (DirectoryExists(fullDestPath.c_str())) - { - Placeholders::ConvertToPlaceholder(fullDestPath, itemIdentity); - Placeholders::MaintainIdentity(fullDestPath, itemIdentity, true); - result.success = true; - return result; - } - - // wprintf(L"Create directory, full destination path: %ls, fullDestPath.c_str()"); - PathRemoveFileSpecW(&fullDestPath[0]); - HRESULT hr = CfCreatePlaceholders(fullDestPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL); - if (FAILED(hr)) - { - result.errorMessage = L"Failed to create placeholder directory"; - wprintf(L"[CreatePlaceholder] Failed to create placeholder directory with HRESULT 0x%08x\n", hr); - throw winrt::hresult_error(hr); - } - - std::wstring finalPath = std::wstring(destPath) + L"\\" + std::wstring(itemName); - Placeholders::UpdatePinState(finalPath, PinState::OnlineOnly); - UpdateSyncStatus(finalPath, true, true); - result.success = true; - } - catch (const winrt::hresult_error &error) - { - result.errorMessage = error.message().c_str(); - wprintf(L"[CreatePlaceholder] Error while creating %s: %s\n", L"directory", error.message().c_str()); - } - catch (...) - { - result.errorMessage = L"Unknown error occurred"; - wprintf(L"[CreatePlaceholder] Unknown error occurred\n"); - } - - return result; -} - -PlaceholderResult Placeholders::ConvertToPlaceholder(const std::wstring &fullPath, const std::wstring &serverIdentity) -{ - PlaceholderResult result = {false, L""}; - - if (!std::filesystem::exists(fullPath)) - { - result.errorMessage = L"File does not exist"; - return result; - } - - wprintf(L"[ConvertToPlaceholder] Full path: %ls\n", fullPath.c_str()); - bool isDirectory = fs::is_directory(fullPath); - - HANDLE fileHandle = CreateFileW( - fullPath.c_str(), - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - nullptr, - OPEN_EXISTING, - isDirectory ? FILE_FLAG_BACKUP_SEMANTICS : 0, - nullptr); - - if (fileHandle == INVALID_HANDLE_VALUE) - { - result.errorMessage = L"Failed to open file: " + std::to_wstring(GetLastError()); - return result; - } - - CF_CONVERT_FLAGS convertFlags = CF_CONVERT_FLAG_MARK_IN_SYNC; - USN convertUsn; - OVERLAPPED overlapped = {}; - - LPCVOID idStrLPCVOID = static_cast(serverIdentity.c_str()); - DWORD idStrByteLength = static_cast(serverIdentity.size() * sizeof(wchar_t)); - - HRESULT hr = CfConvertToPlaceholder(fileHandle, idStrLPCVOID, idStrByteLength, convertFlags, &convertUsn, &overlapped); - - if (FAILED(hr)) - { - CloseHandle(fileHandle); - if (hr != 0x8007017C) // Ignorar error especĂ­fico de "ya es un placeholder" - { - result.errorMessage = L"Failed to convert to placeholder. HRESULT: 0x" + std::to_wstring(static_cast(hr)); - return result; - } - return result; - } - - if (!isDirectory) - { - HRESULT hrPinState = CfSetPinState(fileHandle, CF_PIN_STATE_PINNED, CF_SET_PIN_FLAG_NONE, nullptr); - if (FAILED(hrPinState)) - { - CloseHandle(fileHandle); - result.errorMessage = L"Failed to set pin state. HRESULT: 0x" + std::to_wstring(static_cast(hrPinState)); - return result; - } - } - - CloseHandle(fileHandle); - wprintf(L"[ConvertToPlaceholder] Successfully converted to placeholder: %ls\n", fullPath.c_str()); - result.success = true; - return result; -} - /** * @brief Mark a file or directory as synchronized * @param filePath path to the file or directory @@ -315,7 +114,7 @@ void Placeholders::UpdateSyncStatus(const std::wstring &filePath, break; case ERROR_CLOUD_FILE_NOT_IN_SYNC: - ConvertToPlaceholder(filePath, L"temp_identity"); + convert_to_placeholder(filePath, L"temp_identity"); hr = CfSetInSyncState(h, sync, CF_SET_IN_SYNC_FLAG_NONE, nullptr); wprintf(L"[UpdateSyncStatus] Retry CfSetInSyncState\n"); break; diff --git a/native-src/virtual_drive/Wrappers.cpp b/native-src/virtual_drive/Wrappers.cpp index fe3d40b3..ecf1513a 100644 --- a/native-src/virtual_drive/Wrappers.cpp +++ b/native-src/virtual_drive/Wrappers.cpp @@ -23,7 +23,7 @@ #include "update_sync_status_wrapper.h" #include "NAPI_SAFE_WRAP.h" -napi_value CreatePlaceholderFile(napi_env env, napi_callback_info args) { +napi_value CreateFilePlaceholderWrapper(napi_env env, napi_callback_info args) { return NAPI_SAFE_WRAP(env, args, create_file_placeholder_impl); } @@ -43,7 +43,7 @@ napi_value ConnectSyncRootWrapper(napi_env env, napi_callback_info args) { return NAPI_SAFE_WRAP(env, args, connect_sync_root_impl); } -napi_value CreateEntryWrapper(napi_env env, napi_callback_info args) { +napi_value CreateFolderPlaceholderWrapper(napi_env env, napi_callback_info args) { return NAPI_SAFE_WRAP(env, args, create_folder_placeholder_impl); } @@ -104,7 +104,7 @@ napi_value GetPlaceholderStateWrapper(napi_env env, napi_callback_info args) { } napi_value ConvertToPlaceholderWrapper(napi_env env, napi_callback_info args) { - return NAPI_SAFE_WRAP(env, args, convert_to_placeholder_impl); + return NAPI_SAFE_WRAP(env, args, convert_to_placeholder_wrapper); } napi_value HydrateFileWrapper(napi_env env, napi_callback_info args) { diff --git a/native-src/virtual_drive/convert_to_placeholder.cpp b/native-src/virtual_drive/convert_to_placeholder.cpp index 36f4ca51..7d617b5a 100644 --- a/native-src/virtual_drive/convert_to_placeholder.cpp +++ b/native-src/virtual_drive/convert_to_placeholder.cpp @@ -1,29 +1,47 @@ -#include +#include +#include +#include "stdafx.h" #include "napi_extract_args.h" -#include "Placeholders.h" -napi_value convert_to_placeholder_impl(napi_env env, napi_callback_info info) { - auto [path, serverIdentity] = napi_extract_args(env, info); +void convert_to_placeholder(const std::wstring &path, const std::wstring &placeholderId) +{ + bool isDirectory = std::filesystem::is_directory(path); - std::wstring wPath(path.begin(), path.end()); - std::wstring wServerIdentity(serverIdentity.begin(), serverIdentity.end()); + winrt::file_handle fileHandle{CreateFileW( + path.c_str(), + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, + OPEN_EXISTING, + isDirectory ? FILE_FLAG_BACKUP_SEMANTICS : 0, + nullptr)}; - PlaceholderResult result = Placeholders::ConvertToPlaceholder(wPath, wServerIdentity); + if (!fileHandle) + { + throw std::runtime_error("Failed to open item: " + std::to_string(GetLastError())); + } + + CF_CONVERT_FLAGS convertFlags = CF_CONVERT_FLAG_MARK_IN_SYNC; + USN convertUsn; + OVERLAPPED overlapped = {}; - napi_value resultObj; - napi_create_object(env, &resultObj); + LPCVOID idStrLPCVOID = static_cast(placeholderId.c_str()); + DWORD idStrByteLength = static_cast(placeholderId.size() * sizeof(wchar_t)); - napi_value successValue; - napi_get_boolean(env, result.success, &successValue); - napi_set_named_property(env, resultObj, "success", successValue); + HRESULT hr = CfConvertToPlaceholder(fileHandle.get(), idStrLPCVOID, idStrByteLength, convertFlags, &convertUsn, &overlapped); - if (!result.success) + // Only throw if it's not "already a placeholder" error + if (hr != 0x8007017C) { - std::string errorMessage(result.errorMessage.begin(), result.errorMessage.end()); - napi_value errorValue; - napi_create_string_utf8(env, errorMessage.c_str(), errorMessage.length(), &errorValue); - napi_set_named_property(env, resultObj, "errorMessage", errorValue); + winrt::check_hresult(hr); } +} + +napi_value convert_to_placeholder_wrapper(napi_env env, napi_callback_info info) +{ + auto [path, placeholderId] = napi_extract_args(env, info); + + convert_to_placeholder(path.c_str(), placeholderId.c_str()); - return resultObj; + return nullptr; } diff --git a/native-src/virtual_drive/create_file_placeholder.cpp b/native-src/virtual_drive/create_file_placeholder.cpp index 93cc8f41..ffa8642e 100644 --- a/native-src/virtual_drive/create_file_placeholder.cpp +++ b/native-src/virtual_drive/create_file_placeholder.cpp @@ -1,42 +1,42 @@ -#include +#include +#include #include "Placeholders.h" +#include "convert_to_placeholder.h" #include "Utilities.h" #include "napi_extract_args.h" napi_value create_file_placeholder_impl(napi_env env, napi_callback_info info) { - auto [fileName, fileIdentity, fileSize, creationTimeMs, lastWriteTimeMs, lastAccessTimeMs, destPath] = + auto [name, placeholderId, fileSize, creationTimeMs, lastWriteTimeMs, lastAccessTimeMs, parentPath] = napi_extract_args(env, info); LARGE_INTEGER creationTime = Utilities::JsTimestampToLargeInteger(creationTimeMs); LARGE_INTEGER lastWriteTime = Utilities::JsTimestampToLargeInteger(lastWriteTimeMs); LARGE_INTEGER lastAccessTime = Utilities::JsTimestampToLargeInteger(lastAccessTimeMs); - PlaceholderResult result = Placeholders::CreateOne( - fileName.c_str(), - fileIdentity.c_str(), - fileSize, - creationTime, - lastWriteTime, - lastAccessTime, - destPath.c_str()); + std::wstring path = parentPath + L'\\' + name; - // Create result object - napi_value resultObj; - napi_create_object(env, &resultObj); - - // Add success property - napi_value successValue; - napi_get_boolean(env, result.success, &successValue); - napi_set_named_property(env, resultObj, "success", successValue); - - // Add errorMessage property if there is an error - if (!result.success && !result.errorMessage.empty()) + if (std::filesystem::exists(path)) { - napi_value errorMessageValue; - napi_create_string_utf16(env, reinterpret_cast(result.errorMessage.c_str()), result.errorMessage.length(), &errorMessageValue); - napi_set_named_property(env, resultObj, "errorMessage", errorMessageValue); + convert_to_placeholder(path, placeholderId); + Placeholders::MaintainIdentity(path, placeholderId.c_str(), false); + return nullptr; } - return resultObj; + CF_PLACEHOLDER_CREATE_INFO cloudEntry = {}; + cloudEntry.FileIdentity = placeholderId.c_str(); + cloudEntry.FileIdentityLength = static_cast((placeholderId.size() + 1) * sizeof(WCHAR)); + cloudEntry.RelativeFileName = name.c_str(); + cloudEntry.Flags = CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC; + cloudEntry.FsMetadata.FileSize.QuadPart = fileSize; + cloudEntry.FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; + cloudEntry.FsMetadata.BasicInfo.CreationTime = creationTime; + cloudEntry.FsMetadata.BasicInfo.LastWriteTime = lastWriteTime; + cloudEntry.FsMetadata.BasicInfo.LastAccessTime = lastAccessTime; + cloudEntry.FsMetadata.BasicInfo.ChangeTime = lastWriteTime; + + winrt::check_hresult(CfCreatePlaceholders(parentPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL)); + // Placeholders::UpdatePinState(path, PinState::OnlineOnly); + + return nullptr; } \ No newline at end of file diff --git a/native-src/virtual_drive/create_folder_placeholder.cpp b/native-src/virtual_drive/create_folder_placeholder.cpp index 93ec87e0..5580f204 100644 --- a/native-src/virtual_drive/create_folder_placeholder.cpp +++ b/native-src/virtual_drive/create_folder_placeholder.cpp @@ -1,41 +1,41 @@ -#include +#include +#include #include "Placeholders.h" +#include "convert_to_placeholder.h" #include "Utilities.h" #include "napi_extract_args.h" napi_value create_folder_placeholder_impl(napi_env env, napi_callback_info info) { - auto [folderName, folderIdentity, creationTimeMs, lastWriteTimeMs, lastAccessTimeMs, destPath] = + auto [name, placeholderId, creationTimeMs, lastWriteTimeMs, lastAccessTimeMs, parentPath] = napi_extract_args(env, info); LARGE_INTEGER creationTime = Utilities::JsTimestampToLargeInteger(creationTimeMs); LARGE_INTEGER lastWriteTime = Utilities::JsTimestampToLargeInteger(lastWriteTimeMs); LARGE_INTEGER lastAccessTime = Utilities::JsTimestampToLargeInteger(lastAccessTimeMs); - PlaceholderResult result = Placeholders::CreateEntry( - folderName.c_str(), - folderIdentity.c_str(), - creationTime, - lastWriteTime, - lastAccessTime, - destPath.c_str()); + std::wstring path = parentPath + L'\\' + name; - // Create result object - napi_value resultObj; - napi_create_object(env, &resultObj); - - // Add success property - napi_value successValue; - napi_get_boolean(env, result.success, &successValue); - napi_set_named_property(env, resultObj, "success", successValue); - - // Add errorMessage property if there is an error - if (!result.success && !result.errorMessage.empty()) + if (std::filesystem::exists(path)) { - napi_value errorMessageValue; - napi_create_string_utf16(env, reinterpret_cast(result.errorMessage.c_str()), result.errorMessage.length(), &errorMessageValue); - napi_set_named_property(env, resultObj, "errorMessage", errorMessageValue); + convert_to_placeholder(path, placeholderId); + Placeholders::MaintainIdentity(path, placeholderId.c_str(), true); + return nullptr; } - return resultObj; + CF_PLACEHOLDER_CREATE_INFO cloudEntry = {}; + cloudEntry.FileIdentity = placeholderId.c_str(); + cloudEntry.FileIdentityLength = static_cast((placeholderId.size() + 1) * sizeof(WCHAR)); + cloudEntry.RelativeFileName = name.c_str(); + cloudEntry.Flags = CF_PLACEHOLDER_CREATE_FLAG_DISABLE_ON_DEMAND_POPULATION; // Deactivate download on demand + cloudEntry.FsMetadata.BasicInfo.FileAttributes = FILE_ATTRIBUTE_DIRECTORY; + cloudEntry.FsMetadata.BasicInfo.CreationTime = creationTime; + cloudEntry.FsMetadata.BasicInfo.LastWriteTime = lastWriteTime; + cloudEntry.FsMetadata.BasicInfo.LastAccessTime = lastAccessTime; + + winrt::check_hresult(CfCreatePlaceholders(parentPath.c_str(), &cloudEntry, 1, CF_CREATE_FLAG_NONE, NULL)); + // Placeholders::UpdatePinState(path, PinState::OnlineOnly); + // UpdateSyncStatus(path, true, true); + + return nullptr; } diff --git a/package.json b/package.json index 526a6ced..0588ecc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@internxt/node-win", - "version": "1.0.25", + "version": "1.0.26", "author": "Internxt ", "description": "Drive desktop node addon", "main": "dist/index.js",