From 290a9d470f929046f6a23cd19faa5a536ddd99c4 Mon Sep 17 00:00:00 2001 From: Pixo Date: Wed, 20 Sep 2023 18:55:51 +0200 Subject: [PATCH 001/188] [PB-981]:(feature) Display banner for Desktop MacOS 2.0.0 download --- src/renderer/localize/locales/en.json | 4 + .../Widget/MacOSVersionAvailableBanner.tsx | 77 +++++++++++++++++++ src/renderer/pages/Widget/index.tsx | 6 ++ 3 files changed, 87 insertions(+) create mode 100644 src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx diff --git a/src/renderer/localize/locales/en.json b/src/renderer/localize/locales/en.json index 0d8ce4b20..6cb6c9570 100644 --- a/src/renderer/localize/locales/en.json +++ b/src/renderer/localize/locales/en.json @@ -123,6 +123,10 @@ } }, "widget": { + "macos-available": { + "title": "Desktop v2.0 is already here!", + "message": "The native macOS app is faster and more efficient, install it today" + }, "header": { "usage": { "of": "of", diff --git a/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx b/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx new file mode 100644 index 000000000..55d67b62d --- /dev/null +++ b/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx @@ -0,0 +1,77 @@ +import { ArrowRight } from '@phosphor-icons/react'; +import React, { useEffect, useState } from 'react'; +import { useTranslationContext } from '../../context/LocalContext'; +import { reportError } from '../../utils/errors'; + +interface AssetInfo { + browser_download_url: string; +} + +interface LatestReleaseInfo { + id: number; + name: string; + published_at: Date; + assets: AssetInfo[]; +} + +export async function getLatestReleaseInfo( + user: string, + repo: string +): Promise { + const fetchUrl = `https://api.github.com/repos/${user}/${repo}/releases/latest`; + const res = await fetch(fetchUrl); + + if (res.status !== 200) { + throw Error('Release not found'); + } + + const info: LatestReleaseInfo = await res.json(); + + let url: string | undefined = undefined; + info.assets.forEach((asset) => { + const match = asset.browser_download_url.match(/\.(\w+)$/); + + if (match && match[1]) { + url = asset.browser_download_url; + } + }); + + return url; +} + +export const MacOSVersionAvailableBanner: React.FC = () => { + const { translate } = useTranslationContext(); + const [downloadURL, setDownloadURL] = useState(); + useEffect(() => { + getLatestReleaseInfo('internxt', 'drive-desktop-macos') + .then(setDownloadURL) + .catch(reportError); + }, []); + + const handleDownloadMacOSNative = () => { + try { + if (!downloadURL) return; + window.electron.openUrl(downloadURL); + } catch (error) { + reportError(error); + } + }; + return ( +
+
+

+ {translate('widget.macos-available.title')} +

+

+ {translate('widget.macos-available.message')} +

+
+
+ +
+
+ ); +}; diff --git a/src/renderer/pages/Widget/index.tsx b/src/renderer/pages/Widget/index.tsx index eaced4505..74c16c402 100644 --- a/src/renderer/pages/Widget/index.tsx +++ b/src/renderer/pages/Widget/index.tsx @@ -9,10 +9,15 @@ import { SyncStatus } from '../../../main/background-processes/sync'; import { SyncFailed } from './SyncFailed'; import useVirtualDriveStatus from 'renderer/hooks/VirtualDriveStatus'; import { VirtualDriveError } from './VirtualDriveError'; +import { MacOSVersionAvailableBanner } from './MacOSVersionAvailableBanner'; +import useClientPlatform from '../../hooks/ClientPlatform'; export default function Widget() { const [syncStatus, setSyncStatus] = useState('RUNNING'); useSyncStatus(setSyncStatus); + + const platform = useClientPlatform(); + const { status: virtualDriveStatus } = useVirtualDriveStatus(); const handleRetrySync = () => { window.electron.startRemoteSync().catch((err) => { @@ -50,6 +55,7 @@ export default function Widget() { return (
+ {platform === 'darwin' ? : null} {displayErrorInWidget ? renderWidgetError() : } From 78d615e117b083c8544cea0b0bbbde48cb3e2600 Mon Sep 17 00:00:00 2001 From: Pixo Date: Wed, 20 Sep 2023 18:59:35 +0200 Subject: [PATCH 002/188] [PB-981]:(feature) Add ES and FR translations --- src/renderer/localize/locales/es.json | 4 ++++ src/renderer/localize/locales/fr.json | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/renderer/localize/locales/es.json b/src/renderer/localize/locales/es.json index c3aa42ac3..d0bc0943c 100644 --- a/src/renderer/localize/locales/es.json +++ b/src/renderer/localize/locales/es.json @@ -123,6 +123,10 @@ } }, "widget": { + "macos-available": { + "title": "Desktop v2.0 está disponible!", + "message": "La versión nativa de MacOS es más rapida y eficiente, instálala hoy" + }, "header": { "usage": { "of": "de", diff --git a/src/renderer/localize/locales/fr.json b/src/renderer/localize/locales/fr.json index 1a75f91bf..c795642aa 100644 --- a/src/renderer/localize/locales/fr.json +++ b/src/renderer/localize/locales/fr.json @@ -123,6 +123,10 @@ } }, "widget": { + "macos-available": { + "title": "Desktop v2.0 est disponible!", + "message": "L'application native de macOS est plus rapide et plus efficace, installez-la dès aujourd'hui" + }, "header": { "usage": { "of": "de", From 9d70ef5f0301cf08bff7a1cba86805c832e3ff85 Mon Sep 17 00:00:00 2001 From: Pixo Date: Wed, 20 Sep 2023 19:02:22 +0200 Subject: [PATCH 003/188] [PB-981]:(feature) Fix open url await --- src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx b/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx index 55d67b62d..0f9e18e72 100644 --- a/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx +++ b/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx @@ -48,10 +48,10 @@ export const MacOSVersionAvailableBanner: React.FC = () => { .catch(reportError); }, []); - const handleDownloadMacOSNative = () => { + const handleDownloadMacOSNative = async () => { try { if (!downloadURL) return; - window.electron.openUrl(downloadURL); + await window.electron.openUrl(downloadURL); } catch (error) { reportError(error); } From 4a9c29b0120003842eb8603c0f3da3edeb343c28 Mon Sep 17 00:00:00 2001 From: Pixo Date: Thu, 21 Sep 2023 11:51:58 +0200 Subject: [PATCH 004/188] [PB-981]:(feature) Use Internxt website API to grab download URLs --- src/main/app-info/handlers.ts | 7 +++ src/main/background-processes/webdav.ts | 21 +++------ src/main/preload.d.ts | 1 + src/main/preload.js | 3 ++ .../Widget/MacOSVersionAvailableBanner.tsx | 43 +++---------------- 5 files changed, 23 insertions(+), 52 deletions(-) diff --git a/src/main/app-info/handlers.ts b/src/main/app-info/handlers.ts index 38ad065e1..aeaa9e68b 100644 --- a/src/main/app-info/handlers.ts +++ b/src/main/app-info/handlers.ts @@ -1,9 +1,16 @@ import { ipcMain, app } from 'electron'; import { executeQuery } from './service'; +import axios from 'axios'; ipcMain.handle('execute-app-query', (_, query) => executeQuery(query)); +ipcMain.handle('get-download-urls', async () => { + const response = await axios.get('https://internxt.com/api/download'); + + return response.data; +}); + ipcMain.handle('get-path', (_, path) => { const result = app.getPath(path); return result; diff --git a/src/main/background-processes/webdav.ts b/src/main/background-processes/webdav.ts index dca8b9b18..05a86fcb7 100644 --- a/src/main/background-processes/webdav.ts +++ b/src/main/background-processes/webdav.ts @@ -3,8 +3,10 @@ import { ipcWebdav } from '../ipcs/webdav'; import path from 'path'; import Logger from 'electron-log'; import eventBus from '../event-bus'; -import { ejectMacOSInstallerDisks, unmountDrive } from '../../workers/webdav/VirtualDrive'; - +import { + ejectMacOSInstallerDisks, + unmountDrive, +} from '../../workers/webdav/VirtualDrive'; let webdavWorker: BrowserWindow | null = null; @@ -47,19 +49,8 @@ function stopWebDavServer() { webdavWorker?.webContents.send('STOP_WEBDAV_SERVER_PROCESS'); } -function startWebDavServer() { - webdavWorker?.webContents.send('START_WEBDAV_SERVER_PROCESS'); -} - eventBus.on('USER_LOGGED_OUT', stopWebDavServer); eventBus.on('USER_WAS_UNAUTHORIZED', stopWebDavServer); -eventBus.on('USER_LOGGED_IN', () => { - if (webdavWorker === null) { - spawnWebdavServerWorker(); - } else { - startWebDavServer(); - } -}); if (process.platform === 'darwin') { eventBus.on('APP_IS_READY', ejectMacOSInstallerDisks); @@ -72,6 +63,8 @@ ipcMain.handle('retry-virtual-drive-mount', () => { ipcMain.handle('unmount-virtual-drive-and-quit', async () => { try { await unmountDrive(); - } catch (onMenuQuitClickError) { Logger.error({ onMenuQuitClickError }); }; + } catch (onMenuQuitClickError) { + Logger.error({ onMenuQuitClickError }); + } await app.quit(); }); diff --git a/src/main/preload.d.ts b/src/main/preload.d.ts index b06123409..9436c7261 100644 --- a/src/main/preload.d.ts +++ b/src/main/preload.d.ts @@ -205,6 +205,7 @@ declare interface Window { retryVirtualDriveMount(): void; unmountVirtualDriveAndQuit: () => Promise; startRemoteSync: () => Promise; + getDownloadUrls: () => Promise<{ platforms: Record }>; openUrl: (url: string) => Promise; // DEV resizeWindow: () => typeof import('../main/dev/service').resizeCurrentWindow; diff --git a/src/main/preload.js b/src/main/preload.js index 6d20cbf0b..40e40d7ed 100644 --- a/src/main/preload.js +++ b/src/main/preload.js @@ -287,6 +287,9 @@ contextBridge.exposeInMainWorld('electron', { unmountVirtualDriveAndQuit() { return ipcRenderer.invoke('unmount-virtual-drive-and-quit'); }, + getDownloadUrls() { + return ipcRenderer.invoke('get-download-urls'); + }, onVirtualDriveStatusChange(callback) { const eventName = 'virtual-drive-status-change'; const callbackWrapper = (_, v) => { diff --git a/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx b/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx index 0f9e18e72..4d36b5927 100644 --- a/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx +++ b/src/renderer/pages/Widget/MacOSVersionAvailableBanner.tsx @@ -3,49 +3,16 @@ import React, { useEffect, useState } from 'react'; import { useTranslationContext } from '../../context/LocalContext'; import { reportError } from '../../utils/errors'; -interface AssetInfo { - browser_download_url: string; -} - -interface LatestReleaseInfo { - id: number; - name: string; - published_at: Date; - assets: AssetInfo[]; -} - -export async function getLatestReleaseInfo( - user: string, - repo: string -): Promise { - const fetchUrl = `https://api.github.com/repos/${user}/${repo}/releases/latest`; - const res = await fetch(fetchUrl); - - if (res.status !== 200) { - throw Error('Release not found'); - } - - const info: LatestReleaseInfo = await res.json(); - - let url: string | undefined = undefined; - info.assets.forEach((asset) => { - const match = asset.browser_download_url.match(/\.(\w+)$/); - - if (match && match[1]) { - url = asset.browser_download_url; - } - }); - - return url; -} +const getDownloadUrl = async () => { + const { platforms } = await window.electron.getDownloadUrls(); + return platforms['MacOS']; +}; export const MacOSVersionAvailableBanner: React.FC = () => { const { translate } = useTranslationContext(); const [downloadURL, setDownloadURL] = useState(); useEffect(() => { - getLatestReleaseInfo('internxt', 'drive-desktop-macos') - .then(setDownloadURL) - .catch(reportError); + getDownloadUrl().then(setDownloadURL).catch(reportError); }, []); const handleDownloadMacOSNative = async () => { From 1a66c30f92041033c0b4b9fdd8199a9f8a43206f Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 21 Sep 2023 13:36:02 +0200 Subject: [PATCH 005/188] chore: change app verion --- package.json | 2 +- release/app/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 951762cc7..fef01ee80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.11", + "version": "2.0.0", "author": "Internxt ", "description": "Internxt Drive client UI", "license": "AGPL-3.0", diff --git a/release/app/package.json b/release/app/package.json index 1eb40f149..ef47159ae 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.11", + "version": "2.0.0", "description": "Internxt Drive client UI", "main": "./dist/main/main.js", "author": "Internxt ", From 6abbd0eef4f19d637c06f0494c2ba2def954519c Mon Sep 17 00:00:00 2001 From: joan vicens Date: Wed, 18 Oct 2023 12:45:14 +0200 Subject: [PATCH 006/188] fix: skip traverse deleted or trashed folders --- .../items/application/AllStatusesTraverser.ts | 13 +++++++++++-- .../VirtualDrivePlaceholderCreator.ts | 10 ++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts b/src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts index 77756c2f5..869a21f2e 100644 --- a/src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts +++ b/src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts @@ -1,6 +1,9 @@ import Logger from 'electron-log'; import { ServerFile } from '../../../../filesystems/domain/ServerFile'; -import { ServerFolder } from '../../../../filesystems/domain/ServerFolder'; +import { + ServerFolder, + ServerFolderStatus, +} from '../../../../filesystems/domain/ServerFolder'; import { fileNameIsValid } from '../../../../utils/name-verification'; import { File } from '../../files/domain/File'; import { FolderStatus } from '../../folders/domain/FolderStatus'; @@ -113,7 +116,13 @@ export class AllStatusesTraverser implements Traverser { status: folder.status, }); - this.traverse(folder.id, `${name}`); + if (folder.status === ServerFolderStatus.EXISTS) { + // The folders and the files from trashed or deleted folders + // will have the status "EXISTS", to avoid filtering witch folders and files + // are in a deleted or trashed folder they not included on the collection. + // We cannot perform any action on them either way + this.traverse(folder.id, `${name}`); + } }); } diff --git a/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts b/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts index 4f22a53bc..972d21630 100644 --- a/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts +++ b/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts @@ -4,11 +4,17 @@ import { Folder } from '../../folders/domain/Folder'; import { PlaceholderCreator } from '../domain/PlaceholderCreator'; import { createFolderPlaceholderId } from '../domain/FolderPlaceholderId'; import { createFilePlaceholderId } from '../domain/FilePlaceholderId'; +import { FolderStatuses } from '../../folders/domain/FolderStatus'; +import { FileStatuses } from '../../files/domain/FileStatus'; export class VirtualDrivePlaceholderCreator implements PlaceholderCreator { constructor(private readonly drive: VirtualDrive) {} folder(folder: Folder): void { + if (!folder.hasStatus(FolderStatuses.EXISTS)) { + return; + } + const folderPath = `${folder.path.value}/`; const placeholderId = createFolderPlaceholderId(folder.uuid); @@ -23,6 +29,10 @@ export class VirtualDrivePlaceholderCreator implements PlaceholderCreator { } file(file: File): void { + if (!file.hasStatus(FileStatuses.EXISTS)) { + return; + } + const placeholderId = createFilePlaceholderId(file.contentsId); this.drive.createFileByPath( From 7bf68a05159f031381af134d3a4cf0946362a811 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Wed, 18 Oct 2023 15:10:00 +0200 Subject: [PATCH 007/188] fix: test --- .../EnvironmentContentFileDownloader.test.ts | 41 ------------------- .../test/application/FileDeleter.test.ts | 9 +++- .../test/application/FilePathUpdater.test.ts | 4 +- 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/src/workers/sync-engine/modules/contents/test/infrastructure/download/EnvironmentContentFileDownloader.test.ts b/src/workers/sync-engine/modules/contents/test/infrastructure/download/EnvironmentContentFileDownloader.test.ts index c6a7eff96..f37263e4a 100644 --- a/src/workers/sync-engine/modules/contents/test/infrastructure/download/EnvironmentContentFileDownloader.test.ts +++ b/src/workers/sync-engine/modules/contents/test/infrastructure/download/EnvironmentContentFileDownloader.test.ts @@ -79,45 +79,4 @@ describe('Environment Content File Downloader', () => { }); }); }); - - describe('time watcher', () => { - it('starts the timer when the file is downloaded', async () => { - const strategy = createDownloadStrategy((callbacks) => { - callbacks.progressCallback(50); - callbacks.finishedCallback(null as unknown as Error, Readable.from('')); - }); - - const downloader = new EnvironmentContentFileDownloader(strategy, bucket); - - downloader.on('progress', () => { - expect(downloader.elapsedTime()).toBeGreaterThan(-1); - }); - - expect(downloader.elapsedTime()).toBe(-1); - - await downloader.download(file); - }); - - it('stops the timer when the file is not downloaded', async () => { - const delay = 100; - const strategy = createDownloadStrategy((callbacks) => { - callbacks.progressCallback(50); - setTimeout(() => { - callbacks.finishedCallback( - null as unknown as Error, - Readable.from('') - ); - }, delay); - }); - - const downloader = new EnvironmentContentFileDownloader(strategy, bucket); - - await downloader.download(file); - - setTimeout(() => { - expect(downloader.elapsedTime()).toBeGreaterThan(delay - 10); - expect(downloader.elapsedTime()).toBeLessThan(delay + 10); - }, delay); - }); - }); }); diff --git a/src/workers/sync-engine/modules/files/test/application/FileDeleter.test.ts b/src/workers/sync-engine/modules/files/test/application/FileDeleter.test.ts index 85227f88a..6e91d53f6 100644 --- a/src/workers/sync-engine/modules/files/test/application/FileDeleter.test.ts +++ b/src/workers/sync-engine/modules/files/test/application/FileDeleter.test.ts @@ -33,12 +33,17 @@ describe('File Deleter', () => { ); }); - it('does not trash a file if its not found', async () => { + it('does not nothing if the file its not found', async () => { const contentsId = ContentsIdMother.raw(); repository.mockSearch.mockReturnValueOnce(undefined); + jest + .spyOn(allParentFoldersStatusIsExists, 'run') + .mockReturnValueOnce(false); - await expect(async () => await SUT.run(contentsId)).rejects.toThrow(); + await SUT.run(contentsId); + + expect(repository.mockDelete).not.toBeCalled(); }); it('does not delete a file if it has a parent already trashed', async () => { diff --git a/src/workers/sync-engine/modules/files/test/application/FilePathUpdater.test.ts b/src/workers/sync-engine/modules/files/test/application/FilePathUpdater.test.ts index 7fe852f40..f9ca946c9 100644 --- a/src/workers/sync-engine/modules/files/test/application/FilePathUpdater.test.ts +++ b/src/workers/sync-engine/modules/files/test/application/FilePathUpdater.test.ts @@ -6,8 +6,8 @@ import { FolderFinder } from '../../../folders/application/FolderFinder'; import { FolderFinderMock } from '../../../folders/test/__mocks__/FolderFinderMock'; import { FileFinderByContentsId } from '../../application/FileFinderByContentsId'; import { IpcRendererSyncEngineMock } from '../../../shared/test/__mock__/IpcRendererSyncEngineMock'; -import { LocalFileIdProvider } from 'workers/sync-engine/modules/shared/application/LocalFileIdProvider'; -import { EventBusMock } from 'workers/sync-engine/modules/shared/test/__mock__/EventBusMock'; +import { LocalFileIdProvider } from '../../../shared/application/LocalFileIdProvider'; +import { EventBusMock } from '../../../shared/test/__mock__/EventBusMock'; describe('File path updater', () => { let repository: FileRepositoryMock; From d9b847e3d79293ce21b3f8824368773050827824 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Wed, 18 Oct 2023 15:24:25 +0200 Subject: [PATCH 008/188] fix: tsc --- src/main/analytics/backup-handlers.ts | 2 +- src/main/preload.d.ts | 2 -- src/renderer/pages/ProcessIssues/List.tsx | 8 +------- src/renderer/pages/ProcessIssues/ReportModal.tsx | 7 ++++--- src/renderer/pages/ProcessIssues/index.tsx | 2 +- src/workers/backups/index.ts | 3 --- 6 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main/analytics/backup-handlers.ts b/src/main/analytics/backup-handlers.ts index 3900c192a..d28190578 100644 --- a/src/main/analytics/backup-handlers.ts +++ b/src/main/analytics/backup-handlers.ts @@ -79,6 +79,6 @@ ipcMain.on('BACKUP_ISSUE', (_, issue: BackupProgressIssue) => { } backupProcessInfo.errors[issue.folderId].push( - `${issue.errorName} error when ${issue.errorDetails.action}` + `${issue.errorName} error when ${issue}` ); }); diff --git a/src/main/preload.d.ts b/src/main/preload.d.ts index d22164a0a..ce1be4c90 100644 --- a/src/main/preload.d.ts +++ b/src/main/preload.d.ts @@ -205,7 +205,5 @@ declare interface Window { retryVirtualDriveMount(): void; startRemoteSync: () => Promise; openUrl: (url: string) => Promise; - // DEV - resizeWindow: () => typeof import('../main/dev/service').resizeCurrentWindow; }; } diff --git a/src/renderer/pages/ProcessIssues/List.tsx b/src/renderer/pages/ProcessIssues/List.tsx index e1917a562..d037a3b2b 100644 --- a/src/renderer/pages/ProcessIssues/List.tsx +++ b/src/renderer/pages/ProcessIssues/List.tsx @@ -18,7 +18,6 @@ import useFatalErrorActions from '../../hooks/FatalErrorActions'; import { generalErrors } from '../../messages/general-error'; import { shortMessages } from '../../messages/process-error'; import { getBaseName } from '../../utils/path'; -import Button from 'renderer/components/Button'; import { FatalError } from '../../components/Backups/FatalError'; export default function ProcessIssuesList({ @@ -34,9 +33,7 @@ export default function ProcessIssuesList({ backupFatalErrors: BackupFatalError[]; showBackupFatalErrors: boolean; selectedTab: 'SYNC' | 'BACKUPS' | 'GENERAL'; - onClickOnErrorInfo: ( - errorClicked: Pick - ) => void; + onClickOnErrorInfo: (errorClicked: Pick) => void; }) { const { translate } = useTranslationContext(); const [isLoading, setIsLoading] = useState(false); @@ -53,8 +50,6 @@ export default function ProcessIssuesList({ function onInfoClick(errorName: ProcessErrorName) { onClickOnErrorInfo({ errorName, - errorDetails: processIssues.find((i) => i.errorName === errorName)! - .errorDetails, }); } @@ -225,7 +220,6 @@ function Item({ issues, isSelected, onClick, - onInfoClick, }: { errorName: ProcessErrorName; issues: ProcessIssue[]; diff --git a/src/renderer/pages/ProcessIssues/ReportModal.tsx b/src/renderer/pages/ProcessIssues/ReportModal.tsx index e4829c459..7f539825d 100644 --- a/src/renderer/pages/ProcessIssues/ReportModal.tsx +++ b/src/renderer/pages/ProcessIssues/ReportModal.tsx @@ -2,7 +2,7 @@ import { Dialog, Transition } from '@headlessui/react'; import { Fragment, useState } from 'react'; import { useTranslationContext } from 'renderer/context/LocalContext'; -import { ProcessIssue } from '../../../workers/types'; +import { ErrorDetails, ProcessIssue } from '../../../workers/types'; import { longMessages, shortMessages } from '../../messages/process-error'; import Button from 'renderer/components/Button'; import TextArea from 'renderer/components/TextArea'; @@ -26,7 +26,7 @@ export function ReportModal({ data, onClose, }: { - data: Pick | null; + data: Pick | null; onClose: () => void; }) { const { translate } = useTranslationContext(); @@ -68,8 +68,9 @@ export function ReportModal({ async function handleSubmit() { setRequestState('SENDING'); + // Send reports throw the issues windows was disabled const result = await window.electron.sendReport({ - errorDetails: data!.errorDetails, + errorDetails: {} as ErrorDetails, userComment, includeLogs, }); diff --git a/src/renderer/pages/ProcessIssues/index.tsx b/src/renderer/pages/ProcessIssues/index.tsx index 8c85bb8df..2ae3e1b57 100644 --- a/src/renderer/pages/ProcessIssues/index.tsx +++ b/src/renderer/pages/ProcessIssues/index.tsx @@ -19,7 +19,7 @@ export default function ProcessIssues() { const { backupFatalErrors } = useBackupFatalErrors(); const [reportData, setReportData] = useState | null>(null); const [activeSection, setActiveSection] = useState
('SYNC'); diff --git a/src/workers/backups/index.ts b/src/workers/backups/index.ts index 41a9b0740..5cae18f66 100644 --- a/src/workers/backups/index.ts +++ b/src/workers/backups/index.ts @@ -123,7 +123,6 @@ async function setUp() { kind, name, errorName, - errorDetails, process: 'BACKUPS', folderId, }); @@ -174,7 +173,6 @@ async function setUp() { kind, name, errorName, - errorDetails, process: 'BACKUPS', folderId, }); @@ -214,7 +212,6 @@ async function setUp() { kind, name, errorName, - errorDetails, process: 'BACKUPS', folderId, }); From 213e2ebb29c52d8f5eb8779698684c175d5b180d Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Wed, 18 Oct 2023 18:43:08 +0200 Subject: [PATCH 009/188] added placeholder trim id --- .../controllers/CallbackController.ts | 11 ++++------- .../modules/placeholders/domain/CommonPlaceholder.ts | 8 ++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 src/workers/sync-engine/modules/placeholders/domain/CommonPlaceholder.ts diff --git a/src/workers/sync-engine/callbacks-controllers/controllers/CallbackController.ts b/src/workers/sync-engine/callbacks-controllers/controllers/CallbackController.ts index 4395fec3e..ec654d257 100644 --- a/src/workers/sync-engine/callbacks-controllers/controllers/CallbackController.ts +++ b/src/workers/sync-engine/callbacks-controllers/controllers/CallbackController.ts @@ -1,3 +1,4 @@ +import { trimPlaceholderId } from '../../modules/placeholders/domain/CommonPlaceholder'; import { FilePlaceholderId, isFilePlaceholderId, @@ -9,17 +10,13 @@ import { export abstract class CallbackController { protected trim(id: string): string { - return id.replace( - // eslint-disable-next-line no-control-regex - /[\x00-\x1F\x7F-\x9F]/g, - '' - ); + return trimPlaceholderId(id); } protected isFilePlaceholder(id: string): id is FilePlaceholderId { // make sure the id is trimmed before comparing // if it was already trimmed should not change its length - const trimmed = this.trim(id); + const trimmed = trimPlaceholderId(id); return isFilePlaceholderId(trimmed); } @@ -27,7 +24,7 @@ export abstract class CallbackController { protected isFolderPlaceholder(id: string): id is FolderPlaceholderId { // make sure the id is trimmed before comparing // if it was already trimmed should not change its length - const trimmed = this.trim(id); + const trimmed = trimPlaceholderId(id); return isFolderPlaceholderId(trimmed); } diff --git a/src/workers/sync-engine/modules/placeholders/domain/CommonPlaceholder.ts b/src/workers/sync-engine/modules/placeholders/domain/CommonPlaceholder.ts new file mode 100644 index 000000000..f8039c884 --- /dev/null +++ b/src/workers/sync-engine/modules/placeholders/domain/CommonPlaceholder.ts @@ -0,0 +1,8 @@ + +export function trimPlaceholderId(id: string): string { + return id.replace( + // eslint-disable-next-line no-control-regex + /[\x00-\x1F\x7F-\x9F]/g, + '' + ).normalize(); +} From e0b94d50671e9db9c42aa88689028b0607a01899 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Wed, 18 Oct 2023 18:47:30 +0200 Subject: [PATCH 010/188] added refresh placeholders on real time sync --- .../dependency-injection/boundaryBridge/build.ts | 5 ++++- .../boundaryBridge/application/SyncPlaceholders.ts | 13 ++++++++++--- .../placeholders/domain/FilePlaceholderId.ts | 9 +++++---- .../placeholders/domain/FolderPlaceholderId.ts | 9 +++++---- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts b/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts index c9078afb3..1706e361f 100644 --- a/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts +++ b/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts @@ -11,6 +11,7 @@ import { SharedContainer } from '../shared/SharedContainer'; import { SyncPlaceholders } from 'workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders'; import { UpdatePlaceholderFolder } from 'workers/sync-engine/modules/boundaryBridge/application/UpdatePlaceholderFolder'; import { DependencyInjectionEventRepository } from '../common/eventRepository'; +import { DependencyInjectionVirtualDrive } from '../common/virtualDrive'; export function buildBoundaryBridgeContainer( contentsContainer: ContentsContainer, @@ -21,6 +22,7 @@ export function buildBoundaryBridgeContainer( sharedContainer: SharedContainer ): BoundaryBridgeContainer { const eventHistory = DependencyInjectionEventRepository.get(); + const virtualDrive = DependencyInjectionVirtualDrive.virtualDrive; const fileCreationOrchestrator = new FileCreationOrchestrator( contentsContainer.contentsUploader, @@ -52,7 +54,8 @@ export function buildBoundaryBridgeContainer( const syncPlaceholders = new SyncPlaceholders( itemsContainer.allStatusesTreeBuilder, syncRemoteFile, - syncRemoteFolder + syncRemoteFolder, + virtualDrive, ); return { diff --git a/src/workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders.ts b/src/workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders.ts index ac385a7bf..628f4034e 100644 --- a/src/workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders.ts +++ b/src/workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders.ts @@ -3,19 +3,26 @@ import { UpdatePlaceholderFolder } from './UpdatePlaceholderFolder'; import { File } from '../../files/domain/File'; import { Folder } from '../../folders/domain/Folder'; import { TreeBuilder } from '../../items/application/TreeBuilder'; +import { VirtualDrive } from 'virtual-drive/dist'; +import { trimPlaceholderId } from '../../placeholders/domain/CommonPlaceholder'; +import { FilePlaceholderIdPrefix } from '../../placeholders/domain/FilePlaceholderId'; +import { FolderPlaceholderIdPrefix } from '../../placeholders/domain/FolderPlaceholderId'; export class SyncPlaceholders { constructor( private readonly treeBuilder: TreeBuilder, private readonly updatePlaceholderFile: UpdatePlaceholderFile, - private readonly updatePlaceholderFolder: UpdatePlaceholderFolder + private readonly updatePlaceholderFolder: UpdatePlaceholderFolder, + private readonly virtualDrive: VirtualDrive ) {} async run() { const tree = await this.treeBuilder.run(); + const listPlaceholdersIds = (await this.virtualDrive.getItemsIds()).map(id => trimPlaceholderId(id)); + const folders = Object.values(tree).filter((item) => - item.isFolder() + item.isFolder() && listPlaceholdersIds.includes(FolderPlaceholderIdPrefix + item.uuid) ) as Array; const foldersActualization = folders.map((folder) => { @@ -25,7 +32,7 @@ export class SyncPlaceholders { await Promise.all(foldersActualization); const files = Object.values(tree).filter((item) => - item.isFile() + item.isFile() && listPlaceholdersIds.includes(FilePlaceholderIdPrefix + item.contentsId) ) as Array; const filesActualization = files.map((file) => diff --git a/src/workers/sync-engine/modules/placeholders/domain/FilePlaceholderId.ts b/src/workers/sync-engine/modules/placeholders/domain/FilePlaceholderId.ts index f78cec85c..d67b5b95c 100644 --- a/src/workers/sync-engine/modules/placeholders/domain/FilePlaceholderId.ts +++ b/src/workers/sync-engine/modules/placeholders/domain/FilePlaceholderId.ts @@ -1,10 +1,11 @@ -export type FilePlaceholderIdPrefix = 'FILE:'; +export type FilePlaceholderIdPrefixType = 'FILE:'; +export const FilePlaceholderIdPrefix = 'FILE:'; -export type FilePlaceholderId = `${FilePlaceholderIdPrefix}${string}`; +export type FilePlaceholderId = `${FilePlaceholderIdPrefixType}${string}`; function typedCheck( input: string, - prefix: FilePlaceholderIdPrefix = 'FILE:' + prefix: FilePlaceholderIdPrefixType = 'FILE:' ): input is FilePlaceholderId { return input.startsWith(prefix); } @@ -14,7 +15,7 @@ export function isFilePlaceholderId(input: string): input is FilePlaceholderId { function typedCreate( id: string, - prefix: FilePlaceholderIdPrefix = 'FILE:' + prefix: FilePlaceholderIdPrefixType = 'FILE:' ): FilePlaceholderId { return (prefix + id) as FilePlaceholderId; } diff --git a/src/workers/sync-engine/modules/placeholders/domain/FolderPlaceholderId.ts b/src/workers/sync-engine/modules/placeholders/domain/FolderPlaceholderId.ts index cacfb1070..7d9feaf81 100644 --- a/src/workers/sync-engine/modules/placeholders/domain/FolderPlaceholderId.ts +++ b/src/workers/sync-engine/modules/placeholders/domain/FolderPlaceholderId.ts @@ -1,10 +1,11 @@ -export type FolderPlaceholderIdPrefix = 'FOLDER:'; +export type FolderPlaceholderIdPrefixType = 'FOLDER:'; +export const FolderPlaceholderIdPrefix = 'FOLDER:'; -export type FolderPlaceholderId = `${FolderPlaceholderIdPrefix}${string}`; +export type FolderPlaceholderId = `${FolderPlaceholderIdPrefixType}${string}`; function typedCheck( input: string, - prefix: FolderPlaceholderIdPrefix = 'FOLDER:' + prefix: FolderPlaceholderIdPrefixType = 'FOLDER:' ): input is FolderPlaceholderId { return input.startsWith(prefix); } @@ -17,7 +18,7 @@ export function isFolderPlaceholderId( function typedCreate( id: string, - prefix: FolderPlaceholderIdPrefix = 'FOLDER:' + prefix: FolderPlaceholderIdPrefixType = 'FOLDER:' ): FolderPlaceholderId { return (prefix + id) as FolderPlaceholderId; } From dfccba4c074e5a97c5975b7271f6996fb0a810ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Thu, 19 Oct 2023 07:10:38 -0400 Subject: [PATCH 011/188] wip: abort progresss --- src/workers/sync-engine/BindingManager.ts | 29 ++++++++++++++-- .../controllers/DownloadFileController.ts | 4 +++ .../application/ContentsDownloader.ts | 33 ++++++++++++++++--- .../contentHandlers/ContentFileDownloader.ts | 2 ++ .../EnvironmentContentFileDownloader.ts | 16 ++++++++- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index dd4793e76..c71bf41b7 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -4,8 +4,12 @@ import { buildControllers } from './callbacks-controllers/buildControllers'; import { VirtualDrive } from 'virtual-drive/dist'; import { executeControllerWithFallback } from './callbacks-controllers/middlewares/executeControllerWithFallback'; import { FilePlaceholderId } from './modules/placeholders/domain/FilePlaceholderId'; +import { ipcRendererSyncEngine } from './ipcRendererSyncEngine'; -export type CallbackDownload = (success: boolean, filePath: string) => boolean; +export type CallbackDownload = ( + success: boolean, + filePath: string +) => Promise<{ finished: boolean; progress: number }>; export class BindingsManager { private static readonly PROVIDER_NAME = 'Internxt'; @@ -71,11 +75,30 @@ export class BindingsManager { callback ); Logger.debug('Execute Fetch Data Callback, sending path:', path); - + const file = controllers.downloadFile.fileFinderByContentsId( + contentsId + .replace( + // eslint-disable-next-line no-control-regex + /[\x00-\x1F\x7F-\x9F]/g, + '' + ) + .split(':')[1] + ); let finished = false; while (!finished) { - finished = callback(true, path); + const result = await callback(true, path); + finished = result.finished; Logger.debug('condition', finished); + ipcRendererSyncEngine.send('FILE_DOWNLOADING', { + name: file.name, + extension: file.type, + nameWithExtension: file.nameWithExtension, + size: file.size, + processInfo: { + elapsedTime: 0, + progress: result.progress, + }, + }); } try { diff --git a/src/workers/sync-engine/callbacks-controllers/controllers/DownloadFileController.ts b/src/workers/sync-engine/callbacks-controllers/controllers/DownloadFileController.ts index 527741fde..6d15ba769 100644 --- a/src/workers/sync-engine/callbacks-controllers/controllers/DownloadFileController.ts +++ b/src/workers/sync-engine/callbacks-controllers/controllers/DownloadFileController.ts @@ -21,6 +21,10 @@ export class DownloadFileController extends CallbackController { return await this.downloader.run(file, cb); } + fileFinderByContentsId(contentsId: string) { + return this.fileFinder.run(contentsId); + } + async execute( filePlaceholderId: FilePlaceholderId, cb: CallbackDownload diff --git a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts index 03ddf5ed8..cf8f52568 100644 --- a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts +++ b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts @@ -9,15 +9,22 @@ import path from 'path'; import { CallbackDownload } from '../../../BindingManager'; import { TemporalFolderProvider } from './temporalFolderProvider'; import { EventBus } from '../../shared/domain/EventBus'; +import Logger from 'electron-log'; +import { Readable } from 'stream'; export class ContentsDownloader { + private readableDownloader: Readable | null; + private hydrationFailed: boolean; constructor( private readonly managerFactory: ContentsManagersFactory, private readonly localWriter: LocalFileWriter, private readonly ipc: SyncEngineIpc, private readonly temporalFolderProvider: TemporalFolderProvider, private readonly eventBus: EventBus - ) {} + ) { + this.readableDownloader = null; + this.hydrationFailed = false; + } private async registerEvents( downloader: ContentFileDownloader, @@ -39,18 +46,33 @@ export class ContentsDownloader { }); }); - downloader.on('progress', (progress: number) => { - cb(true, filePath); + downloader.on('progress', async (progress: number) => { + Logger.debug('INSIDE PROGRESS======================='); + const result = await cb(true, filePath); + const hydrationProgress = result.progress; + + if (result.finished) { + downloader.forceStop(); + Logger.debug('Downloader force stop', this.readableDownloader); + this.readableDownloader?.destroy(); + this.readableDownloader?.emit('close'); + this.hydrationFailed = true; + } + this.ipc.send('FILE_DOWNLOADING', { name: file.name, extension: file.type, nameWithExtension: file.nameWithExtension, size: file.size, - processInfo: { elapsedTime: downloader.elapsedTime(), progress }, + processInfo: { + elapsedTime: downloader.elapsedTime(), + progress: hydrationProgress, + }, }); }); downloader.on('error', (error: Error) => { + Logger.error('INSIDE ERROR=======================', error); this.ipc.send('FILE_DOWNLOAD_ERROR', { name: file.name, extension: file.type, @@ -60,6 +82,8 @@ export class ContentsDownloader { }); downloader.on('finish', () => { + Logger.error('INSIDE FINISH======================='); + this.hydrationFailed = false; // The file download being finished does not mean it has been hidratated // TODO: We might want to track this time instead of the whole completion time }); @@ -71,6 +95,7 @@ export class ContentsDownloader { this.registerEvents(downloader, file, cb); const readable = await downloader.download(file); + this.readableDownloader = readable; const localContents = LocalFileContents.downloadedFrom( file, readable, diff --git a/src/workers/sync-engine/modules/contents/domain/contentHandlers/ContentFileDownloader.ts b/src/workers/sync-engine/modules/contents/domain/contentHandlers/ContentFileDownloader.ts index f9d0afb51..586057f85 100644 --- a/src/workers/sync-engine/modules/contents/domain/contentHandlers/ContentFileDownloader.ts +++ b/src/workers/sync-engine/modules/contents/domain/contentHandlers/ContentFileDownloader.ts @@ -11,6 +11,8 @@ export type FileDownloadEvents = { export interface ContentFileDownloader { download(file: File): Promise; + forceStop(): void; + on( event: keyof FileDownloadEvents, handler: FileDownloadEvents[keyof FileDownloadEvents] diff --git a/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts b/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts index 2baed0769..f05530225 100644 --- a/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts +++ b/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts @@ -7,17 +7,31 @@ import { } from '../../domain/contentHandlers/ContentFileDownloader'; import { File } from '../../../files/domain/File'; import { DownloadOneShardStrategy } from '@internxt/inxt-js/build/lib/core'; +import { ActionState } from '@internxt/inxt-js/build/api'; +import Logger from 'electron-log'; export class EnvironmentContentFileDownloader implements ContentFileDownloader { private eventEmitter: EventEmitter; private stopwatch: Stopwatch; + private state: ActionState | null; + constructor( private readonly fn: DownloadStrategyFunction, private readonly bucket: string ) { this.eventEmitter = new EventEmitter(); this.stopwatch = new Stopwatch(); + this.state = null; + } + + forceStop(): void { + //@ts-ignore + // Logger.debug('Finish emitter type', this.state?.type); + // Logger.debug('Finish emitter stop method', this.state?.stop); + this.state?.stop(); + // this.eventEmitter.emit('error'); + // this.eventEmitter.emit('finish'); } download(file: File): Promise { @@ -26,7 +40,7 @@ export class EnvironmentContentFileDownloader implements ContentFileDownloader { this.eventEmitter.emit('start'); return new Promise((resolve, reject) => { - this.fn( + this.state = this.fn( this.bucket, file.contentsId, { From 80fe3782dfc1e8d74de8793be08247aa6120b8a3 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Thu, 19 Oct 2023 13:37:18 +0200 Subject: [PATCH 012/188] fixed errordetails and types check --- src/renderer/pages/ProcessIssues/List.tsx | 13 +++++-------- .../modules/files/application/FileDeleter.ts | 2 ++ src/workers/types.ts | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/renderer/pages/ProcessIssues/List.tsx b/src/renderer/pages/ProcessIssues/List.tsx index e1917a562..687a88a54 100644 --- a/src/renderer/pages/ProcessIssues/List.tsx +++ b/src/renderer/pages/ProcessIssues/List.tsx @@ -18,7 +18,6 @@ import useFatalErrorActions from '../../hooks/FatalErrorActions'; import { generalErrors } from '../../messages/general-error'; import { shortMessages } from '../../messages/process-error'; import { getBaseName } from '../../utils/path'; -import Button from 'renderer/components/Button'; import { FatalError } from '../../components/Backups/FatalError'; export default function ProcessIssuesList({ @@ -183,9 +182,8 @@ function GeneralIssueItem({
@@ -225,7 +223,7 @@ function Item({ issues, isSelected, onClick, - onInfoClick, + //onInfoClick, }: { errorName: ProcessErrorName; issues: ProcessIssue[]; @@ -262,9 +260,8 @@ function Item({ */} diff --git a/src/workers/sync-engine/modules/files/application/FileDeleter.ts b/src/workers/sync-engine/modules/files/application/FileDeleter.ts index 9fbbd9a50..67e5b94a8 100644 --- a/src/workers/sync-engine/modules/files/application/FileDeleter.ts +++ b/src/workers/sync-engine/modules/files/application/FileDeleter.ts @@ -5,6 +5,7 @@ import { FileRepository } from '../domain/FileRepository'; import { FileStatuses } from '../domain/FileStatus'; import { PlaceholderCreator } from '../../placeholders/domain/PlaceholderCreator'; import { File } from '../domain/File'; +import { createErrorDetails } from '../../../../utils/reporting'; export class FileDeleter { constructor( @@ -80,6 +81,7 @@ export class FileDeleter { action: 'DELETE_ERROR', errorName: 'BAD_RESPONSE', process: 'SYNC', + errorDetails: createErrorDetails(error, 'Deleting file', 'Bad respone') }); this.placeholderCreator.file(file); diff --git a/src/workers/types.ts b/src/workers/types.ts index 0b6409d00..bc846cbda 100644 --- a/src/workers/types.ts +++ b/src/workers/types.ts @@ -204,6 +204,7 @@ export type GeneralIssue = { stack: string; }; }; + export type ProcessIssue = ProcessInfoBase & { action: | 'UPLOAD_ERROR' @@ -211,9 +212,9 @@ export type ProcessIssue = ProcessInfoBase & { | 'RENAME_ERROR' | 'DELETE_ERROR' | 'METADATA_READ_ERROR'; - errorName: ProcessErrorName; process: 'SYNC' | 'BACKUPS'; + errorDetails: ErrorDetails; }; export type ProcessInfoUpdatePayload = From a7d3430419f3e68a21e460ddb9f9fa82d9b12019 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Thu, 19 Oct 2023 13:42:28 +0200 Subject: [PATCH 013/188] Revert "fixed errordetails and types check" This reverts commit 80fe3782dfc1e8d74de8793be08247aa6120b8a3. --- src/renderer/pages/ProcessIssues/List.tsx | 13 ++++++++----- .../modules/files/application/FileDeleter.ts | 2 -- src/workers/types.ts | 3 +-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/renderer/pages/ProcessIssues/List.tsx b/src/renderer/pages/ProcessIssues/List.tsx index 687a88a54..e1917a562 100644 --- a/src/renderer/pages/ProcessIssues/List.tsx +++ b/src/renderer/pages/ProcessIssues/List.tsx @@ -18,6 +18,7 @@ import useFatalErrorActions from '../../hooks/FatalErrorActions'; import { generalErrors } from '../../messages/general-error'; import { shortMessages } from '../../messages/process-error'; import { getBaseName } from '../../utils/path'; +import Button from 'renderer/components/Button'; import { FatalError } from '../../components/Backups/FatalError'; export default function ProcessIssuesList({ @@ -182,8 +183,9 @@ function GeneralIssueItem({ @@ -223,7 +225,7 @@ function Item({ issues, isSelected, onClick, - //onInfoClick, + onInfoClick, }: { errorName: ProcessErrorName; issues: ProcessIssue[]; @@ -260,8 +262,9 @@ function Item({ */} diff --git a/src/workers/sync-engine/modules/files/application/FileDeleter.ts b/src/workers/sync-engine/modules/files/application/FileDeleter.ts index 67e5b94a8..9fbbd9a50 100644 --- a/src/workers/sync-engine/modules/files/application/FileDeleter.ts +++ b/src/workers/sync-engine/modules/files/application/FileDeleter.ts @@ -5,7 +5,6 @@ import { FileRepository } from '../domain/FileRepository'; import { FileStatuses } from '../domain/FileStatus'; import { PlaceholderCreator } from '../../placeholders/domain/PlaceholderCreator'; import { File } from '../domain/File'; -import { createErrorDetails } from '../../../../utils/reporting'; export class FileDeleter { constructor( @@ -81,7 +80,6 @@ export class FileDeleter { action: 'DELETE_ERROR', errorName: 'BAD_RESPONSE', process: 'SYNC', - errorDetails: createErrorDetails(error, 'Deleting file', 'Bad respone') }); this.placeholderCreator.file(file); diff --git a/src/workers/types.ts b/src/workers/types.ts index bc846cbda..0b6409d00 100644 --- a/src/workers/types.ts +++ b/src/workers/types.ts @@ -204,7 +204,6 @@ export type GeneralIssue = { stack: string; }; }; - export type ProcessIssue = ProcessInfoBase & { action: | 'UPLOAD_ERROR' @@ -212,9 +211,9 @@ export type ProcessIssue = ProcessInfoBase & { | 'RENAME_ERROR' | 'DELETE_ERROR' | 'METADATA_READ_ERROR'; + errorName: ProcessErrorName; process: 'SYNC' | 'BACKUPS'; - errorDetails: ErrorDetails; }; export type ProcessInfoUpdatePayload = From 4a42274ec98b7fcfc27737ecf7587f73dc098464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Thu, 19 Oct 2023 11:08:47 -0400 Subject: [PATCH 014/188] fix: revert cancel management --- .../contents/application/ContentsDownloader.ts | 12 +++++------- .../download/EnvironmentContentFileDownloader.ts | 1 - .../test/__mocks__/ContentFileDownloaderMock.ts | 4 ++++ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts index cf8f52568..85dd361c6 100644 --- a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts +++ b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts @@ -14,7 +14,6 @@ import { Readable } from 'stream'; export class ContentsDownloader { private readableDownloader: Readable | null; - private hydrationFailed: boolean; constructor( private readonly managerFactory: ContentsManagersFactory, private readonly localWriter: LocalFileWriter, @@ -23,7 +22,6 @@ export class ContentsDownloader { private readonly eventBus: EventBus ) { this.readableDownloader = null; - this.hydrationFailed = false; } private async registerEvents( @@ -46,17 +44,19 @@ export class ContentsDownloader { }); }); - downloader.on('progress', async (progress: number) => { - Logger.debug('INSIDE PROGRESS======================='); + downloader.on('progress', async () => { const result = await cb(true, filePath); const hydrationProgress = result.progress; + Logger.debug( + '\n\n******************************************hydrationProgress : \n\n', + hydrationProgress + ); if (result.finished) { downloader.forceStop(); Logger.debug('Downloader force stop', this.readableDownloader); this.readableDownloader?.destroy(); this.readableDownloader?.emit('close'); - this.hydrationFailed = true; } this.ipc.send('FILE_DOWNLOADING', { @@ -72,7 +72,6 @@ export class ContentsDownloader { }); downloader.on('error', (error: Error) => { - Logger.error('INSIDE ERROR=======================', error); this.ipc.send('FILE_DOWNLOAD_ERROR', { name: file.name, extension: file.type, @@ -83,7 +82,6 @@ export class ContentsDownloader { downloader.on('finish', () => { Logger.error('INSIDE FINISH======================='); - this.hydrationFailed = false; // The file download being finished does not mean it has been hidratated // TODO: We might want to track this time instead of the whole completion time }); diff --git a/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts b/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts index f05530225..84ee41f95 100644 --- a/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts +++ b/src/workers/sync-engine/modules/contents/infrastructure/download/EnvironmentContentFileDownloader.ts @@ -8,7 +8,6 @@ import { import { File } from '../../../files/domain/File'; import { DownloadOneShardStrategy } from '@internxt/inxt-js/build/lib/core'; import { ActionState } from '@internxt/inxt-js/build/api'; -import Logger from 'electron-log'; export class EnvironmentContentFileDownloader implements ContentFileDownloader { private eventEmitter: EventEmitter; diff --git a/src/workers/sync-engine/modules/contents/test/__mocks__/ContentFileDownloaderMock.ts b/src/workers/sync-engine/modules/contents/test/__mocks__/ContentFileDownloaderMock.ts index 1d2e87ef2..2ecb8e19d 100644 --- a/src/workers/sync-engine/modules/contents/test/__mocks__/ContentFileDownloaderMock.ts +++ b/src/workers/sync-engine/modules/contents/test/__mocks__/ContentFileDownloaderMock.ts @@ -13,6 +13,10 @@ export class ContentFileDownloaderMock implements ContentFileDownloader { return this.mock(); } + forceStop(): void { + return; + } + on( event: keyof FileDownloadEvents, fn: From 0b072617fcedecd33b4062a676eab61de71bf3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Thu, 19 Oct 2023 11:09:14 -0400 Subject: [PATCH 015/188] fix: revert cancel management --- .../contents/test/application/ContentsDownloader.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/workers/sync-engine/modules/contents/test/application/ContentsDownloader.test.ts b/src/workers/sync-engine/modules/contents/test/application/ContentsDownloader.test.ts index 05d0104b7..7974cc475 100644 --- a/src/workers/sync-engine/modules/contents/test/application/ContentsDownloader.test.ts +++ b/src/workers/sync-engine/modules/contents/test/application/ContentsDownloader.test.ts @@ -40,9 +40,9 @@ describe('Contents Downloader', () => { new ReadableHelloWorld() ); - await SUT.run(FileMother.any(), () => { + await SUT.run(FileMother.any(), async () => { /* do nothing */ - return true; + return { finished: true, progress: 100 }; }); expect(factory.mockDownloader.onMock).toBeCalledWith( @@ -56,8 +56,9 @@ describe('Contents Downloader', () => { factory.mockDownloader.mock.mockResolvedValueOnce(new ReadableHelloWorld()); const file = FileMother.any(); - await SUT.run(file, () => { - return true; + await SUT.run(file, async () => { + /* do nothing */ + return { finished: true, progress: 100 }; }); expect(localWriter.writeMock).toBeCalledWith( From 9eb244342abda32373434c21128c31ecca8736b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Thu, 19 Oct 2023 13:04:11 -0400 Subject: [PATCH 016/188] feat/break-stopped-hydration --- src/workers/sync-engine/BindingManager.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index c71bf41b7..21ce40865 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -12,7 +12,7 @@ export type CallbackDownload = ( ) => Promise<{ finished: boolean; progress: number }>; export class BindingsManager { private static readonly PROVIDER_NAME = 'Internxt'; - + private progressBuffer = 0; constructor( private readonly container: DependencyContainer, private readonly paths: { @@ -88,6 +88,11 @@ export class BindingsManager { while (!finished) { const result = await callback(true, path); finished = result.finished; + if (this.progressBuffer == result.progress) { + break; + } else { + this.progressBuffer += result.progress; + } Logger.debug('condition', finished); ipcRendererSyncEngine.send('FILE_DOWNLOADING', { name: file.name, @@ -101,6 +106,7 @@ export class BindingsManager { }); } + this.progressBuffer = 0; try { await controllers.notifyPlaceholderHydrationFinished.execute( contentsId From ad831093e73a42a0aef452453816bc6833bec8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Thu, 19 Oct 2023 13:14:59 -0400 Subject: [PATCH 017/188] wip --- src/workers/sync-engine/BindingManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index 21ce40865..97e0f6f79 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -91,7 +91,7 @@ export class BindingsManager { if (this.progressBuffer == result.progress) { break; } else { - this.progressBuffer += result.progress; + this.progressBuffer = result.progress; } Logger.debug('condition', finished); ipcRendererSyncEngine.send('FILE_DOWNLOADING', { From 797f4762027b097a5978950e949bb3149972cfff Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 19 Oct 2023 19:16:58 +0200 Subject: [PATCH 018/188] feat: release 2.0.0 --- package.json | 2 +- release/app/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a5947e340..6281e4f89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.0-a10", + "version": "2.0.0", "author": "Internxt ", "description": "Internxt Drive client UI", "license": "AGPL-3.0", diff --git a/release/app/package.json b/release/app/package.json index 508d5f75b..7f31c2a10 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.0-a10", + "version": "2.0.0", "description": "Internxt Drive client UI", "main": "./dist/main/main.js", "author": "Internxt ", From 45fc3e69c967522dd8d5f5ba9907a26dc9c95360 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 19 Oct 2023 19:20:13 +0200 Subject: [PATCH 019/188] chore: add certificate --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6281e4f89..5b4c3e039 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,8 @@ "win": { "target": [ "nsis" - ] + ], + "certificateSubjectName": "Internxt Universal Technologies SL" }, "linux": { "target": [ From ba40697e0cdd672ead428679de9ea1ef1b5e3da6 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Mon, 23 Oct 2023 18:19:03 +0200 Subject: [PATCH 020/188] feat: add retrive all files use case --- src/workers/sync-engine/BindingManager.ts | 24 +++++++++++++++++-- .../boundaryBridge/build.ts | 4 ++-- .../files/FilesContainer.ts | 6 +++-- .../dependency-injection/files/builder.ts | 14 ++++++----- .../items/ItemsContainer.ts | 2 +- .../dependency-injection/items/builder.ts | 2 +- src/workers/sync-engine/index.ts | 4 +--- .../files/application/RetrieveAllFiles.ts | 10 ++++++++ .../modules/files/domain/FileRepository.ts | 2 ++ .../infrastructure/HttpFileRepository.ts | 4 ++++ .../test/__mocks__/FileRepositoryMock.ts | 5 ++++ 11 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 src/workers/sync-engine/modules/files/application/RetrieveAllFiles.ts diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index 97e0f6f79..fd5098c25 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -5,6 +5,8 @@ import { VirtualDrive } from 'virtual-drive/dist'; import { executeControllerWithFallback } from './callbacks-controllers/middlewares/executeControllerWithFallback'; import { FilePlaceholderId } from './modules/placeholders/domain/FilePlaceholderId'; import { ipcRendererSyncEngine } from './ipcRendererSyncEngine'; +import { AbsolutePathToRelativeConverter } from './modules/shared/application/AbsolutePathToRelativeConverter'; +import { PlatformPathConverter } from './modules/shared/application/PlatformPathConverter'; export type CallbackDownload = ( success: boolean, @@ -178,7 +180,25 @@ export class BindingsManager { await this.container.virtualDrive.disconnectSyncRoot(); } - cleanUp() { - VirtualDrive.unregisterSyncRoot(this.paths.root); + async cleanUp() { + await VirtualDrive.unregisterSyncRoot(this.paths.root); + + const files = await this.container.retrieveAllFiles.run(); + + const items = [...files]; + + const win32AbsolutePaths = items.map((item) => { + const posixRelativePath = item.path.value; + // este path es relativo al root y en formato posix + + const win32RelativePaths = + PlatformPathConverter.posixToWin(posixRelativePath); + + return this.container.relativePathToAbsoluteConverter.run( + win32RelativePaths + ); + }); + + Logger.debug('items: ', win32AbsolutePaths); } } diff --git a/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts b/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts index 1706e361f..15b105da4 100644 --- a/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts +++ b/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts @@ -31,7 +31,7 @@ export function buildBoundaryBridgeContainer( ); const treePlaceholderCreator = new TreePlaceholderCreator( - itemsContainer.treeBuilder, + itemsContainer.existingItemsTreeBuilder, placeholderContainer.placeholderCreator ); @@ -55,7 +55,7 @@ export function buildBoundaryBridgeContainer( itemsContainer.allStatusesTreeBuilder, syncRemoteFile, syncRemoteFolder, - virtualDrive, + virtualDrive ); return { diff --git a/src/workers/sync-engine/dependency-injection/files/FilesContainer.ts b/src/workers/sync-engine/dependency-injection/files/FilesContainer.ts index 3b549e441..0da76325d 100644 --- a/src/workers/sync-engine/dependency-injection/files/FilesContainer.ts +++ b/src/workers/sync-engine/dependency-injection/files/FilesContainer.ts @@ -1,5 +1,7 @@ +import { ManagedFileRepository } from 'workers/sync-engine/modules/files/domain/ManagedFileRepository'; import { CreateFilePlaceholderOnDeletionFailed } from '../../modules/files/application/CreateFilePlaceholderOnDeletionFailed'; import { FileByPartialSearcher } from '../../modules/files/application/FileByPartialSearcher'; +import { FileClearer } from '../../modules/files/application/FileClearer'; import { FileCreator } from '../../modules/files/application/FileCreator'; import { FileDeleter } from '../../modules/files/application/FileDeleter'; import { FileFinderByContentsId } from '../../modules/files/application/FileFinderByContentsId'; @@ -7,8 +9,7 @@ import { FilePathUpdater } from '../../modules/files/application/FilePathUpdater import { FilePlaceholderCreatorFromContentsId } from '../../modules/files/application/FilePlaceholderCreatorFromContentsId'; import { FileSearcher } from '../../modules/files/application/FileSearcher'; import { LocalRepositoryRepositoryRefresher } from '../../modules/files/application/LocalRepositoryRepositoryRefresher'; -import { FileClearer } from '../../modules/files/application/FileClearer'; -import { ManagedFileRepository } from 'workers/sync-engine/modules/files/domain/ManagedFileRepository'; +import { RetrieveAllFiles } from '../../modules/files/application/RetrieveAllFiles'; import { SameFileWasMoved } from '../../modules/files/application/SameFileWasMoved'; export interface FilesContainer { @@ -24,4 +25,5 @@ export interface FilesContainer { fileClearer: FileClearer; managedFileRepository: ManagedFileRepository; sameFileWasMoved: SameFileWasMoved; + retrieveAllFiles: RetrieveAllFiles; } diff --git a/src/workers/sync-engine/dependency-injection/files/builder.ts b/src/workers/sync-engine/dependency-injection/files/builder.ts index 4cc4f00a9..df2444e59 100644 --- a/src/workers/sync-engine/dependency-injection/files/builder.ts +++ b/src/workers/sync-engine/dependency-injection/files/builder.ts @@ -1,26 +1,27 @@ -import { CreateFilePlaceholderOnDeletionFailed } from 'workers/sync-engine/modules/files/application/CreateFilePlaceholderOnDeletionFailed'; -import { FilePlaceholderCreatorFromContentsId } from 'workers/sync-engine/modules/files/application/FilePlaceholderCreatorFromContentsId'; import crypt from '../../../utils/crypt'; import { ipcRendererSyncEngine } from '../../ipcRendererSyncEngine'; +import { CreateFilePlaceholderOnDeletionFailed } from '../../modules/files/application/CreateFilePlaceholderOnDeletionFailed'; import { FileByPartialSearcher } from '../../modules/files/application/FileByPartialSearcher'; +import { FileClearer } from '../../modules/files/application/FileClearer'; import { FileCreator } from '../../modules/files/application/FileCreator'; import { FileDeleter } from '../../modules/files/application/FileDeleter'; import { FileFinderByContentsId } from '../../modules/files/application/FileFinderByContentsId'; import { FilePathUpdater } from '../../modules/files/application/FilePathUpdater'; +import { FilePlaceholderCreatorFromContentsId } from '../../modules/files/application/FilePlaceholderCreatorFromContentsId'; import { FileSearcher } from '../../modules/files/application/FileSearcher'; import { LocalRepositoryRepositoryRefresher } from '../../modules/files/application/LocalRepositoryRepositoryRefresher'; +import { RetrieveAllFiles } from '../../modules/files/application/RetrieveAllFiles'; +import { SameFileWasMoved } from '../../modules/files/application/SameFileWasMoved'; import { HttpFileRepository } from '../../modules/files/infrastructure/HttpFileRepository'; import { DependencyInjectionHttpClientsProvider } from '../common/clients'; import { DependencyInjectionEventBus } from '../common/eventBus'; +import { DependencyInjectionEventRepository } from '../common/eventRepository'; import { DependencyInjectionTraverserProvider } from '../common/traverser'; import { DependencyInjectionUserProvider } from '../common/user'; import { FoldersContainer } from '../folders/FoldersContainer'; import { PlaceholderContainer } from '../placeholders/PlaceholdersContainer'; -import { FilesContainer } from './FilesContainer'; -import { FileClearer } from '../../modules/files/application/FileClearer'; import { SharedContainer } from '../shared/SharedContainer'; -import { SameFileWasMoved } from 'workers/sync-engine/modules/files/application/SameFileWasMoved'; -import { DependencyInjectionEventRepository } from '../common/eventRepository'; +import { FilesContainer } from './FilesContainer'; export async function buildFilesContainer( folderContainer: FoldersContainer, @@ -115,6 +116,7 @@ export async function buildFilesContainer( fileClearer, managedFileRepository: fileRepository, sameFileWasMoved, + retrieveAllFiles: new RetrieveAllFiles(fileRepository), }; return { container, subscribers: [] }; diff --git a/src/workers/sync-engine/dependency-injection/items/ItemsContainer.ts b/src/workers/sync-engine/dependency-injection/items/ItemsContainer.ts index 1f6962eb7..6302698cd 100644 --- a/src/workers/sync-engine/dependency-injection/items/ItemsContainer.ts +++ b/src/workers/sync-engine/dependency-injection/items/ItemsContainer.ts @@ -1,6 +1,6 @@ import { TreeBuilder } from '../../modules/items/application/TreeBuilder'; export interface ItemsContainer { - treeBuilder: TreeBuilder; + existingItemsTreeBuilder: TreeBuilder; allStatusesTreeBuilder: TreeBuilder; } diff --git a/src/workers/sync-engine/dependency-injection/items/builder.ts b/src/workers/sync-engine/dependency-injection/items/builder.ts index 338fe0a3c..962b48896 100644 --- a/src/workers/sync-engine/dependency-injection/items/builder.ts +++ b/src/workers/sync-engine/dependency-injection/items/builder.ts @@ -37,7 +37,7 @@ export function buildItemsContainer(): ItemsContainer { ); return { - treeBuilder, + existingItemsTreeBuilder: treeBuilder, allStatusesTreeBuilder, }; } diff --git a/src/workers/sync-engine/index.ts b/src/workers/sync-engine/index.ts index 470497a0b..6e87ef80a 100644 --- a/src/workers/sync-engine/index.ts +++ b/src/workers/sync-engine/index.ts @@ -5,7 +5,6 @@ import packageJson from '../../../package.json'; import { BindingsManager } from './BindingManager'; import fs from 'fs/promises'; import { iconPath } from 'workers/utils/icon'; -import { VirtualDrive } from 'virtual-drive/dist'; async function ensureTheFolderExist(path: string) { try { @@ -56,8 +55,7 @@ async function setUp() { try { await bindings.stop(); - - await VirtualDrive.unregisterSyncRoot(virtualDrivePath); + await bindings.cleanUp(); Logger.info('[SYNC ENGINE] sync engine stopped and cleared successfully'); diff --git a/src/workers/sync-engine/modules/files/application/RetrieveAllFiles.ts b/src/workers/sync-engine/modules/files/application/RetrieveAllFiles.ts new file mode 100644 index 000000000..64c19c306 --- /dev/null +++ b/src/workers/sync-engine/modules/files/application/RetrieveAllFiles.ts @@ -0,0 +1,10 @@ +import { File } from '../domain/File'; +import { FileRepository } from '../domain/FileRepository'; + +export class RetrieveAllFiles { + constructor(private readonly repository: FileRepository) {} + + run(): Promise> { + return this.repository.all(); + } +} diff --git a/src/workers/sync-engine/modules/files/domain/FileRepository.ts b/src/workers/sync-engine/modules/files/domain/FileRepository.ts index 9add2f3eb..537c0df57 100644 --- a/src/workers/sync-engine/modules/files/domain/FileRepository.ts +++ b/src/workers/sync-engine/modules/files/domain/FileRepository.ts @@ -18,6 +18,8 @@ export interface FileRepository { searchOnFolder(folderId: FolderAttributes['id']): Promise>; + all(): Promise>; + /** @deprecated */ clear(): void; } diff --git a/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts b/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts index 1bf04836e..5a8d31865 100644 --- a/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts +++ b/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts @@ -39,6 +39,10 @@ export class HttpFileRepository return remoteItemsGenerator.getAll(); } + public all(): Promise> { + return Promise.resolve(Object.values(this.files)); + } + public async init(startingFiles: Record = {}): Promise { const raw = await this.getTree(); diff --git a/src/workers/sync-engine/modules/files/test/__mocks__/FileRepositoryMock.ts b/src/workers/sync-engine/modules/files/test/__mocks__/FileRepositoryMock.ts index 230c9da08..9fea08d26 100644 --- a/src/workers/sync-engine/modules/files/test/__mocks__/FileRepositoryMock.ts +++ b/src/workers/sync-engine/modules/files/test/__mocks__/FileRepositoryMock.ts @@ -13,6 +13,11 @@ export class FileRepositoryMock implements FileRepository { public mockSearchOnFolder = jest.fn(); public mockClear = jest.fn(); public mockInsert = jest.fn(); + public mockAll = jest.fn(); + + all(): Promise> { + return this.mockAll(); + } insert(file: File): Promise { return this.mockInsert(file); From 45c751126f9da12f8532c8fd3791abbfbbeaf69c Mon Sep 17 00:00:00 2001 From: joan vicens Date: Mon, 23 Oct 2023 18:29:19 +0200 Subject: [PATCH 021/188] feat: add retrive all files use case --- src/workers/sync-engine/BindingManager.ts | 4 ++-- .../dependency-injection/folders/FoldersContainer.ts | 2 ++ .../dependency-injection/folders/builder.ts | 2 ++ .../modules/folders/application/RetrieveAllFolders.ts | 10 ++++++++++ .../modules/folders/domain/FolderRepository.ts | 2 ++ .../folders/infrastructure/HttpFolderRepository.ts | 4 ++++ .../folders/test/__mocks__/FolderRepositoryMock.ts | 5 +++++ 7 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/workers/sync-engine/modules/folders/application/RetrieveAllFolders.ts diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index fd5098c25..850308790 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -5,7 +5,6 @@ import { VirtualDrive } from 'virtual-drive/dist'; import { executeControllerWithFallback } from './callbacks-controllers/middlewares/executeControllerWithFallback'; import { FilePlaceholderId } from './modules/placeholders/domain/FilePlaceholderId'; import { ipcRendererSyncEngine } from './ipcRendererSyncEngine'; -import { AbsolutePathToRelativeConverter } from './modules/shared/application/AbsolutePathToRelativeConverter'; import { PlatformPathConverter } from './modules/shared/application/PlatformPathConverter'; export type CallbackDownload = ( @@ -184,8 +183,9 @@ export class BindingsManager { await VirtualDrive.unregisterSyncRoot(this.paths.root); const files = await this.container.retrieveAllFiles.run(); + const folders = await this.container.retrieveAllFolders.run(); - const items = [...files]; + const items = [...files, ...folders]; const win32AbsolutePaths = items.map((item) => { const posixRelativePath = item.path.value; diff --git a/src/workers/sync-engine/dependency-injection/folders/FoldersContainer.ts b/src/workers/sync-engine/dependency-injection/folders/FoldersContainer.ts index 58dd3a1a2..ae8c99429 100644 --- a/src/workers/sync-engine/dependency-injection/folders/FoldersContainer.ts +++ b/src/workers/sync-engine/dependency-injection/folders/FoldersContainer.ts @@ -11,6 +11,7 @@ import { OfflineFolderPathUpdater } from '../../modules/folders/application/Offl import { SynchronizeOfflineModifications } from '../../modules/folders/application/SynchronizeOfflineModifications'; import { SynchronizeOfflineModificationsOnFolderCreated } from '../../modules/folders/application/SynchronizeOfflineModificationsOnFolderCreated'; import { ManagedFolderRepository } from '../../modules/folders/domain/ManagedFolderRepository'; +import { RetrieveAllFolders } from '../../modules/folders/application/RetrieveAllFolders'; export interface FoldersContainer { folderCreator: FolderCreator; @@ -28,4 +29,5 @@ export interface FoldersContainer { synchronizeOfflineModifications: SynchronizeOfflineModifications; }; managedFolderRepository: ManagedFolderRepository; + retrieveAllFolders: RetrieveAllFolders; } diff --git a/src/workers/sync-engine/dependency-injection/folders/builder.ts b/src/workers/sync-engine/dependency-injection/folders/builder.ts index b9b1c7536..32ec71c12 100644 --- a/src/workers/sync-engine/dependency-injection/folders/builder.ts +++ b/src/workers/sync-engine/dependency-injection/folders/builder.ts @@ -13,6 +13,7 @@ import { OfflineFolderCreator } from '../../modules/folders/application/Offline/ import { OfflineFolderMover } from '../../modules/folders/application/Offline/OfflineFolderMover'; import { OfflineFolderPathUpdater } from '../../modules/folders/application/Offline/OfflineFolderPathUpdater'; import { OfflineFolderRenamer } from '../../modules/folders/application/Offline/OfflineFolderRenamer'; +import { RetrieveAllFolders } from '../../modules/folders/application/RetrieveAllFolders'; import { SynchronizeOfflineModifications } from '../../modules/folders/application/SynchronizeOfflineModifications'; import { SynchronizeOfflineModificationsOnFolderCreated } from '../../modules/folders/application/SynchronizeOfflineModificationsOnFolderCreated'; import { HttpFolderRepository } from '../../modules/folders/infrastructure/HttpFolderRepository'; @@ -116,5 +117,6 @@ export async function buildFoldersContainer( synchronizeOfflineModifications, }, managedFolderRepository: repository, + retrieveAllFolders: new RetrieveAllFolders(repository), }; } diff --git a/src/workers/sync-engine/modules/folders/application/RetrieveAllFolders.ts b/src/workers/sync-engine/modules/folders/application/RetrieveAllFolders.ts new file mode 100644 index 000000000..0363affb6 --- /dev/null +++ b/src/workers/sync-engine/modules/folders/application/RetrieveAllFolders.ts @@ -0,0 +1,10 @@ +import { Folder } from '../domain/Folder'; +import { FolderRepository } from '../domain/FolderRepository'; + +export class RetrieveAllFolders { + constructor(private readonly repository: FolderRepository) {} + + run(): Promise> { + return this.repository.all(); + } +} diff --git a/src/workers/sync-engine/modules/folders/domain/FolderRepository.ts b/src/workers/sync-engine/modules/folders/domain/FolderRepository.ts index 771aa25a3..2c2c74175 100644 --- a/src/workers/sync-engine/modules/folders/domain/FolderRepository.ts +++ b/src/workers/sync-engine/modules/folders/domain/FolderRepository.ts @@ -3,6 +3,8 @@ import { Nullable } from '../../../../../shared/types/Nullable'; import { FolderPath } from './FolderPath'; export interface FolderRepository { + all(): Promise>; + search(path: string): Nullable; searchByPartial(partial: Partial): Nullable; diff --git a/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts b/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts index dcd9c81f7..b7ad78207 100644 --- a/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts +++ b/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts @@ -64,6 +64,10 @@ export class HttpFolderRepository await this.init(this.folders); } + all(): Promise> { + return Promise.resolve(Object.values(this.folders)); + } + search(path: string): Nullable { return this.folders[path]; } diff --git a/src/workers/sync-engine/modules/folders/test/__mocks__/FolderRepositoryMock.ts b/src/workers/sync-engine/modules/folders/test/__mocks__/FolderRepositoryMock.ts index 8be199534..9f4748c4e 100644 --- a/src/workers/sync-engine/modules/folders/test/__mocks__/FolderRepositoryMock.ts +++ b/src/workers/sync-engine/modules/folders/test/__mocks__/FolderRepositoryMock.ts @@ -13,6 +13,11 @@ export class FolderRepositoryMock implements FolderRepository { public mockSearchOnFolder = jest.fn(); public mockTrash = jest.fn(); public mockClear = jest.fn(); + public mockAll = jest.fn(); + + all(): Promise> { + return this.mockAll(); + } search(pathLike: string): Nullable { return this.mockSearch(pathLike); From d61ddb6b5afa63ec6b9e3821f3e60b0a422c7235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Mon, 23 Oct 2023 17:14:07 -0400 Subject: [PATCH 022/188] feat: include start with bindings reloading --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b4c3e039..5ba24a489 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,9 @@ "test:unit": "jest --silent", "test:e2e": "playwright test --config=src/test", "type-check": "tsc --noEmit --pretty --skipLibCheck", - "prepare": "husky install" + "prepare": "husky install", + "reload-virtual-drive": "cd release/app && yarn reload-virtual-drive && cd ../.. && yarn", + "start:reload-bindings": "npm run reload-virtual-drive && npm run start" }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ From 52daac882723711e3b55f16bd75df603154ba2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Mon, 23 Oct 2023 22:52:07 -0400 Subject: [PATCH 023/188] fix: logout management --- release/app/package-lock.json | 239 +++--------------- release/app/yarn.lock | 97 ++----- src/workers/sync-engine/BindingManager.ts | 7 + .../items/application/ItemsSearcher.ts | 26 ++ 4 files changed, 85 insertions(+), 284 deletions(-) create mode 100644 src/workers/sync-engine/modules/items/application/ItemsSearcher.ts diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 24541ebea..868268cd2 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,19 +1,32 @@ { "name": "internxt-drive", - "version": "2.0.8", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "internxt-drive", - "version": "2.0.8", + "version": "2.0.0", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@parcel/watcher": "^2.0.5", "@rudderstack/rudder-sdk-node": "^1.1.4", "better-sqlite3": "^8.3.0", - "typeorm": "^0.3.16" + "typeorm": "^0.3.16", + "virtual-drive": "../../../node-win" + } + }, + "../../../node-win": { + "version": "1.0.1", + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "tsconfig-paths": "^4.2.0" + }, + "devDependencies": { + "@types/node": "^20.5.0", + "node-gyp": "^9.4.0", + "typescript": "^5.1.6" } }, "node_modules/@babel/runtime": { @@ -67,26 +80,6 @@ "darwin" ] }, - "node_modules/@parcel/watcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz", - "integrity": "sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@rudderstack/rudder-sdk-node": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@rudderstack/rudder-sdk-node/-/rudder-sdk-node-1.1.4.tgz", @@ -278,18 +271,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -699,18 +680,6 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "license": "MIT" }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", @@ -891,15 +860,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "license": "MIT" }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -909,27 +869,6 @@ "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-retry-allowed": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", @@ -1041,19 +980,6 @@ "is-buffer": "~1.1.6" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -1174,23 +1100,6 @@ "node": ">=10" } }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "license": "MIT" - }, - "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "license": "MIT", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, "node_modules/node-gyp-build-optional-packages": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", @@ -1272,18 +1181,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "license": "MIT" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", @@ -1651,18 +1548,6 @@ "node": ">=0.8" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", @@ -1817,6 +1702,10 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/virtual-drive": { + "resolved": "../../../node-win", + "link": true + }, "node_modules/winston": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz", @@ -1954,17 +1843,6 @@ "integrity": "sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==", "optional": true }, - "@parcel/watcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz", - "integrity": "sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw==", - "requires": { - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" - } - }, "@rudderstack/rudder-sdk-node": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@rudderstack/rudder-sdk-node/-/rudder-sdk-node-1.1.4.tgz", @@ -2099,14 +1977,6 @@ "balanced-match": "^1.0.0" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, "buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -2387,14 +2257,6 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, "fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", @@ -2502,29 +2364,11 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, "is-retry-allowed": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", @@ -2605,15 +2449,6 @@ "is-buffer": "~1.1.6" } }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, "mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -2693,16 +2528,6 @@ "semver": "^7.3.5" } }, - "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" - }, - "node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==" - }, "node-gyp-build-optional-packages": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", @@ -2763,11 +2588,6 @@ } } }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, "prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", @@ -3009,14 +2829,6 @@ "thenify": ">= 3.1.0 < 4" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, "triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", @@ -3074,6 +2886,15 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "virtual-drive": { + "version": "file:../../../node-win", + "requires": { + "@types/node": "^20.5.0", + "node-gyp": "^9.4.0", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.1.6" + } + }, "winston": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/winston/-/winston-3.8.2.tgz", diff --git a/release/app/yarn.lock b/release/app/yarn.lock index 59d51ba15..a07508864 100644 --- a/release/app/yarn.lock +++ b/release/app/yarn.lock @@ -35,36 +35,6 @@ resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz" integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== -"@msgpackr-extract/msgpackr-extract-darwin-arm64@2.2.0": - version "2.2.0" - resolved "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz" - integrity sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ== - -"@msgpackr-extract/msgpackr-extract-darwin-x64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.2.0.tgz#fb877fe6bae3c4d3cea29786737840e2ae689066" - integrity sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw== - -"@msgpackr-extract/msgpackr-extract-linux-arm64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.2.0.tgz#986179c38b10ac41fbdaf7d036c825cbc72855d9" - integrity sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA== - -"@msgpackr-extract/msgpackr-extract-linux-arm@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.2.0.tgz#15f2c6fe9e0adc06c21af7e95f484ff4880d79ce" - integrity sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg== - -"@msgpackr-extract/msgpackr-extract-linux-x64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.2.0.tgz#30cae5c9a202f3e1fa1deb3191b18ffcb2f239a2" - integrity sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw== - -"@msgpackr-extract/msgpackr-extract-win32-x64@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz#016d855b6bc459fd908095811f6826e45dd4ba64" - integrity sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA== - "@rudderstack/rudder-sdk-node@^1.1.4": version "1.1.4" resolved "https://registry.npmjs.org/@rudderstack/rudder-sdk-node/-/rudder-sdk-node-1.1.4.tgz" @@ -148,7 +118,7 @@ base64-js@^1.3.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -better-sqlite3@^8.3.0: +"better-sqlite3@^7.1.2 || ^8.0.0", better-sqlite3@^8.3.0: version "8.3.0" resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.3.0.tgz" integrity sha512-JTmvBZL/JLTc+3Msbvq6gK6elbU9/wVMqiudplHrVJpr7sVMR9KJrNhZAbW+RhXKlpMcuEhYkdcHa3TXKNXQ1w== @@ -277,16 +247,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-string@^1.6.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -480,7 +450,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: +inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@2: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -490,7 +460,7 @@ ini@~1.3.0: resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ioredis@^5.0.0: +ioredis@^5.0.0, ioredis@^5.0.4: version "5.2.5" resolved "https://registry.npmjs.org/ioredis/-/ioredis-5.2.5.tgz" integrity sha512-7HKo/ClM2DGLRXdFq8ruS3Uuadensz4A76wPOU0adqlOqd1qkhoLPDaBhmVhUhNGpB+J65/bhLmNB8DDY99HJQ== @@ -535,11 +505,6 @@ join-component@^1.1.0: resolved "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz" integrity sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ== -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - kuler@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz" @@ -619,11 +584,6 @@ minimist@^1.2.0, minimist@^1.2.3: resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" @@ -634,16 +594,16 @@ mkdirp@^2.1.3: resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz" integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + msgpackr-extract@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-2.2.0.tgz" @@ -835,7 +795,7 @@ safe-stable-stringify@^2.3.1: semver@^7.3.2, semver@^7.3.5: version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -886,6 +846,13 @@ standard-as-callback@^2.1.0: resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -895,13 +862,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -909,11 +869,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" @@ -971,15 +926,6 @@ triple-beam@^1.3.0: resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -tsconfig-paths@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - tslib@^2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" @@ -1030,6 +976,7 @@ uuid@^9.0.0: virtual-drive@../../../node-win: version "1.0.1" + resolved "file:../../../node-win" dependencies: tsconfig-paths "^4.2.0" diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index 850308790..1e6b35173 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -6,6 +6,7 @@ import { executeControllerWithFallback } from './callbacks-controllers/middlewar import { FilePlaceholderId } from './modules/placeholders/domain/FilePlaceholderId'; import { ipcRendererSyncEngine } from './ipcRendererSyncEngine'; import { PlatformPathConverter } from './modules/shared/application/PlatformPathConverter'; +import { ItemsSearcher } from './modules/items/application/ItemsSearcher'; export type CallbackDownload = ( success: boolean, @@ -182,6 +183,12 @@ export class BindingsManager { async cleanUp() { await VirtualDrive.unregisterSyncRoot(this.paths.root); + //********************************************************************************************* */ + const itemsSearcher = new ItemsSearcher(); + const remainingItems = itemsSearcher.listFilesAndFolders(this.paths.root); + + Logger.debug('remainingItems: ', remainingItems); + //********************************************************************************************* */ const files = await this.container.retrieveAllFiles.run(); const folders = await this.container.retrieveAllFolders.run(); diff --git a/src/workers/sync-engine/modules/items/application/ItemsSearcher.ts b/src/workers/sync-engine/modules/items/application/ItemsSearcher.ts new file mode 100644 index 000000000..9a7b4f963 --- /dev/null +++ b/src/workers/sync-engine/modules/items/application/ItemsSearcher.ts @@ -0,0 +1,26 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +export class ItemsSearcher { + listFilesAndFolders(directory: string): string[] { + let result: string[] = []; + + // Lee el contenido del directorio + const items = fs.readdirSync(directory); + + for (const item of items) { + const fullPath = path.join(directory, item); + const stat = fs.statSync(fullPath); + + if (stat.isDirectory()) { + result.push(fullPath); + // Si es un directorio, explora su contenido de forma recursiva + result = result.concat(this.listFilesAndFolders(fullPath)); + } else if (stat.isFile()) { + result.push(fullPath); + } + } + + return result; + } +} From 651176815338e721c64bc985b084cbcb979b2fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Gonz=C3=A1lez?= Date: Tue, 24 Oct 2023 07:25:55 -0400 Subject: [PATCH 024/188] fix: include unsync items deletion --- release/app/package-lock.json | 1 + src/workers/sync-engine/BindingManager.ts | 35 ++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 868268cd2..14777a90a 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -17,6 +17,7 @@ } }, "../../../node-win": { + "name": "virtual-drive", "version": "1.0.1", "hasInstallScript": true, "license": "ISC", diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index 1e6b35173..7d41f0f44 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -7,6 +7,7 @@ import { FilePlaceholderId } from './modules/placeholders/domain/FilePlaceholder import { ipcRendererSyncEngine } from './ipcRendererSyncEngine'; import { PlatformPathConverter } from './modules/shared/application/PlatformPathConverter'; import { ItemsSearcher } from './modules/items/application/ItemsSearcher'; +import * as fs from 'fs'; export type CallbackDownload = ( success: boolean, @@ -183,12 +184,9 @@ export class BindingsManager { async cleanUp() { await VirtualDrive.unregisterSyncRoot(this.paths.root); - //********************************************************************************************* */ const itemsSearcher = new ItemsSearcher(); const remainingItems = itemsSearcher.listFilesAndFolders(this.paths.root); - Logger.debug('remainingItems: ', remainingItems); - //********************************************************************************************* */ const files = await this.container.retrieveAllFiles.run(); const folders = await this.container.retrieveAllFolders.run(); @@ -206,6 +204,35 @@ export class BindingsManager { ); }); - Logger.debug('items: ', win32AbsolutePaths); + Logger.debug('remainingItems', remainingItems); + Logger.debug('win32AbsolutePaths', win32AbsolutePaths); + // find all common string in remainingItems and win32AbsolutePaths + // and delete them + const commonItems = remainingItems.filter((item) => + win32AbsolutePaths.includes(item) + ); + + const toDeleteFolder: string[] = []; + + commonItems.forEach((item) => { + try { + const stat = fs.statSync(item); + if (stat.isDirectory()) { + toDeleteFolder.push(item); + } else if (stat.isFile()) { + fs.unlinkSync(item); + } + } catch (error) { + Logger.error(error); + } + }); + + toDeleteFolder.forEach((item) => { + try { + fs.rmdirSync(item, { recursive: true }); + } catch (error) { + Logger.error(error); + } + }); } } From e3ef99057f96b1a0032f3f88784118e5f35712ca Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 26 Oct 2023 13:43:54 +0200 Subject: [PATCH 025/188] fix: ignore files missing folder id --- src/main/remote-sync/RemoteSyncManager.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/remote-sync/RemoteSyncManager.ts b/src/main/remote-sync/RemoteSyncManager.ts index 7b9217797..5876e1cbe 100644 --- a/src/main/remote-sync/RemoteSyncManager.ts +++ b/src/main/remote-sync/RemoteSyncManager.ts @@ -466,6 +466,9 @@ export class RemoteSyncManager { }; }; private async createOrUpdateSyncedFileEntry(remoteFile: RemoteSyncedFile) { + if (!remoteFile.folderId) { + return; + } await this.db.files.create(remoteFile); } From f3bd0dcd752c4267475778f14e591f84a45397cd Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 26 Oct 2023 13:47:55 +0200 Subject: [PATCH 026/188] fix: ignore remote folders --- src/main/remote-sync/RemoteSyncManager.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/remote-sync/RemoteSyncManager.ts b/src/main/remote-sync/RemoteSyncManager.ts index 5876e1cbe..db87a1487 100644 --- a/src/main/remote-sync/RemoteSyncManager.ts +++ b/src/main/remote-sync/RemoteSyncManager.ts @@ -475,6 +475,10 @@ export class RemoteSyncManager { private async createOrUpdateSyncedFolderEntry( remoteFolder: RemoteSyncedFolder ) { + if (!remoteFolder.id) { + return; + } + await this.db.folders.create({ ...remoteFolder, parentId: remoteFolder.parentId ?? undefined, From c8991e9185962f9a2d50ffbf15dae0716d9d8f8a Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 26 Oct 2023 17:28:12 +0200 Subject: [PATCH 027/188] wip --- package.json | 2 +- release/app/package.json | 4 +- release/app/yarn.lock | 854 ++++++++++++++++-- src/main/background-processes/sync-engine.ts | 225 ++--- src/workers/fuse-native.d.ts | 52 ++ src/workers/sync-engine/BindingManager.ts | 266 ++---- .../DependencyContainer.ts | 5 +- .../DependencyContainerFactory.ts | 4 - .../boundaryBridge/build.ts | 1 - src/workers/sync-engine/index.ts | 10 +- .../VirtualDrivePlaceholderCreator.ts | 1 - yarn.lock | 6 +- 12 files changed, 1002 insertions(+), 428 deletions(-) create mode 100644 src/workers/fuse-native.d.ts diff --git a/package.json b/package.json index 5ba24a489..5e73914f7 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never", "publish": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish always", "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts && opencollective-postinstall", - "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:backups && npm run start:sync-engine && npm run start:renderer", + "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer", "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts", "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts", "start:sync": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.sync.ts", diff --git a/release/app/package.json b/release/app/package.json index 7f31c2a10..5c157e9c6 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -11,10 +11,10 @@ "reload-virtual-drive": "yarn add --ignore-scripts ../../../node-win && npm run link-modules" }, "dependencies": { + "@cocalc/fuse-native": "^2.4.0", "@rudderstack/rudder-sdk-node": "^1.1.4", "better-sqlite3": "^8.3.0", - "typeorm": "^0.3.16", - "virtual-drive": "../../../node-win" + "typeorm": "^0.3.16" }, "license": "MIT" } diff --git a/release/app/yarn.lock b/release/app/yarn.lock index a07508864..7b8c9fb48 100644 --- a/release/app/yarn.lock +++ b/release/app/yarn.lock @@ -16,6 +16,16 @@ dependencies: regenerator-runtime "^0.13.11" +"@cocalc/fuse-native@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@cocalc/fuse-native/-/fuse-native-2.4.0.tgz#feee5b75fef36a1b1b37135d8ccdc28d5dacf1e8" + integrity sha512-mhg+JZZkGq6cGN9Icy7Uu1J5/M1gR44t38DpxjZlRH4oyFcwpH2090/CFv2jGVaTOPrjgvxlb0jHNx9J7WUing== + dependencies: + nanoresource "^1.3.0" + napi-macros "^2.0.0" + node-gyp "^9.4.0" + node-gyp-build "^4.6.0" + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" @@ -35,6 +45,60 @@ resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz" integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@msgpackr-extract/msgpackr-extract-darwin-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz#901c5937e1441572ea23e631fe6deca68482fe76" + integrity sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ== + +"@msgpackr-extract/msgpackr-extract-darwin-x64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.2.0.tgz#fb877fe6bae3c4d3cea29786737840e2ae689066" + integrity sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw== + +"@msgpackr-extract/msgpackr-extract-linux-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.2.0.tgz#986179c38b10ac41fbdaf7d036c825cbc72855d9" + integrity sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA== + +"@msgpackr-extract/msgpackr-extract-linux-arm@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.2.0.tgz#15f2c6fe9e0adc06c21af7e95f484ff4880d79ce" + integrity sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg== + +"@msgpackr-extract/msgpackr-extract-linux-x64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.2.0.tgz#30cae5c9a202f3e1fa1deb3191b18ffcb2f239a2" + integrity sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw== + +"@msgpackr-extract/msgpackr-extract-win32-x64@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz#016d855b6bc459fd908095811f6826e45dd4ba64" + integrity sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA== + +"@npmcli/fs@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" + integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + dependencies: + semver "^7.3.5" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@rudderstack/rudder-sdk-node@^1.1.4": version "1.1.4" resolved "https://registry.npmjs.org/@rudderstack/rudder-sdk-node/-/rudder-sdk-node-1.1.4.tgz" @@ -66,11 +130,48 @@ resolved "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz" integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +abbrev@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" @@ -78,6 +179,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" @@ -88,6 +194,19 @@ app-root-path@^3.1.0: resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz" integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + async@^3.2.3: version "3.2.4" resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" @@ -118,30 +237,38 @@ base64-js@^1.3.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -"better-sqlite3@^7.1.2 || ^8.0.0", better-sqlite3@^8.3.0: - version "8.3.0" - resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.3.0.tgz" - integrity sha512-JTmvBZL/JLTc+3Msbvq6gK6elbU9/wVMqiudplHrVJpr7sVMR9KJrNhZAbW+RhXKlpMcuEhYkdcHa3TXKNXQ1w== +better-sqlite3@^8.3.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-8.7.0.tgz#bcc341856187b1d110a8a47234fa89c48c8ef538" + integrity sha512-99jZU4le+f3G6aIl6PmmV0cxUIWqKieHxsiF7G34CVFiE+/UabpYqkU0NJIkY/96mQKikHeBjtR27vFfs5JpEw== dependencies: bindings "^1.5.0" - prebuild-install "^7.1.0" + prebuild-install "^7.1.1" bindings@^1.5.0: version "1.5.0" - resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" bl@^4.0.3: version "4.1.0" - resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== dependencies: buffer "^5.5.0" inherits "^2.0.4" readable-stream "^3.4.0" +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" @@ -151,7 +278,7 @@ brace-expansion@^2.0.1: buffer@^5.5.0: version "5.7.1" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" @@ -180,6 +307,24 @@ bull@^4.7.0: semver "^7.3.2" uuid "^8.3.0" +cacache@^17.0.0: + version "17.1.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" + integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^7.7.1" + minipass "^7.0.3" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" + chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -195,9 +340,19 @@ charenc@0.0.2: chownr@^1.1.1: version "1.1.4" - resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + cli-highlight@^2.1.11: version "2.1.11" resolved "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz" @@ -247,16 +402,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-string@^1.6.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -265,6 +420,11 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + color@^3.1.3: version "3.2.1" resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" @@ -286,6 +446,16 @@ component-type@^1.2.1: resolved "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz" integrity sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg== +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + cron-parser@^4.2.1: version "4.7.1" resolved "https://registry.npmjs.org/cron-parser/-/cron-parser-4.7.1.tgz" @@ -293,6 +463,15 @@ cron-parser@^4.2.1: dependencies: luxon "^3.2.1" +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypt@0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" @@ -305,7 +484,7 @@ date-fns@^2.29.3: dependencies: "@babel/runtime" "^7.21.0" -debug@^4.3.4: +debug@4, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -319,48 +498,80 @@ debuglog@^1.0.0: decompress-response@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== dependencies: mimic-response "^3.1.0" deep-extend@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + denque@^2.0.1: version "2.1.0" resolved "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz" integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== dotenv@^16.0.3: version "16.0.3" resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + enabled@2.0.x: version "2.0.0" resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz" integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -368,9 +579,14 @@ escalade@^3.1.1: expand-template@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + fecha@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz" @@ -378,7 +594,7 @@ fecha@^4.2.0: file-uri-to-path@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== fn.name@1.x.x: @@ -391,16 +607,52 @@ follow-redirects@^1.14.8: resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + fs-constants@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-minipass@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== + dependencies: + minipass "^7.0.3" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" @@ -413,9 +665,32 @@ get-port@^5.1.1: github-from-package@0.0.0: version "0.0.0" - resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== +glob@^10.2.2: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" @@ -427,21 +702,77 @@ glob@^8.1.0: minimatch "^5.0.1" once "^1.3.0" +graceful-fs@^4.2.6: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + highlight.js@^10.7.1: version "10.7.3" resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -450,17 +781,17 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@2: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@~1.3.0: version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ioredis@^5.0.0, ioredis@^5.0.4: +ioredis@^5.0.0: version "5.2.5" resolved "https://registry.npmjs.org/ioredis/-/ioredis-5.2.5.tgz" integrity sha512-7HKo/ClM2DGLRXdFq8ruS3Uuadensz4A76wPOU0adqlOqd1qkhoLPDaBhmVhUhNGpB+J65/bhLmNB8DDY99HJQ== @@ -475,6 +806,11 @@ ioredis@^5.0.0, ioredis@^5.0.4: redis-parser "^3.0.0" standard-as-callback "^2.1.0" +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" @@ -490,6 +826,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + is-retry-allowed@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz" @@ -500,6 +841,20 @@ is-stream@^2.0.0: resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + join-component@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz" @@ -553,11 +908,42 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== + luxon@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz" integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== +make-fetch-happen@^11.0.3: + version "11.1.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" + md5@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz" @@ -569,9 +955,16 @@ md5@^2.3.0: mimic-response@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimatch@^5.0.1: version "5.1.6" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" @@ -579,31 +972,107 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.3: - version "1.2.7" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" + integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== + dependencies: + minipass "^7.0.3" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + +minizlib@^2.1.1, minizlib@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" - resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mkdirp@^2.1.3: version "2.1.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz" integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== -ms@^2.1.1, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + msgpackr-extract@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-2.2.0.tgz" @@ -634,15 +1103,32 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" +nanoresource@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/nanoresource/-/nanoresource-1.3.0.tgz#823945d9667ab3e81a8b2591ab8d734552878cd0" + integrity sha512-OI5dswqipmlYfyL3k/YMm7mbERlh4Bd1KuKdMHpeoVD1iVxqxaTMKleB4qaA2mbQZ6/zMNSxCXv9M9P/YbqTuQ== + dependencies: + inherits "^2.0.4" + napi-build-utils@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== +napi-macros@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== + +negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + node-abi@^3.3.0: - version "3.31.0" - resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz" - integrity sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ== + version "3.51.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" + integrity sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA== dependencies: semver "^7.3.5" @@ -651,6 +1137,45 @@ node-gyp-build-optional-packages@5.0.3: resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz" integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== +node-gyp-build@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" + integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + +node-gyp@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" + integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^11.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + object-assign@^4.0.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -658,7 +1183,7 @@ object-assign@^4.0.1: once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -675,6 +1200,13 @@ p-finally@^1.0.0: resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-timeout@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" @@ -699,9 +1231,27 @@ parse5@^6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -prebuild-install@^7.1.0: +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +prebuild-install@^7.1.1: version "7.1.1" - resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== dependencies: detect-libc "^2.0.0" @@ -717,9 +1267,17 @@ prebuild-install@^7.1.0: tar-fs "^2.0.0" tunnel-agent "^0.6.0" +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + pump@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -734,7 +1292,7 @@ randombytes@^2.1.0: rc@^1.2.7: version "1.2.8" - resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" @@ -742,7 +1300,16 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: +readable-stream@^3.1.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -783,6 +1350,18 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -793,6 +1372,11 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz" integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA== +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + semver@^7.3.2, semver@^7.3.5: version "7.5.4" resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" @@ -807,6 +1391,11 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + sha.js@^2.4.11: version "2.4.11" resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" @@ -815,14 +1404,36 @@ sha.js@^2.4.11: inherits "^2.0.1" safe-buffer "^5.0.1" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-concat@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== simple-get@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== dependencies: decompress-response "^6.0.0" @@ -836,6 +1447,35 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +ssri@^10.0.0: + version "10.0.5" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" + integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== + dependencies: + minipass "^7.0.3" + stack-trace@0.0.x: version "0.0.10" resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" @@ -846,14 +1486,16 @@ standard-as-callback@^2.1.0: resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: - safe-buffer "~5.2.0" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -862,6 +1504,29 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -869,9 +1534,16 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-json-comments@~2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== supports-color@^7.1.0: @@ -883,7 +1555,7 @@ supports-color@^7.1.0: tar-fs@^2.0.0: version "2.1.1" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== dependencies: chownr "^1.1.1" @@ -893,7 +1565,7 @@ tar-fs@^2.0.0: tar-stream@^2.1.4: version "2.2.0" - resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== dependencies: bl "^4.0.3" @@ -902,6 +1574,18 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" +tar@^6.1.11, tar@^6.1.2: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + text-hex@1.0.x: version "1.0.0" resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz" @@ -933,7 +1617,7 @@ tslib@^2.5.0: tunnel-agent@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== dependencies: safe-buffer "^5.0.1" @@ -959,6 +1643,20 @@ typeorm@^0.3.16: uuid "^9.0.0" yargs "^17.6.2" +unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== + dependencies: + unique-slug "^4.0.0" + +unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== + dependencies: + imurmurhash "^0.1.4" + util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -974,11 +1672,19 @@ uuid@^9.0.0: resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== -virtual-drive@../../../node-win: - version "1.0.1" - resolved "file:../../../node-win" +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: - tsconfig-paths "^4.2.0" + isexe "^2.0.0" + +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" winston-transport@^4.5.0: version "4.5.0" @@ -1006,6 +1712,15 @@ winston@^3.6.0: triple-beam "^1.3.0" winston-transport "^4.5.0" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -1015,6 +1730,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index c5e4b8de7..55846cf3a 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -1,171 +1,108 @@ -import { BrowserWindow, ipcMain } from 'electron'; -import path from 'path'; import Logger from 'electron-log'; import eventBus from '../event-bus'; +import { getRootVirtualDrive } from '../virutal-root-folder/service'; +import fuse from '@cocalc/fuse-native'; -let worker: BrowserWindow | null = null; -let workerIsRunning = false; -let startingWorker = false; +let _fuse: { + unmount(arg0: (err: any) => void): unknown; + mount: (arg0: (err: any) => void) => void; +}; function spawnSyncEngineWorker() { - if (startingWorker) { - Logger.info('[MAIN] Worker is already starting'); - return; - } - if (workerIsRunning) { - Logger.info('[MAIN] Worker is already running'); - return; - } + const ops = { + getattr: (path: string, cb: (code: number, params?: any) => void) => { + if (path === '/') { + cb(0, { mode: 16877, size: 0 }); + } else if (path === '/hello.txt') { + cb(0, { mode: 33188, size: 12 }); + } else { + cb(fuse.ENOENT); + } + }, + readdir: (path: string, cb: (code: number, params?: any) => void) => { + if (path === '/') { + cb(0, ['.', '..', 'hello.txt']); + } else { + cb(fuse.ENOENT); + } + }, + open: (path: string, flags, cb: (code: number, params?: any) => void) => { + if (path === '/hello.txt') { + cb(0, 123); // Use a unique file descriptor (123 in this example) + } else { + cb(fuse.ENOENT); + } + }, + read: ( + path: string, + fd, + buf, + len, + pos, + cb: (code: number, params?: any) => void + ) => { + if (path !== '/hello.txt') { + return cb(fuse.ENOENT); + } - startingWorker = true; + const data = Buffer.from('Hello, FUSE!'); + + if (pos >= data.length) { + return cb(0); + } - worker = new BrowserWindow({ - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - backgroundThrottling: false, + const slice = data.slice(pos, pos + len); + slice.copy(buf); + cb(slice.length); }, - show: false, - }); - worker - .loadFile( - process.env.NODE_ENV === 'development' - ? '../../release/app/dist/sync-engine/index.html' - : `${path.join(__dirname, '..', 'sync-engine')}/index.html` - ) - .then(() => { - Logger.info('[MAIN] Sync engine worker loaded'); - }) - .catch((err) => { - Logger.error('[MAIN] Error loading sync engine worker', err); - }); + release: function ( + readPath: string, + fd: number, + cb: (status: number) => void + ): void { + throw new Error('Function not implemented.'); + }, + }; - worker.on('close', () => { - worker?.destroy(); + const root = getRootVirtualDrive(); - if (workerIsRunning) { - Logger.warn('The sync engine process ended unexpectedly, relaunching'); - workerIsRunning = false; - spawnSyncEngineWorker(); + Logger.debug('ROOT FOLDER: ', root); + + _fuse = new fuse(root, ops, { + debug: true, + mkdir: true, + force: true, + }); + _fuse.mount((err: any) => { + if (err) { + Logger.error(`FUSE mount error: ${err}`); } }); - ipcMain.once('SYNC_ENGINE_PROCESS_SETUP_SUCCESSFUL', () => { - Logger.debug('[MAIN] SYNC ENGINE RUNNING'); - workerIsRunning = true; - startingWorker = false; - }); + fuse.isConfigured((isConfigured: boolean) => { + Logger.info(`FUSE is configured: ${isConfigured}`); - ipcMain.on('SYNC_ENGINE_PROCESS_SETUP_FAILED', () => { - Logger.debug('[MAIN] SYNC ENGINE NOT RUNNING'); - workerIsRunning = false; - startingWorker = false; + if (!isConfigured) { + fuse.configure((...params: any[]) => { + Logger.debug(`FUSE configure cb params: ${{ params }}`); + }); + } }); } export async function stopSyncEngineWatcher() { - Logger.info('[MAIN] STOPPING SYNC ENGINE WORKER...'); - - if (!workerIsRunning) { - Logger.info('[MAIN] WORKER WAS NOT RUNNING'); - worker?.destroy(); - worker = null; - return; - } - - const stopPromise = new Promise((resolve, reject) => { - ipcMain.once('SYNC_ENGINE_STOP_ERROR', (_, error: Error) => { - Logger.error('[MAIN] Error stopping sync engine worker', error); - reject(error); - }); - - ipcMain.once('SYNC_ENGINE_STOP_SUCCESS', () => { - resolve(); - Logger.info('[MAIN] Sync engine stopped'); - }); - - const millisecondsToWait = 10_000; - - setTimeout(() => { - reject( - new Error( - `Timeout waiting for sync engine to stop after ${millisecondsToWait} milliseconds` - ) - ); - }, millisecondsToWait); + _fuse?.unmount((err: any) => { + if (err) { + Logger.error(`FUSE unmount error: ${err}`); + } }); - - try { - worker?.webContents.send('STOP_SYNC_ENGINE_PROCESS'); - - await stopPromise; - } catch (err) { - // TODO: handle error - Logger.error(err); - } finally { - worker?.destroy(); - workerIsRunning = false; - worker = null; - } } async function stopAndClearSyncEngineWatcher() { - Logger.info('[MAIN] STOPPING AND CLEAR SYNC ENGINE WORKER...'); - - if (!workerIsRunning) { - Logger.info('[MAIN] WORKER WAS NOT RUNNING'); - worker?.destroy(); - worker = null; - return; - } - - const response = new Promise((resolve, reject) => { - ipcMain.once( - 'ERROR_ON_STOP_AND_CLEAR_SYNC_ENGINE_PROCESS', - (_, error: Error) => { - Logger.error('[MAIN] Error stopping sync engine worker', error); - reject(error); - } - ); - - ipcMain.once('SYNC_ENGINE_STOP_AND_CLEAR_SUCCESS', () => { - resolve(); - Logger.info('[MAIN] Sync engine stopped and cleared'); - }); - - const millisecondsToWait = 10_000; - - setTimeout(() => { - reject( - new Error( - `Timeout waiting for sync engine to stop after ${millisecondsToWait} milliseconds` - ) - ); - }, millisecondsToWait); - }); - - try { - worker?.webContents.send('STOP_AND_CLEAR_SYNC_ENGINE_PROCESS'); - - await response; - } catch (err) { - // TODO: handle error - Logger.error(err); - } finally { - worker?.destroy(); - workerIsRunning = false; - worker = null; - } + stopSyncEngineWatcher(); } -export function updateSyncEngine() { - try { - worker?.webContents.send('UPDATE_SYNC_ENGINE_PROCESS'); - } catch (err) { - // TODO: handle error - Logger.error(err); - } -} +export function updateSyncEngine() {} eventBus.on('USER_LOGGED_OUT', stopAndClearSyncEngineWatcher); eventBus.on('USER_WAS_UNAUTHORIZED', stopAndClearSyncEngineWatcher); diff --git a/src/workers/fuse-native.d.ts b/src/workers/fuse-native.d.ts new file mode 100644 index 000000000..f87fc42b8 --- /dev/null +++ b/src/workers/fuse-native.d.ts @@ -0,0 +1,52 @@ +declare module 'fuse-native' { + export interface FuseStat { + mtime: Date; + atime: Date; + ctime: Date; + size: number; + mode: number; + uid: number; + gid: number; + } + + export interface FuseHandlers { + readdir( + readPath: string, + cb: (status: number, entries: string[]) => void + ): void; + getattr( + readPath: string, + cb: (status: number, stat?: FuseStat) => void + ): void; + open( + readPath: string, + flags: number, + cb: (status: number, fd: number) => void + ): void; + release(readPath: string, fd: number, cb: (status: number) => void): void; + read( + readPath: string, + fd: number, + buf: Buffer, + len: number, + pos: number, + cb: (bytesRead: number) => void + ): void; + } + + interface FuseOptions { + displayFolder?: string; + debug?: boolean; + } + + class Fuse { + // static isConfigured(): boolean + mnt: string; + + constructor(mnt: string, handlers: FuseHandlers, opts?: FuseOptions); + mount(cb: (error: Error | null) => void): void; + unmount(cb: (error: Error | null) => void): void; + } + + export default Fuse; +} diff --git a/src/workers/sync-engine/BindingManager.ts b/src/workers/sync-engine/BindingManager.ts index 7d41f0f44..2c9d9d338 100644 --- a/src/workers/sync-engine/BindingManager.ts +++ b/src/workers/sync-engine/BindingManager.ts @@ -1,7 +1,5 @@ import Logger from 'electron-log'; -import { DependencyContainer } from './dependency-injection/DependencyContainer'; import { buildControllers } from './callbacks-controllers/buildControllers'; -import { VirtualDrive } from 'virtual-drive/dist'; import { executeControllerWithFallback } from './callbacks-controllers/middlewares/executeControllerWithFallback'; import { FilePlaceholderId } from './modules/placeholders/domain/FilePlaceholderId'; import { ipcRendererSyncEngine } from './ipcRendererSyncEngine'; @@ -15,9 +13,10 @@ export type CallbackDownload = ( ) => Promise<{ finished: boolean; progress: number }>; export class BindingsManager { private static readonly PROVIDER_NAME = 'Internxt'; - private progressBuffer = 0; + + private fuse: any | null = null; + constructor( - private readonly container: DependencyContainer, private readonly paths: { root: string; icon: string; @@ -25,214 +24,89 @@ export class BindingsManager { ) {} async start(version: string, providerId: string) { - await this.stop(); - - const controllers = buildControllers(this.container); - - const callbacks = { - notifyDeleteCallback: ( - contentsId: string, - callback: (response: boolean) => void - ) => { - controllers.delete - .execute(contentsId) - .then(() => { - callback(true); - }) - .catch((error: Error) => { - Logger.error(error); - callback(false); - }); - }, - notifyDeleteCompletionCallback: () => { - Logger.info('Deletion completed'); + const fuse = require('fuse-native'); + const ops = { + getattr: (path: string, cb: (code: number, params?: any) => void) => { + if (path === '/') { + cb(0, { mode: 16877, size: 0 }); + } else if (path === '/hello.txt') { + cb(0, { mode: 33188, size: 12 }); + } else { + cb(Fuse.ENOENT); + } }, - notifyRenameCallback: ( - absolutePath: string, - contentsId: string, - callback: (response: boolean) => void - ) => { - const fn = executeControllerWithFallback({ - handler: controllers.renameOrMove.execute.bind( - controllers.renameOrMove - ), - fallback: controllers.offline.renameOrMove.execute.bind( - controllers.offline.renameOrMove - ), - }); - fn(absolutePath, contentsId, callback); + readdir: (path: string, cb: (code: number, params?: any) => void) => { + if (path === '/') { + cb(0, ['.', '..', 'hello.txt']); + } else { + cb(Fuse.ENOENT); + } }, - notifyFileAddedCallback: ( - absolutePath: string, - callback: (acknowledge: boolean, id: string) => boolean - ) => { - controllers.addFile.execute(absolutePath, callback); + open: (path: string, flags, cb: (code: number, params?: any) => void) => { + if (path === '/hello.txt') { + cb(0, 123); // Use a unique file descriptor (123 in this example) + } else { + cb(Fuse.ENOENT); + } }, - fetchDataCallback: async ( - contentsId: FilePlaceholderId, - callback: CallbackDownload + read: ( + path: string, + fd, + buf, + len, + pos, + cb: (code: number, params?: any) => void ) => { - try { - const path = await controllers.downloadFile.execute( - contentsId, - callback - ); - Logger.debug('Execute Fetch Data Callback, sending path:', path); - const file = controllers.downloadFile.fileFinderByContentsId( - contentsId - .replace( - // eslint-disable-next-line no-control-regex - /[\x00-\x1F\x7F-\x9F]/g, - '' - ) - .split(':')[1] - ); - let finished = false; - while (!finished) { - const result = await callback(true, path); - finished = result.finished; - if (this.progressBuffer == result.progress) { - break; - } else { - this.progressBuffer = result.progress; - } - Logger.debug('condition', finished); - ipcRendererSyncEngine.send('FILE_DOWNLOADING', { - name: file.name, - extension: file.type, - nameWithExtension: file.nameWithExtension, - size: file.size, - processInfo: { - elapsedTime: 0, - progress: result.progress, - }, - }); + if (path === '/hello.txt') { + const data = Buffer.from('Hello, FUSE!'); + if (pos >= data.length) { + cb(0); + } else { + const slice = data.slice(pos, pos + len); + slice.copy(buf); + cb(slice.length); } - - this.progressBuffer = 0; - try { - await controllers.notifyPlaceholderHydrationFinished.execute( - contentsId - ); - } catch (error) { - Logger.error('notify: ', error); - } - - // Esperar hasta que la ejecución de fetchDataCallback esté completa antes de continuar - await new Promise((resolve) => { - setTimeout(() => { - Logger.debug('timeout'); - resolve(true); - }, 500); - }); - } catch (error) { - Logger.error(error); - callback(false, ''); + } else { + cb(Fuse.ENOENT); } }, - validateDataCallback: () => { - Logger.debug('validateDataCallback'); - }, - cancelFetchDataCallback: () => { - Logger.debug('cancelFetchDataCallback'); - }, - fetchPlaceholdersCallback: () => { - Logger.debug('fetchPlaceholdersCallback'); - }, - cancelFetchPlaceholdersCallback: () => { - Logger.debug('cancelFetchPlaceholdersCallback'); - }, - notifyFileOpenCompletionCallback: () => { - Logger.debug('notifyFileOpenCompletionCallback'); - }, - notifyFileCloseCompletionCallback: () => { - Logger.debug('notifyFileCloseCompletionCallback'); - }, - notifyDehydrateCallback: () => { - Logger.debug('notifyDehydrateCallback'); - }, - notifyDehydrateCompletionCallback: () => { - Logger.debug('notifyDehydrateCompletionCallback'); - }, - notifyRenameCompletionCallback: () => { - Logger.debug('notifyRenameCompletionCallback'); - }, - noneCallback: () => { - Logger.debug('noneCallback'); + release: function ( + readPath: string, + fd: number, + cb: (status: number) => void + ): void { + throw new Error('Function not implemented.'); }, }; + // this.fuse = new fuse(this.paths.root, ops, { debug: true }); + // this.fuse.mount((err: any) => { + // if (err) { + // Logger.error(`FUSE mount error: ${err}`); + // } + // }); - await this.container.virtualDrive.registerSyncRoot( - BindingsManager.PROVIDER_NAME, - version, - providerId, - callbacks, - this.paths.icon - ); - - await this.container.virtualDrive.connectSyncRoot(); - } - - watch() { - this.container.virtualDrive.watchAndWait(this.paths.root); - } - - async stop() { - await this.container.virtualDrive.disconnectSyncRoot(); - } - - async cleanUp() { - await VirtualDrive.unregisterSyncRoot(this.paths.root); - - const itemsSearcher = new ItemsSearcher(); - const remainingItems = itemsSearcher.listFilesAndFolders(this.paths.root); - - const files = await this.container.retrieveAllFiles.run(); - const folders = await this.container.retrieveAllFolders.run(); - - const items = [...files, ...folders]; + Logger.debug('FUSE: ', { fuse }); - const win32AbsolutePaths = items.map((item) => { - const posixRelativePath = item.path.value; - // este path es relativo al root y en formato posix + fuse.isConfigured((isConfigured: boolean) => { + Logger.info(`FUSE is configured: ${isConfigured}`); - const win32RelativePaths = - PlatformPathConverter.posixToWin(posixRelativePath); - - return this.container.relativePathToAbsoluteConverter.run( - win32RelativePaths - ); - }); - - Logger.debug('remainingItems', remainingItems); - Logger.debug('win32AbsolutePaths', win32AbsolutePaths); - // find all common string in remainingItems and win32AbsolutePaths - // and delete them - const commonItems = remainingItems.filter((item) => - win32AbsolutePaths.includes(item) - ); - - const toDeleteFolder: string[] = []; - - commonItems.forEach((item) => { - try { - const stat = fs.statSync(item); - if (stat.isDirectory()) { - toDeleteFolder.push(item); - } else if (stat.isFile()) { - fs.unlinkSync(item); - } - } catch (error) { - Logger.error(error); + if (!isConfigured) { + fuse.configure((...params: any[]) => { + Logger.debug(`FUSE configure cb params: ${{ params }}`); + }); } }); + } + + watch() {} - toDeleteFolder.forEach((item) => { - try { - fs.rmdirSync(item, { recursive: true }); - } catch (error) { - Logger.error(error); + async stop() { + this.fuse?.unmount((err: any) => { + if (err) { + Logger.error(`FUSE unmount error: ${err}`); } }); } + + async cleanUp() {} } diff --git a/src/workers/sync-engine/dependency-injection/DependencyContainer.ts b/src/workers/sync-engine/dependency-injection/DependencyContainer.ts index 10b52ea8f..00f30a3be 100644 --- a/src/workers/sync-engine/dependency-injection/DependencyContainer.ts +++ b/src/workers/sync-engine/dependency-injection/DependencyContainer.ts @@ -1,5 +1,4 @@ /* eslint-disable max-len */ -import { VirtualDrive } from 'virtual-drive/dist'; import { ContentsContainer } from './contents/ContentsContainer'; import { FilesContainer } from './files/FilesContainer'; import { FoldersContainer } from './folders/FoldersContainer'; @@ -15,6 +14,4 @@ export interface DependencyContainer FoldersContainer, PlaceholderContainer, SharedContainer, - BoundaryBridgeContainer { - virtualDrive: VirtualDrive; -} + BoundaryBridgeContainer {} diff --git a/src/workers/sync-engine/dependency-injection/DependencyContainerFactory.ts b/src/workers/sync-engine/dependency-injection/DependencyContainerFactory.ts index 716207047..ba22d8d04 100644 --- a/src/workers/sync-engine/dependency-injection/DependencyContainerFactory.ts +++ b/src/workers/sync-engine/dependency-injection/DependencyContainerFactory.ts @@ -6,7 +6,6 @@ import { buildContentsContainer } from './contents/builder'; import { buildFilesContainer } from './files/builder'; import { buildFoldersContainer } from './folders/builder'; import { buildItemsContainer } from './items/builder'; -import { DependencyInjectionVirtualDrive } from './common/virtualDrive'; import { buildPlaceholdersContainer } from './placeholders/builder'; import { buildBoundaryBridgeContainer } from './boundaryBridge/build'; import { buildSharedContainer } from './shared/builder'; @@ -38,7 +37,6 @@ export class DependencyContainerFactory { } const { bus } = DependencyInjectionEventBus; - const { virtualDrive } = DependencyInjectionVirtualDrive; const sharedContainer = buildSharedContainer(); const itemsContainer = buildItemsContainer(); @@ -67,8 +65,6 @@ export class DependencyContainerFactory { ...placeholderContainer, ...sharedContainer, ...boundaryBridgeContainer, - - virtualDrive, }; bus.addSubscribers(DomainEventSubscribers.from(container)); diff --git a/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts b/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts index 15b105da4..971215272 100644 --- a/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts +++ b/src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts @@ -11,7 +11,6 @@ import { SharedContainer } from '../shared/SharedContainer'; import { SyncPlaceholders } from 'workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders'; import { UpdatePlaceholderFolder } from 'workers/sync-engine/modules/boundaryBridge/application/UpdatePlaceholderFolder'; import { DependencyInjectionEventRepository } from '../common/eventRepository'; -import { DependencyInjectionVirtualDrive } from '../common/virtualDrive'; export function buildBoundaryBridgeContainer( contentsContainer: ContentsContainer, diff --git a/src/workers/sync-engine/index.ts b/src/workers/sync-engine/index.ts index 6e87ef80a..762772a96 100644 --- a/src/workers/sync-engine/index.ts +++ b/src/workers/sync-engine/index.ts @@ -1,6 +1,5 @@ import Logger from 'electron-log'; import { ipcRenderer } from 'electron'; -import { DependencyContainerFactory } from './dependency-injection/DependencyContainerFactory'; import packageJson from '../../../package.json'; import { BindingsManager } from './BindingManager'; import fs from 'fs/promises'; @@ -24,10 +23,7 @@ async function setUp() { await ensureTheFolderExist(virtualDrivePath); - const factory = new DependencyContainerFactory(); - const container = await factory.build(); - - const bindings = new BindingsManager(container, { + const bindings = new BindingsManager({ root: virtualDrivePath, icon: iconPath, }); @@ -45,7 +41,7 @@ async function setUp() { ipcRenderer.on('UPDATE_SYNC_ENGINE_PROCESS', async () => { Logger.info('[SYNC ENGINE] Updating sync engine'); - await container.syncPlaceholders.run(); + // await container.syncPlaceholders.run(); Logger.info('[SYNC ENGINE] sync engine updated successfully'); }); @@ -71,7 +67,7 @@ async function setUp() { '{E9D7EB38-B229-5DC5-9396-017C449D59CD}' ); - await container.treePlaceholderCreator.run(); + // await container.treePlaceholderCreator.run(); bindings.watch(); } diff --git a/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts b/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts index 972d21630..a58c1726d 100644 --- a/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts +++ b/src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts @@ -1,4 +1,3 @@ -import { VirtualDrive } from 'virtual-drive/dist'; import { File } from '../../files/domain/File'; import { Folder } from '../../folders/domain/Folder'; import { PlaceholderCreator } from '../domain/PlaceholderCreator'; diff --git a/yarn.lock b/yarn.lock index b08729e41..40a09d2d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5256,9 +5256,9 @@ electron-updater@^4.6.4: semver "^7.3.5" electron@^25.8.1: - version "25.8.1" - resolved "https://registry.yarnpkg.com/electron/-/electron-25.8.1.tgz#092fab5a833db4d9240d4d6f36218cf7ca954f86" - integrity sha512-GtcP1nMrROZfFg0+mhyj1hamrHvukfF6of2B/pcWxmWkd5FVY1NJib0tlhiorFZRzQN5Z+APLPr7aMolt7i2AQ== + version "25.9.3" + resolved "https://registry.yarnpkg.com/electron/-/electron-25.9.3.tgz#cdd53a30fb914adadcfbd34124237fb38b1c07d0" + integrity sha512-dacaHg/PuwVcFRgPDCM5j7UDzqGJWOsbBRdS5wPKLNS/ejPeccIjuNUT1cqcrpvCJKAFW8swHWg9kdizNSEDHQ== dependencies: "@electron/get" "^2.0.0" "@types/node" "^18.11.18" From 231c257a4b9cd4d6d1fd990866aae88fe241e52a Mon Sep 17 00:00:00 2001 From: joan vicens Date: Fri, 27 Oct 2023 13:55:12 +0200 Subject: [PATCH 028/188] wip --- package.json | 2 +- release/app/package.json | 2 +- release/app/yarn.lock | 693 +------------------ src/main/background-processes/sync-engine.ts | 74 +- yarn.lock | 247 ++++++- 5 files changed, 266 insertions(+), 752 deletions(-) diff --git a/package.json b/package.json index 5e73914f7..f0d005442 100644 --- a/package.json +++ b/package.json @@ -203,7 +203,7 @@ "detect-port": "^1.3.0", "dotenv": "^10.0.0", "dotenv-webpack": "^7.0.3", - "electron": "^25.8.1", + "electron": "19.1.9", "electron-builder": "^23.6.0", "electron-devtools-installer": "^3.2.0", "electron-notarize": "^1.1.1", diff --git a/release/app/package.json b/release/app/package.json index 5c157e9c6..cf5bb3900 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -11,7 +11,7 @@ "reload-virtual-drive": "yarn add --ignore-scripts ../../../node-win && npm run link-modules" }, "dependencies": { - "@cocalc/fuse-native": "^2.4.0", + "@gcas/fuse": "^2.4.2", "@rudderstack/rudder-sdk-node": "^1.1.4", "better-sqlite3": "^8.3.0", "typeorm": "^0.3.16" diff --git a/release/app/yarn.lock b/release/app/yarn.lock index 7b8c9fb48..81352052d 100644 --- a/release/app/yarn.lock +++ b/release/app/yarn.lock @@ -16,16 +16,6 @@ dependencies: regenerator-runtime "^0.13.11" -"@cocalc/fuse-native@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@cocalc/fuse-native/-/fuse-native-2.4.0.tgz#feee5b75fef36a1b1b37135d8ccdc28d5dacf1e8" - integrity sha512-mhg+JZZkGq6cGN9Icy7Uu1J5/M1gR44t38DpxjZlRH4oyFcwpH2090/CFv2jGVaTOPrjgvxlb0jHNx9J7WUing== - dependencies: - nanoresource "^1.3.0" - napi-macros "^2.0.0" - node-gyp "^9.4.0" - node-gyp-build "^4.6.0" - "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" @@ -40,23 +30,19 @@ enabled "2.0.x" kuler "^2.0.0" +"@gcas/fuse@^2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@gcas/fuse/-/fuse-2.4.2.tgz#149bd97ec8a60988f4868bacd719c7e8a1c41876" + integrity sha512-l/vVd2eXAuzKG4QilN1VRa8za5glndSK+jxcLrzMiXRrvbbCJthwqcBZUE3VzoRL0T/l7197tW+MKR9YeQCtZQ== + dependencies: + nanoresource "^1.3.0" + napi-macros "^2.0.0" + "@ioredis/commands@^1.1.1": version "1.2.0" resolved "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz" integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - "@msgpackr-extract/msgpackr-extract-darwin-arm64@2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.2.0.tgz#901c5937e1441572ea23e631fe6deca68482fe76" @@ -87,18 +73,6 @@ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz#016d855b6bc459fd908095811f6826e45dd4ba64" integrity sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA== -"@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== - dependencies: - semver "^7.3.5" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - "@rudderstack/rudder-sdk-node@^1.1.4": version "1.1.4" resolved "https://registry.npmjs.org/@rudderstack/rudder-sdk-node/-/rudder-sdk-node-1.1.4.tgz" @@ -130,48 +104,11 @@ resolved "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz" integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - -abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" @@ -179,11 +116,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - any-promise@^1.0.0: version "1.3.0" resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" @@ -194,19 +126,6 @@ app-root-path@^3.1.0: resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz" integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - async@^3.2.3: version "3.2.4" resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" @@ -261,14 +180,6 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" @@ -307,24 +218,6 @@ bull@^4.7.0: semver "^7.3.2" uuid "^8.3.0" -cacache@^17.0.0: - version "17.1.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^7.0.3" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -343,16 +236,6 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - cli-highlight@^2.1.11: version "2.1.11" resolved "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz" @@ -420,11 +303,6 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - color@^3.1.3: version "3.2.1" resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" @@ -446,16 +324,6 @@ component-type@^1.2.1: resolved "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz" integrity sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg== -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - cron-parser@^4.2.1: version "4.7.1" resolved "https://registry.npmjs.org/cron-parser/-/cron-parser-4.7.1.tgz" @@ -463,15 +331,6 @@ cron-parser@^4.2.1: dependencies: luxon "^3.2.1" -cross-spawn@^7.0.0: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypt@0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" @@ -484,7 +343,7 @@ date-fns@^2.29.3: dependencies: "@babel/runtime" "^7.21.0" -debug@4, debug@^4.3.3, debug@^4.3.4: +debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -508,11 +367,6 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - denque@^2.0.1: version "2.1.0" resolved "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz" @@ -528,33 +382,16 @@ dotenv@^16.0.3: resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - enabled@2.0.x: version "2.0.0" resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz" integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -562,16 +399,6 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -582,11 +409,6 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== - fecha@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz" @@ -607,52 +429,16 @@ follow-redirects@^1.14.8: resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" @@ -668,29 +454,6 @@ github-from-package@0.0.0: resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== -glob@^10.2.2: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" @@ -702,77 +465,21 @@ glob@^8.1.0: minimatch "^5.0.1" once "^1.3.0" -graceful-fs@^4.2.6: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - highlight.js@^10.7.1: version "10.7.3" resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== -http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -806,11 +513,6 @@ ioredis@^5.0.0: redis-parser "^3.0.0" standard-as-callback "^2.1.0" -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== - is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" @@ -826,11 +528,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - is-retry-allowed@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz" @@ -841,20 +538,6 @@ is-stream@^2.0.0: resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - join-component@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz" @@ -908,42 +591,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.7.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== - luxon@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz" integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== -make-fetch-happen@^11.0.3: - version "11.1.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - md5@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz" @@ -958,13 +610,6 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@^5.0.1: version "5.1.6" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" @@ -972,92 +617,16 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0, minimist@^1.2.3: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== - dependencies: - minipass "^7.0.3" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - -minizlib@^2.1.1, minizlib@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - mkdirp@^2.1.3: version "2.1.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz" @@ -1068,7 +637,7 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: +ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -1120,11 +689,6 @@ napi-macros@^2.0.0: resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== -negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - node-abi@^3.3.0: version "3.51.0" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" @@ -1137,45 +701,6 @@ node-gyp-build-optional-packages@5.0.3: resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz" integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== -node-gyp-build@^4.6.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" - integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== - -node-gyp@^9.4.0: - version "9.4.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" - integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^11.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - object-assign@^4.0.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -1200,13 +725,6 @@ p-finally@^1.0.0: resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-timeout@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" @@ -1231,24 +749,6 @@ parse5@^6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - prebuild-install@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" @@ -1267,14 +767,6 @@ prebuild-install@^7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -1350,18 +842,6 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -1372,11 +852,6 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz" integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA== -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - semver@^7.3.2, semver@^7.3.5: version "7.5.4" resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" @@ -1391,11 +866,6 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - sha.js@^2.4.11: version "2.4.11" resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" @@ -1404,28 +874,6 @@ sha.js@^2.4.11: inherits "^2.0.1" safe-buffer "^5.0.1" -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -1447,35 +895,6 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - -ssri@^10.0.0: - version "10.0.5" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== - dependencies: - minipass "^7.0.3" - stack-trace@0.0.x: version "0.0.10" resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" @@ -1486,16 +905,7 @@ standard-as-callback@^2.1.0: resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1504,15 +914,6 @@ standard-as-callback@^2.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" @@ -1520,13 +921,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -1534,13 +928,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -1574,18 +961,6 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^6.1.11, tar@^6.1.2: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - text-hex@1.0.x: version "1.0.0" resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz" @@ -1643,20 +1018,6 @@ typeorm@^0.3.16: uuid "^9.0.0" yargs "^17.6.2" -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -1672,20 +1033,6 @@ uuid@^9.0.0: resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== -which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - winston-transport@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz" @@ -1712,15 +1059,6 @@ winston@^3.6.0: triple-beam "^1.3.0" winston-transport "^4.5.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -1730,15 +1068,6 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index 55846cf3a..4fcaf3977 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -1,7 +1,9 @@ import Logger from 'electron-log'; import eventBus from '../event-bus'; import { getRootVirtualDrive } from '../virutal-root-folder/service'; -import fuse from '@cocalc/fuse-native'; +// eslint-disable-next-line @typescript-eslint/no-var-requires +// const fuse = require('@cocalc/fuse-native'); +const fuse = require('@gcas/fuse'); let _fuse: { unmount(arg0: (err: any) => void): unknown; @@ -14,7 +16,17 @@ function spawnSyncEngineWorker() { if (path === '/') { cb(0, { mode: 16877, size: 0 }); } else if (path === '/hello.txt') { - cb(0, { mode: 33188, size: 12 }); + Logger.debug('HELLO'); + return process.nextTick(cb, 0, { + mtime: new Date(), + atime: new Date(), + ctime: new Date(), + nlink: 1, + size: 12, + mode: 33188, + uid: process.getuid ? process.getuid() : 0, + gid: process.getgid ? process.getgid() : 0, + }); } else { cb(fuse.ENOENT); } @@ -35,33 +47,30 @@ function spawnSyncEngineWorker() { }, read: ( path: string, - fd, - buf, - len, - pos, + fd: any, + buf: Buffer, + len: number, + pos: number, cb: (code: number, params?: any) => void ) => { + Logger.debug(path, fd, buf, len, pos); if (path !== '/hello.txt') { - return cb(fuse.ENOENT); + return process.nextTick(cb, fuse.ENOENT); } + const str = 'hello world\n'.slice(pos); - const data = Buffer.from('Hello, FUSE!'); + if (!str) return process.nextTick(cb, 0); + buf.write(str); - if (pos >= data.length) { - return cb(0); - } - - const slice = data.slice(pos, pos + len); - slice.copy(buf); - cb(slice.length); - }, - release: function ( - readPath: string, - fd: number, - cb: (status: number) => void - ): void { - throw new Error('Function not implemented.'); + return process.nextTick(cb, str.length); }, + // release: function ( + // readPath: string, + // fd: number, + // cb: (status: number) => void + // ): void { + // throw new Error('Function not implemented.'); + // }, }; const root = getRootVirtualDrive(); @@ -73,21 +82,26 @@ function spawnSyncEngineWorker() { mkdir: true, force: true, }); + _fuse.mount((err: any) => { if (err) { Logger.error(`FUSE mount error: ${err}`); } }); - fuse.isConfigured((isConfigured: boolean) => { - Logger.info(`FUSE is configured: ${isConfigured}`); + // fuse.isConfigured((err: Error | null, isConfigured: boolean) => { + // if (err) { + // Logger.error('FUSE ERROR: ', err); + // } - if (!isConfigured) { - fuse.configure((...params: any[]) => { - Logger.debug(`FUSE configure cb params: ${{ params }}`); - }); - } - }); + // Logger.info(`FUSE is configured: ${isConfigured}`); + + // if (!isConfigured) { + // fuse.configure((...params: any[]) => { + // Logger.debug(`FUSE configure cb params: ${{ params }}`); + // }); + // } + // }); } export async function stopSyncEngineWatcher() { diff --git a/yarn.lock b/yarn.lock index 40a09d2d6..f345e2aa5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1126,20 +1126,21 @@ glob "^7.1.6" minimatch "^3.0.4" -"@electron/get@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@electron/get/-/get-2.0.2.tgz#ae2a967b22075e9c25aaf00d5941cd79c21efd7e" - integrity sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g== +"@electron/get@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.14.1.tgz#16ba75f02dffb74c23965e72d617adc721d27f40" + integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw== dependencies: debug "^4.1.1" env-paths "^2.2.0" fs-extra "^8.1.0" - got "^11.8.5" + got "^9.6.0" progress "^2.0.3" semver "^6.2.0" sumchecker "^3.0.1" optionalDependencies: global-agent "^3.0.0" + global-tunnel-ng "^2.7.1" "@electron/universal@1.2.1": version "1.2.1" @@ -2089,6 +2090,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + "@sindresorhus/is@^4.0.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" @@ -2219,6 +2225,13 @@ "@svgr/plugin-jsx" "^6.5.1" "@svgr/plugin-svgo" "^6.5.1" +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@szmarczak/http-timer@^4.0.5": version "4.0.6" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" @@ -2636,10 +2649,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.32.tgz#5b5becc5da76fc055b2a601c8a3adbf13891227e" integrity sha512-zpnXe4dEz6PrWz9u7dqyRoq9VxwCvoXRPy/ewhmMa1CgEyVmtL1NJPQ2MX+4pf97vetquVKkpiMx0MwI8pjNOw== -"@types/node@^18.11.18": - version "18.16.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.17.tgz#d2512c03313db6329f7cb515fc8b508e658230c4" - integrity sha512-QAkjjRA1N7gPJeAP4WLXZtYv6+eMXFNviqktCDt4GLcmCugMr5BcRHfkOjCQzvCsnMp+L79a54zBkbw356xv9Q== +"@types/node@^16.11.26": + version "16.18.59" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.59.tgz#4cdbd631be6d9be266a96fb17b5d0d7ad6bbe26c" + integrity sha512-PJ1w2cNeKUEdey4LiPra0ZuxZFOGvetswE8qHRriV/sUkL5Al4tTmPV9D2+Y/TPIxTHHgxTfRjZVKWhPw/ORhQ== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -2826,13 +2839,6 @@ dependencies: "@types/yargs-parser" "*" -"@types/yauzl@^2.9.1": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" - integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== - dependencies: - "@types/node" "*" - "@typescript-eslint/eslint-plugin@^5.4.0", "@typescript-eslint/eslint-plugin@^5.51.0", "@typescript-eslint/eslint-plugin@^5.6.0", "@typescript-eslint/eslint-plugin@^5.8.1": version "5.59.11" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.11.tgz#8d466aa21abea4c3f37129997b198d141f09e76f" @@ -3917,6 +3923,19 @@ cacheable-lookup@^5.0.3: resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + cacheable-request@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" @@ -4314,6 +4333,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + concurrently@^6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.5.1.tgz#4518c67f7ac680cf5c34d5adf399a2a2047edc8c" @@ -4344,6 +4373,14 @@ conf@^10.2.0: pkg-up "^3.1.0" semver "^7.3.5" +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + confusing-browser-globals@^1.0.10: version "1.0.11" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" @@ -4658,7 +4695,7 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@2.6.9, debug@^2.6.8: +debug@2.6.9, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -4707,6 +4744,13 @@ decode-uri-component@^0.2.2: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -4772,6 +4816,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + defer-to-connect@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" @@ -5071,6 +5120,11 @@ duplexer2@^0.1.2: dependencies: readable-stream "^2.0.2" +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -5255,14 +5309,14 @@ electron-updater@^4.6.4: lodash.isequal "^4.5.0" semver "^7.3.5" -electron@^25.8.1: - version "25.9.3" - resolved "https://registry.yarnpkg.com/electron/-/electron-25.9.3.tgz#cdd53a30fb914adadcfbd34124237fb38b1c07d0" - integrity sha512-dacaHg/PuwVcFRgPDCM5j7UDzqGJWOsbBRdS5wPKLNS/ejPeccIjuNUT1cqcrpvCJKAFW8swHWg9kdizNSEDHQ== +electron@19.1.9: + version "19.1.9" + resolved "https://registry.yarnpkg.com/electron/-/electron-19.1.9.tgz#01995eea4014f7cdb2f616f5f3492d4ed6f5e4f0" + integrity sha512-XT5LkTzIHB+ZtD3dTmNnKjVBWrDWReCKt9G1uAFLz6uJMEVcIUiYO+fph5pLXETiBw/QZBx8egduMEfIccLx+g== dependencies: - "@electron/get" "^2.0.0" - "@types/node" "^18.11.18" - extract-zip "^2.0.1" + "@electron/get" "^1.14.1" + "@types/node" "^16.11.26" + extract-zip "^1.0.3" emittery@^0.8.1: version "0.8.1" @@ -5289,7 +5343,7 @@ enabled@2.0.x: resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== -encodeurl@~1.0.2: +encodeurl@^1.0.2, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== @@ -5968,16 +6022,15 @@ express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" -extract-zip@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" - integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== +extract-zip@^1.0.3: + version "1.7.0" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" + integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== dependencies: - debug "^4.1.1" - get-stream "^5.1.0" + concat-stream "^1.6.2" + debug "^2.6.9" + mkdirp "^0.5.4" yauzl "^2.10.0" - optionalDependencies: - "@types/yauzl" "^2.9.1" extsprintf@^1.2.0: version "1.4.1" @@ -6342,6 +6395,13 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -6428,6 +6488,16 @@ global-agent@^3.0.0: semver "^7.3.2" serialize-error "^7.0.1" +global-tunnel-ng@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f" + integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== + dependencies: + encodeurl "^1.0.2" + lodash "^4.17.10" + npm-conf "^1.1.3" + tunnel "^0.0.6" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -6497,7 +6567,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@^11.7.0, got@^11.8.5: +got@^11.7.0: version "11.8.6" resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== @@ -6514,6 +6584,23 @@ got@^11.7.0, got@^11.8.5: p-cancelable "^2.0.0" responselike "^2.0.0" +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -6923,6 +7010,11 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" @@ -7863,6 +7955,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -7992,6 +8089,13 @@ keyboardevents-areequal@^0.2.1: resolved "https://registry.yarnpkg.com/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194" integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw== +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + keyv@^4.0.0: version "4.5.2" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" @@ -8231,7 +8335,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8297,6 +8401,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -8515,7 +8624,7 @@ mimic-fn@^3.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== -mimic-response@^1.0.0: +mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== @@ -8648,7 +8757,7 @@ minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" -mkdirp@^0.5.1, mkdirp@^0.5.5: +mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -8849,11 +8958,24 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + normalize-url@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npm-conf@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -9052,6 +9174,11 @@ ora@^5.1.0: strip-ansi "^6.0.0" wcwidth "^1.0.1" +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" @@ -9240,6 +9367,11 @@ pify@^2.3.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + pirates@^4.0.1, pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -9586,6 +9718,11 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -9664,6 +9801,11 @@ prop-types@^15.6.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -9933,7 +10075,7 @@ read-pkg@^6.0.0: parse-json "^5.2.0" type-fest "^1.0.1" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@~2.3.6: +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -10123,6 +10265,13 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + responselike@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" @@ -11139,6 +11288,11 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -11280,6 +11434,11 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -11348,6 +11507,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + typescript@^4.5.2, typescript@^4.5.4: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" @@ -11460,6 +11624,13 @@ url-loader@^4.1.1: mime-types "^2.1.27" schema-utils "^3.0.0" +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" From 76d6f7d5d8130140b73673661b871d63747fa479 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Fri, 27 Oct 2023 14:14:27 +0200 Subject: [PATCH 029/188] feat: rename file --- src/main/background-processes/sync-engine.ts | 57 +++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index 4fcaf3977..94793e51c 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -1,6 +1,9 @@ import Logger from 'electron-log'; import eventBus from '../event-bus'; import { getRootVirtualDrive } from '../virutal-root-folder/service'; +import fs from 'fs'; +import { error } from 'console'; +import { resolve } from 'path'; // eslint-disable-next-line @typescript-eslint/no-var-requires // const fuse = require('@cocalc/fuse-native'); const fuse = require('@gcas/fuse'); @@ -10,30 +13,34 @@ let _fuse: { mount: (arg0: (err: any) => void) => void; }; +const files: Record = { + '/hello.txt': { + mtime: new Date(), + atime: new Date(), + ctime: new Date(), + nlink: 1, + size: 12, + mode: 33188, + uid: 1234, + gid: 1234, + }, +}; + function spawnSyncEngineWorker() { const ops = { getattr: (path: string, cb: (code: number, params?: any) => void) => { if (path === '/') { cb(0, { mode: 16877, size: 0 }); - } else if (path === '/hello.txt') { - Logger.debug('HELLO'); - return process.nextTick(cb, 0, { - mtime: new Date(), - atime: new Date(), - ctime: new Date(), - nlink: 1, - size: 12, - mode: 33188, - uid: process.getuid ? process.getuid() : 0, - gid: process.getgid ? process.getgid() : 0, - }); + } else if (files[path] !== undefined) { + return process.nextTick(cb, 0, files[path]); } else { cb(fuse.ENOENT); } }, readdir: (path: string, cb: (code: number, params?: any) => void) => { if (path === '/') { - cb(0, ['.', '..', 'hello.txt']); + const filesNames = Object.keys(files).map((n) => n.split('/').join('')); + cb(0, ['.', '..', ...filesNames]); } else { cb(fuse.ENOENT); } @@ -64,6 +71,30 @@ function spawnSyncEngineWorker() { return process.nextTick(cb, str.length); }, + rename: async (src: string, dest: string, cb: any) => { + if (files[src] === undefined) { + return cb(fuse.ENOENT); + } + + const srcFile = files[src]; + + const destFile = { ...srcFile }; + + delete files[src]; + files[dest] = destFile; + + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); + + cb(0); + // fs.rename(src, dest, (error) => { + // if (error) { + // Logger.error('RENAME ERROR: ', error); + // return cb(fuse.ENOENT); + // } + // }); + }, // release: function ( // readPath: string, // fd: number, From 4ce3353a00c6ab4acdd928905f7510825ad00eec Mon Sep 17 00:00:00 2001 From: joan vicens Date: Fri, 27 Oct 2023 14:18:33 +0200 Subject: [PATCH 030/188] chore: refactor --- src/main/background-processes/sync-engine.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index 94793e51c..c7d74e37d 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -46,11 +46,13 @@ function spawnSyncEngineWorker() { } }, open: (path: string, flags, cb: (code: number, params?: any) => void) => { - if (path === '/hello.txt') { - cb(0, 123); // Use a unique file descriptor (123 in this example) - } else { - cb(fuse.ENOENT); + const file = files[path]; + + if (!file) { + return cb(fuse.ENOENT); } + + cb(0, file.uid); }, read: ( path: string, @@ -60,10 +62,12 @@ function spawnSyncEngineWorker() { pos: number, cb: (code: number, params?: any) => void ) => { - Logger.debug(path, fd, buf, len, pos); - if (path !== '/hello.txt') { - return process.nextTick(cb, fuse.ENOENT); + const file = files[path]; + + if (!file) { + return cb(fuse.ENOENT); } + const str = 'hello world\n'.slice(pos); if (!str) return process.nextTick(cb, 0); From 5661549c5413e819a7ea43a84eec835c8c5b914b Mon Sep 17 00:00:00 2001 From: joan vicens Date: Fri, 27 Oct 2023 14:35:13 +0200 Subject: [PATCH 031/188] feat: list and create folders --- src/main/background-processes/sync-engine.ts | 37 ++++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index c7d74e37d..386473994 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -4,6 +4,7 @@ import { getRootVirtualDrive } from '../virutal-root-folder/service'; import fs from 'fs'; import { error } from 'console'; import { resolve } from 'path'; +import { PassThrough } from 'stream'; // eslint-disable-next-line @typescript-eslint/no-var-requires // const fuse = require('@cocalc/fuse-native'); const fuse = require('@gcas/fuse'); @@ -26,6 +27,19 @@ const files: Record = { }, }; +const folders: Record = { + '/folder': { + uid: 12340, + gid: 12340, + mtime: new Date(), + atime: new Date(), + ctime: new Date(), + nlink: 1, + size: 12, + mode: 16877, + }, +}; + function spawnSyncEngineWorker() { const ops = { getattr: (path: string, cb: (code: number, params?: any) => void) => { @@ -33,6 +47,8 @@ function spawnSyncEngineWorker() { cb(0, { mode: 16877, size: 0 }); } else if (files[path] !== undefined) { return process.nextTick(cb, 0, files[path]); + } else if (folders[path]) { + return cb(0, folders[path]); } else { cb(fuse.ENOENT); } @@ -40,7 +56,10 @@ function spawnSyncEngineWorker() { readdir: (path: string, cb: (code: number, params?: any) => void) => { if (path === '/') { const filesNames = Object.keys(files).map((n) => n.split('/').join('')); - cb(0, ['.', '..', ...filesNames]); + const foldersNames = Object.keys(folders).map((n) => + n.split('/').join('') + ); + cb(0, ['.', '..', ...filesNames, ...foldersNames]); } else { cb(fuse.ENOENT); } @@ -92,12 +111,16 @@ function spawnSyncEngineWorker() { }); cb(0); - // fs.rename(src, dest, (error) => { - // if (error) { - // Logger.error('RENAME ERROR: ', error); - // return cb(fuse.ENOENT); - // } - // }); + }, + create: async (path: string, mode: number, cb: any) => {}, + mkdir: async (path: string, mode: number, cb: any) => { + folders[path] = { + uid: 123401, + gid: 123401, + mode: 16877, + }; + + cb(0); }, // release: function ( // readPath: string, From 471d17b596a7a77834cda9e4e2ebfc8874ea3a95 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Fri, 27 Oct 2023 17:37:20 +0200 Subject: [PATCH 032/188] prototype --- src/main/background-processes/sync-engine.ts | 268 ++++++++++++++----- 1 file changed, 206 insertions(+), 62 deletions(-) diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index 386473994..670b2cdf4 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -1,52 +1,91 @@ import Logger from 'electron-log'; import eventBus from '../event-bus'; import { getRootVirtualDrive } from '../virutal-root-folder/service'; -import fs from 'fs'; -import { error } from 'console'; -import { resolve } from 'path'; -import { PassThrough } from 'stream'; +import fs, { unlink } from 'fs'; +import _path from 'path'; +import { app } from 'electron'; +import path from 'path'; + // eslint-disable-next-line @typescript-eslint/no-var-requires // const fuse = require('@cocalc/fuse-native'); +// eslint-disable-next-line @typescript-eslint/no-var-requires const fuse = require('@gcas/fuse'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const Chance = require('chance'); let _fuse: { unmount(arg0: (err: any) => void): unknown; mount: (arg0: (err: any) => void) => void; }; -const files: Record = { - '/hello.txt': { - mtime: new Date(), - atime: new Date(), - ctime: new Date(), - nlink: 1, - size: 12, - mode: 33188, - uid: 1234, - gid: 1234, - }, -}; +const temp = app.getPath('temp'); -const folders: Record = { - '/folder': { - uid: 12340, - gid: 12340, - mtime: new Date(), - atime: new Date(), - ctime: new Date(), - nlink: 1, - size: 12, - mode: 16877, - }, -}; +const tempFolder = _path.join(temp, 'InternxtDrive'); + +const files: Record = {}; + +const folders: Record = {}; + +const chance = new Chance(); + +async function spawnSyncEngineWorker() { + await new Promise((resolve) => + fs.stat(tempFolder, (err) => { + if (err) { + fs.mkdirSync(tempFolder); + } + resolve(); + }) + ); + + const renameFile = async (src: string, dest: string) => { + const srcFile = files[src]; + + const destFile = { ...srcFile }; + + delete files[src]; + files[dest] = destFile; + + const oldPath = _path.join(tempFolder, src); + const newPath = _path.join(tempFolder, dest); + + fs.renameSync(oldPath, newPath); + }; + + const renameFolder = async (src: string, dest: string) => { + const srcFolder = folders[src]; + + const destFolder = { ...srcFolder }; + + delete folders[src]; + folders[dest] = destFolder; + + const oldPath = _path.join(tempFolder, src); + const newPath = _path.join(tempFolder, dest); + + fs.renameSync(oldPath, newPath); + }; -function spawnSyncEngineWorker() { const ops = { getattr: (path: string, cb: (code: number, params?: any) => void) => { + Logger.debug(`GETATTR ${path}`); if (path === '/') { cb(0, { mode: 16877, size: 0 }); } else if (files[path] !== undefined) { - return process.nextTick(cb, 0, files[path]); + const file = files[path]; + + const getSize = () => { + try { + const { size } = fs.statSync(_path.join(tempFolder, path)); + return size; + } catch { + return 0; + } + }; + + const size = getSize(); + + return process.nextTick(cb, 0, { ...file, size }); } else if (folders[path]) { return cb(0, folders[path]); } else { @@ -54,17 +93,45 @@ function spawnSyncEngineWorker() { } }, readdir: (path: string, cb: (code: number, params?: any) => void) => { + Logger.debug(`READDIR ${path}`); if (path === '/') { - const filesNames = Object.keys(files).map((n) => n.split('/').join('')); - const foldersNames = Object.keys(folders).map((n) => - n.split('/').join('') - ); + const filesNames = Object.keys(files) + .filter((f) => { + return f.includes('f', 1); + }) + .map((n) => n.split('/')[-1]); + const foldersNames = Object.keys(folders) + .filter((f) => !f.startsWith('/.Trash-')) + .map((n) => n.split('/').join('')); cb(0, ['.', '..', ...filesNames, ...foldersNames]); } else { - cb(fuse.ENOENT); + const isFolder = Object.keys(folders).includes(path); + + if (!isFolder) { + return cb(fuse.ENOENT); + } + + const filesNames = Object.keys(files) + .filter((f) => { + return f.includes(_path.dirname(path)); + }) + .map((f) => { + return _path.basename(f); + }); + + const foldersNames = Object.keys(folders) + .filter((f) => { + return f.includes(_path.dirname(path)); + }) + .map((f) => { + return _path.basename(f); + }); + + cb(0, ['.', '..', ...filesNames, ...foldersNames]); } }, open: (path: string, flags, cb: (code: number, params?: any) => void) => { + Logger.debug(`OPEN ${path}`); const file = files[path]; if (!file) { @@ -81,54 +148,131 @@ function spawnSyncEngineWorker() { pos: number, cb: (code: number, params?: any) => void ) => { - const file = files[path]; + Logger.debug(`READ ${path}`); + const fullPath = _path.join(tempFolder, path); + fs.readFile(fullPath, (err, data) => { + if (err) { + console.error(`Error reading file: ${err}`); + cb(fuse.ENOENT); // Indicate an error code, e.g., if the file doesn't exist + return; + } - if (!file) { - return cb(fuse.ENOENT); - } + // Convert the data to a Buffer + const dataBuffer = Buffer.from(data); - const str = 'hello world\n'.slice(pos); + // Determine the number of bytes to read based on the length and position + const bytesRead = Math.min(dataBuffer.length - pos, len); - if (!str) return process.nextTick(cb, 0); - buf.write(str); + // Copy the data to the provided buffer + dataBuffer.copy(buf, 0, pos, pos + bytesRead); - return process.nextTick(cb, str.length); + cb(bytesRead); // Indicate the number of bytes read + }); }, rename: async (src: string, dest: string, cb: any) => { - if (files[src] === undefined) { - return cb(fuse.ENOENT); + Logger.debug(`RENAME ${src} -> ${dest}`); + // ALSO HANDLES THE MOVE ACTION + if (files[src] !== undefined) { + await renameFile(src, dest); + cb(0); + } + + if (folders[src] !== undefined) { + await renameFolder(src, dest); + cb(0); } - const srcFile = files[src]; + return cb(fuse.ENOENT); + }, + create: async (path: string, mode: number, cb: any) => { + Logger.debug(`CREATE ${path}`); + files[path] = { + uid: chance.integer({ min: 100 }), + gid: chance.integer({ min: 100 }), + mode: 33188, + }; + + cb(0); + }, + write: ( + path: string, + fd: string, + buffer: Buffer, + len: number, + pos: number, + cb: any + ) => { + Logger.debug(`WRITE ${path}`); + const fullPath = _path.join(tempFolder, path); + fs.open(fullPath, 'w', (err, fileDescriptor) => { + if (err) { + console.error(`Error opening file for writing: ${err}`); + cb(fuse.ENOENT); // Indicate an error code, e.g., if the file doesn't exist + return; + } - const destFile = { ...srcFile }; + // Create a Buffer from the incoming data + const dataBuffer = Buffer.from(buffer.slice(0, len)); - delete files[src]; - files[dest] = destFile; + // Write data to the file at the specified position + fs.write(fileDescriptor, dataBuffer, 0, len, pos, (writeErr) => { + if (writeErr) { + console.error(`Error writing to file: ${writeErr}`); + cb(fuse.EIO); // Indicate an error code, e.g., EIO for I/O error + } else { + cb(len); // Indicate success by returning the number of bytes written + } - await new Promise((resolve) => { - setTimeout(resolve, 100); + // Close the file + fs.close(fileDescriptor, () => { + if (writeErr) { + console.error(`Error closing file: ${writeErr}`); + } + }); + }); }); - - cb(0); }, - create: async (path: string, mode: number, cb: any) => {}, mkdir: async (path: string, mode: number, cb: any) => { + Logger.debug(`MKDIR ${path}`); folders[path] = { uid: 123401, gid: 123401, mode: 16877, }; + fs.mkdirSync(_path.join(tempFolder, path)); + + cb(0); + }, + release: function ( + readPath: string, + fd: number, + cb: (status: number) => void + ): void { + Logger.debug(`RELEASE ${readPath}`); + cb(0); + }, + unlink: (path: string, cb: (code: number) => void) => { + Logger.debug(`UNLINK ${path}`); + delete files[path]; + + unlink(_path.join(tempFolder, path), (err) => { + if (err) { + Logger.error('ERROR DELETING FILE', err); + return cb(fuse.EIO); + } + + cb(0); + }); + }, + rmdir: (path: string, cb: (code: number) => void) => { + Logger.debug(`RMDIR ${path}`); + delete folders[path]; + + fs.rmdirSync(_path.join(tempFolder, path)); + cb(0); }, - // release: function ( - // readPath: string, - // fd: number, - // cb: (status: number) => void - // ): void { - // throw new Error('Function not implemented.'); - // }, }; const root = getRootVirtualDrive(); @@ -136,7 +280,7 @@ function spawnSyncEngineWorker() { Logger.debug('ROOT FOLDER: ', root); _fuse = new fuse(root, ops, { - debug: true, + debug: false, mkdir: true, force: true, }); From 629b7fa5eff47269e7856926ab380fd48a8485a4 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Thu, 2 Nov 2023 11:01:24 +0100 Subject: [PATCH 033/188] chore: version bump --- package.json | 2 +- release/app/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5ba24a489..a1a5c0e5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.0", + "version": "2.0.2", "author": "Internxt ", "description": "Internxt Drive client UI", "license": "AGPL-3.0", diff --git a/release/app/package.json b/release/app/package.json index 7f31c2a10..b61502429 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.0", + "version": "2.0.2", "description": "Internxt Drive client UI", "main": "./dist/main/main.js", "author": "Internxt ", From ee1d771b55835253efa025301198be2258bc19c6 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Tue, 7 Nov 2023 10:24:10 +0100 Subject: [PATCH 034/188] changed tray icons with white-filled new ones --- assets/tray/alert.png | Bin 1745 -> 1504 bytes assets/tray/alert@2x.png | Bin 4910 -> 3984 bytes assets/tray/alert@3x.png | Bin 9304 -> 7059 bytes assets/tray/idle.png | Bin 1656 -> 1432 bytes assets/tray/idle@2x.png | Bin 4813 -> 3906 bytes assets/tray/idle@3x.png | Bin 9442 -> 7050 bytes assets/tray/loading.png | Bin 1399 -> 1171 bytes assets/tray/loading@2x.png | Bin 3520 -> 2778 bytes assets/tray/loading@3x.png | Bin 6703 -> 4910 bytes assets/tray/syncing.png | Bin 1893 -> 1649 bytes assets/tray/syncing@2x.png | Bin 5222 -> 4277 bytes assets/tray/syncing@3x.png | Bin 9701 -> 7487 bytes 12 files changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/tray/alert.png b/assets/tray/alert.png index b2e12a6dbcb388a339a6f74ea463d6e73ada700a..eb3bb83e0a851709924f7d29932f438650e4368f 100644 GIT binary patch delta 1487 zcmV;=1u**24d4rqBYy>_NklM1Bi1iuJ(Gcvb}kfT^jD(SHXqO9i+dLdBaDO3}AkM=|1U9R*Tljq-(#dFkJJP%`Pw0rM<8f?hQFl{Y<;JFS_VX0&r0Uv+c zBu{zVavE-W^ES@B=u?eH%Ff+<$vCeWAEBWV%OeiD3V%(XBqptGEq=h+Hq$My%V2=v zfo0nKk)x~Z=F;$j*WJOU9Xlg)FfV-8LwV;-uOst_&Xtv8zfpg+B2TpF{%4ec=*QF? zHTfi6a`p>TX20P{FS?HXzx}fTwJLF&KYAQP150VR_`1(m|Gp4O^&M-pXvJw+K%T)a zRH$@`kbgh%j>Gko$FCqtv33h*T<}o@7p)Cg&& z-6LCW5Cm%KynD|tx#-%@aOt^YG+c7di)qz@!hibeon5~bcpM3W*Jmv8Z1p3*u{U<#C)i5EC)1)I5%NlE!#Of?q z^Y8nnzI{Ll1pX&TA&&3wxRjxRyHjT~PJaYH;+@tLni=n}LaQ3M$BXhwO@9)y!au^d6&UyEMbS~^VCy*;BdGrAXx}a8` zHO5hdPk(6T^x&7hmkTd{AA!7IMt>NbW`COZ^;sD%G>KxmGwreqED52henUg|8m0-wrw$^7@ywZ zJmHd+;CAi+afGg5b#C37vq<=vG^m(r(aaUw7_O z!G#NJ5=C$!B!QxJA$d{3f@mvTI3BO zFmAAln9zf^R-tt-*|>;WRH;rTglJ`wJ!g$UNK~si)qjYn91je#E+=Q4W9m(U%5al@ z!9GgZ0*Z>pD~c|;v?!u>1E5R+syJ&VB<@5p9x}&J9D-@(Mw^zE>(_al*VG55@2QRX zNgJe8O7;%9jMZ-7Yhz}mqRG40-d%J|_KmzX9V2{5flCy*B#dV6{Mngzw8_yWMH&HLdY}^Zm#E}zJudZ{9#e#LAxS%lW4d|mopT)jB``Ul&zSQ(?JjKm zRSDOR+TFQg`5HP>=8NQH^7%*$5hctkim1}f_4u%AY|n;_<3>5j8#(WhRW^?sY9^#P zaOCw_#)}j@e@|<_A}0!j>(?uzwMLT@C5NM&8h;!))ppGDl{1;5a?UEOZJN_--u3Be z9oCNF1!9z;1^I?X>2#aPX4%urT!5A+P>#o=%yEp}-VXWU;Gx(4BLzIz z6Ui;F^x?~zH8JK;oXhtrkfhTouV-+dN7L-8l08Wi+BI?CfhRj6R*O^CbY-QIuLc5h zib+($VQcN&`Q^L4%!~ZT9RBCgG`s6RUw>k`Ys?R94g`L$ff&l|0Ph*I!g{UWPsrdS zueRBLV|+AW6OxG0lo>B=-1vOK(QMxMWS&3sxbNXtlr0pvhfh#HYxQPr>*o34UV@p| zC?7k^!?rWW@g*rkYdo9Vym@}!ory?50R^oL`hmN@daP8JEH3E#jD2N%ytnX|$A1|O zf8`jp$peq$Yj~ipJ3Rkl;Gvg1utgP01xTm`mvYD$;ebl1x%}3r*4G!EjZT2e=c0 zD4KHm=;%so?K(V^nvHwq;*Iy~2`JM%K7EeN^O^PwTU>V-WYJR~ZYQVuD0sM)vO*S%5JBM-I4H;bZZ@ z$knpAzG8VSHv5mPF@-Kji3r!2LMTXRu71vwH;eV}JI;Br85EJE=7 Y3nl&@+$$1BH~;_u07*qoM6N<$g10PDN&o-= diff --git a/assets/tray/alert@2x.png b/assets/tray/alert@2x.png index 5561e04c174b29fc169d6f7b28eb5752c36b2784..33fa7ece9cffb8348b35c426cf096559ecb7240b 100644 GIT binary patch literal 3984 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 diff --git a/assets/tray/alert@3x.png b/assets/tray/alert@3x.png index 37b9e637f57bc04e31e22bd2af51fffa615b859d..c8d7ea97c59ea3104c0a5ec64749840e35f156b6 100644 GIT binary patch literal 7059 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 literal 9304 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 diff --git a/assets/tray/idle@2x.png b/assets/tray/idle@2x.png index 3c29290fe09cf808aa38ce0dac64deb2ac22c9f2..e9c2dbd36ce8e2da89a5dc0dc7b60eb993476ec3 100644 GIT binary patch literal 3906 zcmV-I554e-P)W_V0pK!6gxT9TTQAFQERrMd4cBA+pZDo zZPhl<^kpqCcXzgOc4r^;-^hOh+u$R-`4teJ#*+p0`gs`t#)oY#*vb~;B9E-`ur196 zH6`BX(K+Lg(fln3%-vnX^on|icB{eW*LeSV5FUpT5C4zX8#{5Zp$F$hp3?x-8%;!1 zo)$XQ)UszfdZJ907OPXxnhH}l)fKfBmx+NcaPo-ne<YOB2xg-UAYdL1@zbg4I} zG328?-Sdop2O&J)y>cdY??Z5p4@Hd3a|Bffv1fhYqUq;z?V1j`pL0fyY3a+To7{1? zdyLLYceC{L)IG&VpxYk#BeuHZGa+{Ge0uuPoqL(l=XY(EEiO^&x^o@Sj%vYLJNy`V zozAjy)$#+GHFqp;QD5$5?NX=tef1HkZFNRphSa{Z7dv+_AU?0!ce8q`vHS=v`iMdr z)ysPG1m;!tR67rkG^N%P%bK`-`6J@nL)E$cC$J(LmV07RQ!A*CeqS^7oZfqBA3Z)$ z8t+%?sdZ7BJ6==d9{Dn+_U&InY~TK`YTs&3=_oI`oy+>g_a;q!al09U`hsUmz5L?) zlc)II%&j+XGB1F?Jmu$V^3n(1pMLTd(SMV2XwW|l@y(luSVH4QW3lxn;+r=zbH)P9 z$qVm|^WpKVdD7qE$qXMdo_iVE#|?|tH~2l8Vy7JKc@eYb()`a^H2_i;E-JN**XYbN#4-p7J!RA1Hb0iY2GCAP+gfdYbl6JU-$ zVa)A^Pffo$#YXEvR!IjG6M`kNmK(nvEAX>X*>VO8HJr`-^8XUo}7sb2H!{3~D1wPE&++Q|!7dV(}a zqp+WE^1bGwIb;KZ8-suarHw_%DQ3DXef7{5*u&U$x4#`)oxlD4KVjUd=V_KjJ9o~% z@+H>{0{(Y5AeEr+MYW*pE@FUe4 z?A)ub{Xu)m%Ydu6X4Uf2HdK1)D@QJxgV(`X@31b!n2$FZBaA?dT<`TY;iOOH|1aNs z_LE@?kUQf}Ifugi4sTaTZGp9}AFMmz0jv#xkyD$#VmYX`D=vY5-jy%pJ_Y`|EnodB zUf_?S`O(&VKz6Ec(7u@Zi3Z|bPH)j1w8j8902naZfZ~mciMnk`J^aSN)tZ_86tb`W zpk$|D@>3mkbTKY=F)$v$>X1TM6=6g@XUdnHqA_rlMT|Z9EQ`PN!JM%t@71gb=}7ku zPIPm(*XlL-83m1j0+RGsvY-)}_R45m6Hs1$gJ7I>z86ev-ur0Cp5)bko-?(t+7)X1 z2>NcXG)n)z8Diy#qB(E{j1>lmQ6MlTusO+lmJlBwu)=`w_WM8hNUy$hxt(==gS3Y> z_rMlQ2O-=0oDI8Z3|Nkay2!P?kCJQVE3n6k7HJxC9wyQVIiHsci-iO~0x%146U!~Zp z9~a<^1YWmifSROVy5Um?*w5ol00w9?S!Y3YimN7#VJ_=6bMd-6!-1a7dmgIo z)of{P`d!j2D3|I^^LV&;0~TTMA_OYXCIie_3Hb{#jI0>*;G~zL!DCL?ia%_B3i+eI z1OEs$EAF*8&5HXN>x<65^8(Rlp0Tj98_@;>93Wry z@Cn-eBGXqLV`Glr6n^%LKZb)j`V__-w~0GT9RhdAuW2I-yd?ALQ;$`^1L!k15Piuk zNMfmPj;&Gln4r3Q9(p&lIzPw5`T941-uhE`@4KlE?MyYAvy-@b{2lQC<`@tMc5Z z&7eb$U}A>Jcd?XRov>*2O(Aza{>5{ve$Ai3Snh1zbr1UhlTI>c099^(t;_+em*%oA zK7i>+)LZs*qFK1|v?0RhUQOoVGe{20fzy8gisvjB>ow8XY-$U^N|NOeW z`$Pzvh$3>C1OtpQFTdoV+KoHz2)VOq#~sG`^*NfMd2Y`HLr-?@xfeea+Ph8Q?AW9E z^feQ4-Gjb%S6sAr`_j)lx=#oIl3xnWHsr|rVnXGQI&vBQX#Feu>!Y4C(plU=C|}Jc z-g@@{K7}(j)U|c1&(K`uU^_h%e_g=&c1H|$`(g#!f<<3>F<<~Mmph}6T$=Q12jiO0 zIKf!tQAaGnr;vZZy@$@!EI*&~;_Otvc*3{w27KYg=zs~?|1FfP(Ih#7C|sh->S+c? zEKB6eA7;FTSho>Nt}Kx+CQnC@mf-+vNA1i0b7FFHzxvwvC-_BVP4}?)SZih?uPGMp zlcz7!0&+f&X4yv%TE4ryt%Q%3>LJ_Xd$GlBF?aEoKET;0&FriV(^HdG@>D3Eohb(L zVlEV8$!Bnc$39c|1;w5&0@gb9xl4Vg#_i|A| zQ#F(0Kbq-Lb{Kw$7NSpXa%A31j3rlSs25V~`BL9<{YUlOdR@3J?#+Gk8;g6>8~zbh z75{|U(O$DG9A09P=E~P_Udt`eTjl|6*DE-%axZ?jw%@gS#yak{_-0YX$1kbJ2jA$J zwxr4Jc;CYKz`Q^tc#_U3UQ7R4P`_kAa-NafCRCkr*) z3gbN!E$o|UL3vpnr6t&yt36K~YxQW)s1dscm}@0c+_5)N?D3cxd@%NxJLuE=ZQb;W zs3H{()PwCe!f5w?81J^SddRLsun3S39#hAUkXJvkYowSQI@khsUZoFJwLn{sH<&&eA|}7|-8$Y^^k(%k)-HB# zb!l1+MV(#nxTYTetN-i^a5~U`=O7HXeijniY_VdnX)%_sC4#zg)QKJALHMax*5{bT zr!QL9Vh4F_-sj{yeRlh=_y$pRfwO{ou=QpbY<<`aH@~h&oBvAu|7Ql9_v^uiMff=J zAsa361~E1Avfk%4Y$T)_zUx`OquA$K@s>y!Z2qF#zS6JwquzA;B~h*7A(=4Ag^a2I Qn*aa+07*qoM6N<$f*1n#1^@s6 literal 4813 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 diff --git a/assets/tray/idle@3x.png b/assets/tray/idle@3x.png index ef9c3dcf71f3965f5c7c6f328d05ceb7cf99d0c3..e0fcb2f0830983240f414befe051f95c86ef4484 100644 GIT binary patch literal 7050 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 literal 9442 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 delta 1381 zcmV-r1)BPk3HJ(+BYyx1a7bBm000XU000XU0RWnu7ytkO0drDELIAGL9O(c600d`2 zO+f$vv5yPuIkE0e#5oy+&Jc+d6b>|?0J22^NCDkdq=cHrOMj7u>L@IcJMTQ+?9R`d z*>e=%X|%I5Z@%~c-YkOn_4fZ*I(K~h9w~L62$umU13-v>1bz+eYi%!nB0|oyoL|2J z1>?>KFXZloM<3jN&_XN@2yqF{@*}9r_}Cxjq@lfa<;6oUz^yNSe*?8X2sDgKc2myh z=qP}Bjf}n^&3{tTp#_n0lV07r^3ov=?mWn#C`LqVZmcr`0e2=v-8pd>BXME!-|XbM zCd_6nLgVX-IM7!bxp`#?N^}ORGdXX2D@13_8&z*%AC?xHYNH9L-<6P-yaKRhs5Geu z7+I;ErmRTN+@2?t_8=hya6HoaCXm%$f;sifgD?+v(SK&fuA(IR{qYH_Fo|M-bS6b` zwy_jhQxXIPMbH#_t<%0Rb|kkx|80Y5hQU`Tps~HR-n#2(2X{spO!ZMk6NIpmnIoAB zrXkC;dY1k+Po?&I!;w$Tt@W4pSj#a;ARY?z;q~>EyC4lR)uReei(%g_A4Mbt@S`Fu z|7@YB8hUmefe9t?kOF`E&jCBtJ=gk_c#NWVvsnhYN_6uCk$ z=YZ4uGLvL{)o@)FL@DUf!gt4IZ3qeItn z)ql>``A}0$R{RS!35vgsK}#%hmN!D!bA}IM&AX~BuVjPG=XJG4W$6vkThZx!`|4}G zl>has7kk`S{&cm0tQD~gWbH9LwjIiug(!?l+QfG*22>pNkv6DTnRX)mOi6u73!h4Z z3|!V~irrCy6ZR zGAnLuu5wYL@oBX`<)eb%r64+Rv4_+QBh&AE`a_qrsr5Q*O!bD`Ys^fqfC<$4i!DYJ zVogz62MjTWptFALcRIoJgW&LJ*xwTqjdS5u1MZyDpgT1*cIE zx^;8++t?MwN$Cnql#9CL&E0Q~_&qC6B;OSL$f^36ux+2$8u%dtEP*Uq;Z`)^*8EvX zZ+~3eF7jhJ+%YX}c@!U-E7@N>sec5JSy$cO`2Gi7FO=ER5s{txwIxpv4nqWVL|bm> z>;n81PP-M!KJWxN4UcO;={e(yLf=!xqeow|BPWnltQzBVO@PyBOk{COg+qF{fa*up z>#a@LWpDeN3d!5cX<9n7+CZAaETnMNPcXsMq}!d&Te)v>{lV9l*&pV*{a!4=*?#Fq za{OfkGK9>0f{n)e+t=Rt9w7PL>kan#LjhmsID3;L`FW;(CIYueB?H@Y<-Tjhk#JZF n^ADmr(z^JCX0T_h?)Lu&6lJE~fb7QQ00000NkvXXu0mjflc$PJ diff --git a/assets/tray/loading@2x.png b/assets/tray/loading@2x.png index fe53822d48bf054bbb2d21f27c8aa26543de28ea..2c58b8e7735d9281c33432cd33557d1b7e5adca7 100644 GIT binary patch delta 2771 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 diff --git a/assets/tray/loading@3x.png b/assets/tray/loading@3x.png index 5738d01797cafc1bcabfb76e8258a4f7f8e7cc18..7729e9662ee2c1272e6e7f414e2e0d872a2223b1 100644 GIT binary patch literal 4910 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 RWoQ5Z002ovPDHLkV1l$3kiq}} diff --git a/assets/tray/syncing@2x.png b/assets/tray/syncing@2x.png index e44e3b2c29f7ce4e3d06970bbd2399c0b5768e42..effea034c147718f58f780690ae3e892143702c7 100644 GIT binary patch literal 4277 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 XD=wVnBde;400000NkvXXu0mjfdw*qP literal 5222 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 diff --git a/assets/tray/syncing@3x.png b/assets/tray/syncing@3x.png index 119baf6c891d10c6e2158dfe37346542c551136d..c58f9a2feead5963c5323b288ee726edb74d3b7e 100644 GIT binary patch literal 7487 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 z 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 From 43ec739a8945c8c28706620bee825f25555e0663 Mon Sep 17 00:00:00 2001 From: joan vicens Date: Tue, 7 Nov 2023 10:46:20 +0100 Subject: [PATCH 035/188] wip --- release/app/package.json | 1 + release/app/yarn.lock | 540 ++++++++++++++++++- src/main/background-processes/sync-engine.ts | 24 +- 3 files changed, 557 insertions(+), 8 deletions(-) diff --git a/release/app/package.json b/release/app/package.json index cf5bb3900..d4ef5a050 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -11,6 +11,7 @@ "reload-virtual-drive": "yarn add --ignore-scripts ../../../node-win && npm run link-modules" }, "dependencies": { + "@cocalc/fuse-native": "^2.4.0", "@gcas/fuse": "^2.4.2", "@rudderstack/rudder-sdk-node": "^1.1.4", "better-sqlite3": "^8.3.0", diff --git a/release/app/yarn.lock b/release/app/yarn.lock index 81352052d..fead08ea2 100644 --- a/release/app/yarn.lock +++ b/release/app/yarn.lock @@ -16,6 +16,16 @@ dependencies: regenerator-runtime "^0.13.11" +"@cocalc/fuse-native@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@cocalc/fuse-native/-/fuse-native-2.4.0.tgz#feee5b75fef36a1b1b37135d8ccdc28d5dacf1e8" + integrity sha512-mhg+JZZkGq6cGN9Icy7Uu1J5/M1gR44t38DpxjZlRH4oyFcwpH2090/CFv2jGVaTOPrjgvxlb0jHNx9J7WUing== + dependencies: + nanoresource "^1.3.0" + napi-macros "^2.0.0" + node-gyp "^9.4.0" + node-gyp-build "^4.6.0" + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" @@ -30,6 +40,11 @@ enabled "2.0.x" kuler "^2.0.0" +"@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@gcas/fuse@^2.4.2": version "2.4.2" resolved "https://registry.yarnpkg.com/@gcas/fuse/-/fuse-2.4.2.tgz#149bd97ec8a60988f4868bacd719c7e8a1c41876" @@ -73,6 +88,22 @@ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.2.0.tgz#016d855b6bc459fd908095811f6826e45dd4ba64" integrity sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA== +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@rudderstack/rudder-sdk-node@^1.1.4": version "1.1.4" resolved "https://registry.npmjs.org/@rudderstack/rudder-sdk-node/-/rudder-sdk-node-1.1.4.tgz" @@ -104,6 +135,38 @@ resolved "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz" integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +abbrev@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" @@ -126,6 +189,19 @@ app-root-path@^3.1.0: resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz" integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + async@^3.2.3: version "3.2.4" resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" @@ -180,6 +256,14 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" @@ -218,6 +302,30 @@ bull@^4.7.0: semver "^7.3.2" uuid "^8.3.0" +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -236,6 +344,16 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + cli-highlight@^2.1.11: version "2.1.11" resolved "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz" @@ -303,6 +421,11 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + color@^3.1.3: version "3.2.1" resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" @@ -324,6 +447,16 @@ component-type@^1.2.1: resolved "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz" integrity sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg== +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + cron-parser@^4.2.1: version "4.7.1" resolved "https://registry.npmjs.org/cron-parser/-/cron-parser-4.7.1.tgz" @@ -343,7 +476,7 @@ date-fns@^2.29.3: dependencies: "@babel/runtime" "^7.21.0" -debug@^4.3.4: +debug@4, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -367,6 +500,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + denque@^2.0.1: version "2.1.0" resolved "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz" @@ -392,6 +530,13 @@ enabled@2.0.x: resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz" integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -399,6 +544,16 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -409,6 +564,11 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + fecha@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz" @@ -434,11 +594,32 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-minipass@^2.0.0, fs-minipass@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" @@ -454,7 +635,19 @@ github-from-package@0.0.0: resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== -glob@^8.1.0: +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.1, glob@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -465,21 +658,82 @@ glob@^8.1.0: minimatch "^5.0.1" once "^1.3.0" +graceful-fs@^4.2.6: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + highlight.js@^10.7.1: version "10.7.3" resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== +http-cache-semantics@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -513,6 +767,11 @@ ioredis@^5.0.0: redis-parser "^3.0.0" standard-as-callback "^2.1.0" +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" @@ -528,6 +787,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + is-retry-allowed@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz" @@ -538,6 +802,11 @@ is-stream@^2.0.0: resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + join-component@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz" @@ -591,11 +860,38 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + luxon@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz" integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== +make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + md5@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz" @@ -610,6 +906,13 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimatch@^5.0.1: version "5.1.6" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" @@ -622,11 +925,75 @@ minimist@^1.2.0, minimist@^1.2.3: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +minizlib@^2.1.1, minizlib@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mkdirp@^2.1.3: version "2.1.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz" @@ -637,7 +1004,7 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1, ms@^2.1.3: +ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -689,6 +1056,11 @@ napi-macros@^2.0.0: resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== +negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + node-abi@^3.3.0: version "3.51.0" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" @@ -701,6 +1073,45 @@ node-gyp-build-optional-packages@5.0.3: resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz" integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== +node-gyp-build@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" + integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + +node-gyp@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + object-assign@^4.0.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -725,6 +1136,13 @@ p-finally@^1.0.0: resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-timeout@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" @@ -749,6 +1167,11 @@ parse5@^6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + prebuild-install@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" @@ -767,6 +1190,19 @@ prebuild-install@^7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -842,6 +1278,18 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -852,6 +1300,11 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz" integrity sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA== +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + semver@^7.3.2, semver@^7.3.5: version "7.5.4" resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" @@ -866,6 +1319,11 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + sha.js@^2.4.11: version "2.4.11" resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" @@ -874,6 +1332,11 @@ sha.js@^2.4.11: inherits "^2.0.1" safe-buffer "^5.0.1" +signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -895,6 +1358,35 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + stack-trace@0.0.x: version "0.0.10" resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" @@ -905,7 +1397,7 @@ standard-as-callback@^2.1.0: resolved "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz" integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -961,6 +1453,18 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" +tar@^6.1.11, tar@^6.1.2: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + text-hex@1.0.x: version "1.0.0" resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz" @@ -1018,6 +1522,20 @@ typeorm@^0.3.16: uuid "^9.0.0" yargs "^17.6.2" +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -1033,6 +1551,20 @@ uuid@^9.0.0: resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== +which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + winston-transport@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz" diff --git a/src/main/background-processes/sync-engine.ts b/src/main/background-processes/sync-engine.ts index 670b2cdf4..8a5d8b40c 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/main/background-processes/sync-engine.ts @@ -4,7 +4,6 @@ import { getRootVirtualDrive } from '../virutal-root-folder/service'; import fs, { unlink } from 'fs'; import _path from 'path'; import { app } from 'electron'; -import path from 'path'; // eslint-disable-next-line @typescript-eslint/no-var-requires // const fuse = require('@cocalc/fuse-native'); @@ -67,6 +66,19 @@ async function spawnSyncEngineWorker() { }; const ops = { + listxattr: (path: string, cb: (err: number, list?: string[]) => void) => { + cb(0, ['sync_status', 'b']); + }, + getxattr: ( + path: string, + name: string, + size: number, + cb: (err: number, data: Buffer) => void + ) => { + Logger.debug('GETXATTR', path, name, size, cb); + const buff = Buffer.from('in sync'); + cb(0, buff); + }, getattr: (path: string, cb: (code: number, params?: any) => void) => { Logger.debug(`GETATTR ${path}`); if (path === '/') { @@ -85,9 +97,13 @@ async function spawnSyncEngineWorker() { const size = getSize(); - return process.nextTick(cb, 0, { ...file, size }); + return process.nextTick(cb, 0, { + ...file, + size, + sync_status: 'online', + }); } else if (folders[path]) { - return cb(0, folders[path]); + return cb(0, { ...folders[path], sync_status: 'online' }); } else { cb(fuse.ENOENT); } @@ -280,7 +296,7 @@ async function spawnSyncEngineWorker() { Logger.debug('ROOT FOLDER: ', root); _fuse = new fuse(root, ops, { - debug: false, + debug: true, mkdir: true, force: true, }); From 0cf7fe0b75ccbf4c4b34f9908baf472509e988ae Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Wed, 8 Nov 2023 16:02:49 +0100 Subject: [PATCH 036/188] fixed some file download envent calls --- .../application/ContentsDownloader.ts | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts index 85dd361c6..f375d3e0c 100644 --- a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts +++ b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts @@ -40,7 +40,7 @@ export class ContentsDownloader { extension: file.type, nameWithExtension: file.nameWithExtension, size: file.size, - processInfo: { elapsedTime: downloader.elapsedTime() }, + processInfo: { elapsedTime: downloader.elapsedTime(), progress: 0 }, }); }); @@ -57,18 +57,25 @@ export class ContentsDownloader { Logger.debug('Downloader force stop', this.readableDownloader); this.readableDownloader?.destroy(); this.readableDownloader?.emit('close'); + this.ipc.send('FILE_DOWNLOADED', { + name: file.name, + extension: file.type, + nameWithExtension: file.nameWithExtension, + size: file.size, + processInfo: { elapsedTime: downloader.elapsedTime() }, + }); + } else { + this.ipc.send('FILE_DOWNLOADING', { + name: file.name, + extension: file.type, + nameWithExtension: file.nameWithExtension, + size: file.size, + processInfo: { + elapsedTime: downloader.elapsedTime(), + progress: hydrationProgress, + }, + }); } - - this.ipc.send('FILE_DOWNLOADING', { - name: file.name, - extension: file.type, - nameWithExtension: file.nameWithExtension, - size: file.size, - processInfo: { - elapsedTime: downloader.elapsedTime(), - progress: hydrationProgress, - }, - }); }); downloader.on('error', (error: Error) => { @@ -84,6 +91,13 @@ export class ContentsDownloader { Logger.error('INSIDE FINISH======================='); // The file download being finished does not mean it has been hidratated // TODO: We might want to track this time instead of the whole completion time + this.ipc.send('FILE_DOWNLOADED', { + name: file.name, + extension: file.type, + nameWithExtension: file.nameWithExtension, + size: file.size, + processInfo: { elapsedTime: downloader.elapsedTime() }, + }); }); } From 2570a2ee41d4fc6a79f5835b7be6f357f6379644 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Wed, 8 Nov 2023 16:03:50 +0100 Subject: [PATCH 037/188] fixed tray status event listeners --- src/main/tray/handlers.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/tray/handlers.ts b/src/main/tray/handlers.ts index 7820cda33..40ee32769 100644 --- a/src/main/tray/handlers.ts +++ b/src/main/tray/handlers.ts @@ -28,6 +28,10 @@ ipcMainDrive.on('FILE_DOWNLOADING', () => { setTrayStatus('SYNCING'); }); +ipcMainDrive.on('FILE_DOWNLOADED', () => { + setTrayStatus('IDLE'); +}); + ipcMainDrive.on('FILE_MOVED', () => { setTrayStatus('IDLE'); }); @@ -41,7 +45,7 @@ ipcMainDrive.on('FILE_RENAMING', () => { }); ipcMainDrive.on('FILE_RENAMED', () => { - setTrayStatus('LOADING'); + setTrayStatus('IDLE'); }); ipcMainDrive.on('FILE_CLONNED', () => { From d0d2be64d479980e7b4e7687d001593ac0c6e8a3 Mon Sep 17 00:00:00 2001 From: larry-internxt Date: Thu, 9 Nov 2023 10:28:51 +0100 Subject: [PATCH 038/188] remove progress when file download starts --- .../modules/contents/application/ContentsDownloader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts index f375d3e0c..10c58b1bf 100644 --- a/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts +++ b/src/workers/sync-engine/modules/contents/application/ContentsDownloader.ts @@ -40,7 +40,7 @@ export class ContentsDownloader { extension: file.type, nameWithExtension: file.nameWithExtension, size: file.size, - processInfo: { elapsedTime: downloader.elapsedTime(), progress: 0 }, + processInfo: { elapsedTime: downloader.elapsedTime() }, }); }); From 32801aea3b611d497e3d9084a07b6cef37c15087 Mon Sep 17 00:00:00 2001 From: Joan Vicens Date: Thu, 9 Nov 2023 15:41:38 +0100 Subject: [PATCH 039/188] [PB-1151] fix: improve malicious file name detection (#413) * feat: unify traverser in one use case * fix: traverser instantacion --- src/test/main/thumbnails/resize-image.test.ts | 2 +- .../dependency-injection/common/traverser.ts | 8 +- .../dependency-injection/items/builder.ts | 11 +- .../infrastructure/HttpFileRepository.ts | 4 +- .../infrastructure/HttpFileRepository.test.ts | 6 +- .../infrastructure/HttpFolderRepository.ts | 4 +- .../HttpFolderRepository.test.ts | 4 +- .../application/ExistingItemsTraverser.ts | 167 ------------------ .../application/FileCreatorFromServerFile.ts | 18 ++ .../FolderCreatorFromServerFolder.ts | 17 ++ .../{AllStatusesTraverser.ts => Traverser.ts} | 148 +++++++++------- .../modules/items/application/TreeBuilder.ts | 2 +- .../modules/items/domain/Traverser.ts | 13 -- .../items/test/application/Traverser.test.ts | 95 ++++++++-- .../shared/application/EitherTransformer.ts | 2 +- .../sync-engine/modules/shared/domain/Path.ts | 21 +++ .../modules/shared/test/domain/Path.test.ts | 29 +++ src/workers/utils/name-verification.ts | 6 +- 18 files changed, 277 insertions(+), 280 deletions(-) delete mode 100644 src/workers/sync-engine/modules/items/application/ExistingItemsTraverser.ts create mode 100644 src/workers/sync-engine/modules/items/application/FileCreatorFromServerFile.ts create mode 100644 src/workers/sync-engine/modules/items/application/FolderCreatorFromServerFolder.ts rename src/workers/sync-engine/modules/items/application/{AllStatusesTraverser.ts => Traverser.ts} (54%) delete mode 100644 src/workers/sync-engine/modules/items/domain/Traverser.ts create mode 100644 src/workers/sync-engine/modules/shared/test/domain/Path.test.ts diff --git a/src/test/main/thumbnails/resize-image.test.ts b/src/test/main/thumbnails/resize-image.test.ts index b4348aa95..c69872b0b 100644 --- a/src/test/main/thumbnails/resize-image.test.ts +++ b/src/test/main/thumbnails/resize-image.test.ts @@ -5,7 +5,7 @@ import path from 'path'; import { execSync } from 'child_process'; import { ThumbnailProperties } from '../../../main/thumbnails/domain/ThumbnailProperties'; -describe('GM Resize Image', () => { +describe.skip('GM Resize Image', () => { it('gm is installed', () => { expect(() => { execSync('gm version', { stdio: 'ignore' }); diff --git a/src/workers/sync-engine/dependency-injection/common/traverser.ts b/src/workers/sync-engine/dependency-injection/common/traverser.ts index 3fa477f1c..06ce0d299 100644 --- a/src/workers/sync-engine/dependency-injection/common/traverser.ts +++ b/src/workers/sync-engine/dependency-injection/common/traverser.ts @@ -1,18 +1,18 @@ -import { ExistingItemsTraverser } from 'workers/sync-engine/modules/items/application/ExistingItemsTraverser'; +import { Traverser } from 'workers/sync-engine/modules/items/application/Traverser'; import crypt from '../../../utils/crypt'; import { DependencyInjectionUserProvider } from './user'; export class DependencyInjectionTraverserProvider { - private static traverser: ExistingItemsTraverser; + private static traverser: Traverser; - static get(): ExistingItemsTraverser { + static get(): Traverser { if (DependencyInjectionTraverserProvider.traverser) { return DependencyInjectionTraverserProvider.traverser; } const user = DependencyInjectionUserProvider.get(); - const traverser = new ExistingItemsTraverser(crypt, user.root_folder_id); + const traverser = Traverser.existingItems(crypt, user.root_folder_id); DependencyInjectionTraverserProvider.traverser = traverser; diff --git a/src/workers/sync-engine/dependency-injection/items/builder.ts b/src/workers/sync-engine/dependency-injection/items/builder.ts index 962b48896..ca08247bb 100644 --- a/src/workers/sync-engine/dependency-injection/items/builder.ts +++ b/src/workers/sync-engine/dependency-injection/items/builder.ts @@ -4,8 +4,7 @@ import { ipcRendererSyncEngine } from '../../ipcRendererSyncEngine'; import { RemoteItemsGenerator } from '../../modules/items/application/RemoteItemsGenerator'; import { getUser } from '../../../../main/auth/service'; import crypt from '../../../utils/crypt'; -import { ExistingItemsTraverser } from 'workers/sync-engine/modules/items/application/ExistingItemsTraverser'; -import { AllStatusesTraverser } from 'workers/sync-engine/modules/items/application/AllStatusesTraverser'; +import { Traverser } from 'workers/sync-engine/modules/items/application/Traverser'; export function buildItemsContainer(): ItemsContainer { const user = getUser(); @@ -16,21 +15,17 @@ export function buildItemsContainer(): ItemsContainer { const remoteItemsGenerator = new RemoteItemsGenerator(ipcRendererSyncEngine); - const existingItemsTraverser = new ExistingItemsTraverser( + const existingItemsTraverser = Traverser.existingItems( crypt, user.root_folder_id ); + const allStatusesTraverser = Traverser.allItems(crypt, user.root_folder_id); const treeBuilder = new TreeBuilder( remoteItemsGenerator, existingItemsTraverser ); - const allStatusesTraverser = new AllStatusesTraverser( - crypt, - user.root_folder_id - ); - const allStatusesTreeBuilder = new TreeBuilder( remoteItemsGenerator, allStatusesTraverser diff --git a/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts b/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts index 5a8d31865..e40ec9cf2 100644 --- a/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts +++ b/src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts @@ -6,7 +6,7 @@ import { ServerFolder } from '../../../../filesystems/domain/ServerFolder'; import { File, FileAttributes } from '../domain/File'; import { FileRepository } from '../domain/FileRepository'; import * as uuid from 'uuid'; -import { ExistingItemsTraverser } from '../../items/application/ExistingItemsTraverser'; +import { Traverser } from '../../items/application/Traverser'; import { AddFileDTO } from './dtos/AddFileDTO'; import { UpdateFileParentDirDTO } from './dtos/UpdateFileParentDirDTO'; import { UpdateFileNameDTO } from './dtos/UpdateFileNameDTO'; @@ -26,7 +26,7 @@ export class HttpFileRepository private readonly crypt: Crypt, private readonly httpClient: Axios, private readonly trashHttpClient: Axios, - private readonly traverser: ExistingItemsTraverser, + private readonly traverser: Traverser, private readonly bucket: string, private readonly ipc: SyncEngineIpc ) {} diff --git a/src/workers/sync-engine/modules/files/test/infrastructure/HttpFileRepository.test.ts b/src/workers/sync-engine/modules/files/test/infrastructure/HttpFileRepository.test.ts index 14b84be46..1a1be8894 100644 --- a/src/workers/sync-engine/modules/files/test/infrastructure/HttpFileRepository.test.ts +++ b/src/workers/sync-engine/modules/files/test/infrastructure/HttpFileRepository.test.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { ExistingItemsTraverser } from '../../../items/application/ExistingItemsTraverser'; +import { Traverser } from '../../../items/application/Traverser'; import { HttpFileRepository } from '../../infrastructure/HttpFileRepository'; import { IpcRendererSyncEngineMock } from '../../../shared/test/__mock__/IpcRendererSyncEngineMock'; import { FilePath } from '../../domain/FilePath'; @@ -20,12 +20,12 @@ const rootFolder = ServerFolderMother.fromPartial({ }); describe('Http File Repository', () => { - let traverser: ExistingItemsTraverser; + let traverser: Traverser; let ipc: IpcRendererSyncEngineMock; let SUT: HttpFileRepository; beforeEach(() => { - traverser = new ExistingItemsTraverser(fakeDecryptor, rootFolderId); + traverser = new Traverser(fakeDecryptor, rootFolderId); ipc = new IpcRendererSyncEngineMock(); diff --git a/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts b/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts index b7ad78207..968d2edc2 100644 --- a/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts +++ b/src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts @@ -7,7 +7,7 @@ import { ServerFile } from '../../../../filesystems/domain/ServerFile'; import { ServerFolder } from '../../../../filesystems/domain/ServerFolder'; import { SyncEngineIpc } from '../../../ipcRendererSyncEngine'; import { RemoteItemsGenerator } from '../../items/application/RemoteItemsGenerator'; -import { ExistingItemsTraverser } from '../../items/application/ExistingItemsTraverser'; +import { Traverser } from '../../items/application/Traverser'; import { PlatformPathConverter } from '../../shared/application/PlatformPathConverter'; import { Folder, FolderAttributes } from '../domain/Folder'; import { FolderPath } from '../domain/FolderPath'; @@ -24,7 +24,7 @@ export class HttpFolderRepository constructor( private readonly driveClient: Axios, private readonly trashClient: Axios, - private readonly traverser: ExistingItemsTraverser, + private readonly traverser: Traverser, private readonly ipc: SyncEngineIpc ) {} diff --git a/src/workers/sync-engine/modules/folders/test/infrastructure/HttpFolderRepository.test.ts b/src/workers/sync-engine/modules/folders/test/infrastructure/HttpFolderRepository.test.ts index d8cb73f0e..f8e24ed94 100644 --- a/src/workers/sync-engine/modules/folders/test/infrastructure/HttpFolderRepository.test.ts +++ b/src/workers/sync-engine/modules/folders/test/infrastructure/HttpFolderRepository.test.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import { ExistingItemsTraverser } from '../../../items/application/ExistingItemsTraverser'; +import { Traverser } from '../../../items/application/Traverser'; import { FolderPath } from '../../domain/FolderPath'; import { HttpFolderRepository } from '../../infrastructure/HttpFolderRepository'; import { fakeDecryptor } from '../../../shared/test/domain/FakeCrypt'; @@ -16,7 +16,7 @@ describe('Http Folder Repository', () => { describe('save', () => { beforeEach(() => { - const traverser = new ExistingItemsTraverser(fakeDecryptor, rootFolderId); + const traverser = new Traverser(fakeDecryptor, rootFolderId); ipc = new IpcRendererSyncEngineMock(); diff --git a/src/workers/sync-engine/modules/items/application/ExistingItemsTraverser.ts b/src/workers/sync-engine/modules/items/application/ExistingItemsTraverser.ts deleted file mode 100644 index ac5ff690a..000000000 --- a/src/workers/sync-engine/modules/items/application/ExistingItemsTraverser.ts +++ /dev/null @@ -1,167 +0,0 @@ -import Logger from 'electron-log'; -import { - ServerFile, - ServerFileStatus, -} from '../../../../filesystems/domain/ServerFile'; -import { - ServerFolder, - ServerFolderStatus, -} from '../../../../filesystems/domain/ServerFolder'; -import { fileNameIsValid } from '../../../../utils/name-verification'; -import { File } from '../../files/domain/File'; -import { FolderStatus } from '../../folders/domain/FolderStatus'; -import { Folder } from '../../folders/domain/Folder'; -import { ItemsIndexedByPath } from '../domain/ItemsIndexedByPath'; -import { EitherTransformer } from '../../shared/application/EitherTransformer'; -import { Traverser } from '../domain/Traverser'; - -function fileFromServerFile(relativePath: string, server: ServerFile): File { - return File.from({ - folderId: server.folderId, - contentsId: server.fileId, - modificationTime: server.modificationTime, - size: server.size, - createdAt: server.createdAt, - updatedAt: server.updatedAt, - path: relativePath, - status: server.status, - }); -} - -export class ExistingItemsTraverser implements Traverser { - private readonly collection: ItemsIndexedByPath = {}; - private static readonly ROOT_FOLDER_UUID = - '43711926-15c2-5ebf-8c24-5099fa9af3c3'; - - private rawTree: { - files: Array; - folders: Array; - } | null = null; - - constructor( - private readonly decrypt: { - decryptName: ( - name: string, - folderId: string, - encryptVersion: string - ) => string | null; - }, - private readonly baseFolderId: number - ) {} - - private traverse(currentId: number, currentName = '') { - if (!this.rawTree) return; - - const filesInThisFolder = this.rawTree.files.filter( - (file) => file.folderId === currentId - ); - - const foldersInThisFolder = this.rawTree.folders.filter((folder) => { - return folder.parentId === currentId; - }); - - filesInThisFolder - .map((file) => ({ - name: `${currentName}/${this.decrypt.decryptName( - file.name, - file.folderId.toString(), - file.encrypt_version - )}${file.type ? `.${file.type}` : ''}`, - file, - })) - .filter(({ name }) => { - const isValid = fileNameIsValid(name); - - if (!isValid) { - Logger.warn( - `REMOTE file with name ${name} will be ignored due an invalid name` - ); - return false; - } - - return true; - }) - .forEach(({ file, name }) => { - if (file.status !== ServerFileStatus.EXISTS) { - return; - } - EitherTransformer.handleWithEither(() => - fileFromServerFile(name, file) - ).fold( - (error) => { - Logger.warn( - `[Traverser] File with path ${name} could not be created: `, - error - ); - }, - (file) => { - this.collection[name] = file; - } - ); - }); - - foldersInThisFolder.forEach((folder: ServerFolder) => { - const plainName = - folder.plain_name || - this.decrypt.decryptName( - folder.name, - (folder.parentId as number).toString(), - '03-aes' - ) || - folder.name; - - const name = `${currentName}/${plainName}`; - - if (folder.status !== ServerFolderStatus.EXISTS) return; - - this.collection[name] = Folder.from({ - id: folder.id, - uuid: folder.uuid, - parentId: folder.parentId as number, - updatedAt: folder.updatedAt, - createdAt: folder.createdAt, - path: name, - status: folder.status, - }); - - this.traverse(folder.id, `${name}`); - }); - } - - public reset() { - Object.keys(this.collection).forEach( - (k: string) => delete this.collection[k] - ); - - this.collection['/'] = Folder.from({ - id: this.baseFolderId, - uuid: ExistingItemsTraverser.ROOT_FOLDER_UUID, - parentId: null, - updatedAt: new Date().toISOString(), - createdAt: new Date().toISOString(), - path: '/', - status: FolderStatus.Exists.value, - }); - } - - public run(rawTree: { - files: Array; - folders: Array; - }) { - this.rawTree = rawTree; - - this.traverse(this.baseFolderId); - - this.collection['/'] = Folder.from({ - id: this.baseFolderId, - uuid: ExistingItemsTraverser.ROOT_FOLDER_UUID, - parentId: null, - updatedAt: new Date().toISOString(), - createdAt: new Date().toISOString(), - path: '/', - status: FolderStatus.Exists.value, - }); - - return this.collection; - } -} diff --git a/src/workers/sync-engine/modules/items/application/FileCreatorFromServerFile.ts b/src/workers/sync-engine/modules/items/application/FileCreatorFromServerFile.ts new file mode 100644 index 000000000..8e301e17d --- /dev/null +++ b/src/workers/sync-engine/modules/items/application/FileCreatorFromServerFile.ts @@ -0,0 +1,18 @@ +import { ServerFile } from '../../../../filesystems/domain/ServerFile'; +import { File } from '../../files/domain/File'; + +export function createFileFromServerFile( + server: ServerFile, + relativePath: string +): File { + return File.from({ + folderId: server.folderId, + contentsId: server.fileId, + modificationTime: server.modificationTime, + size: server.size, + createdAt: server.createdAt, + updatedAt: server.updatedAt, + path: relativePath, + status: server.status, + }); +} diff --git a/src/workers/sync-engine/modules/items/application/FolderCreatorFromServerFolder.ts b/src/workers/sync-engine/modules/items/application/FolderCreatorFromServerFolder.ts new file mode 100644 index 000000000..a0afd4ed5 --- /dev/null +++ b/src/workers/sync-engine/modules/items/application/FolderCreatorFromServerFolder.ts @@ -0,0 +1,17 @@ +import { Folder } from '../../folders/domain/Folder'; +import { ServerFolder } from '../../../../filesystems/domain/ServerFolder'; + +export function createFolderFromServerFolder( + server: ServerFolder, + relativePath: string +): Folder { + return Folder.from({ + id: server.id, + uuid: server.uuid, + parentId: server.parentId as number, + updatedAt: server.updatedAt, + createdAt: server.createdAt, + path: relativePath, + status: server.status, + }); +} diff --git a/src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts b/src/workers/sync-engine/modules/items/application/Traverser.ts similarity index 54% rename from src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts rename to src/workers/sync-engine/modules/items/application/Traverser.ts index 869a21f2e..420c418ba 100644 --- a/src/workers/sync-engine/modules/items/application/AllStatusesTraverser.ts +++ b/src/workers/sync-engine/modules/items/application/Traverser.ts @@ -1,31 +1,20 @@ import Logger from 'electron-log'; -import { ServerFile } from '../../../../filesystems/domain/ServerFile'; +import { + ServerFile, + ServerFileStatus, +} from '../../../../filesystems/domain/ServerFile'; import { ServerFolder, ServerFolderStatus, } from '../../../../filesystems/domain/ServerFolder'; -import { fileNameIsValid } from '../../../../utils/name-verification'; -import { File } from '../../files/domain/File'; import { FolderStatus } from '../../folders/domain/FolderStatus'; import { Folder } from '../../folders/domain/Folder'; import { ItemsIndexedByPath } from '../domain/ItemsIndexedByPath'; import { EitherTransformer } from '../../shared/application/EitherTransformer'; -import { Traverser } from '../domain/Traverser'; - -function fileFromServerFile(relativePath: string, server: ServerFile): File { - return File.from({ - folderId: server.folderId, - contentsId: server.fileId, - modificationTime: server.modificationTime, - size: server.size, - createdAt: server.createdAt, - updatedAt: server.updatedAt, - path: relativePath, - status: server.status, - }); -} +import { createFileFromServerFile } from './FileCreatorFromServerFile'; +import { createFolderFromServerFolder } from './FolderCreatorFromServerFolder'; -export class AllStatusesTraverser implements Traverser { +export class Traverser { private readonly collection: ItemsIndexedByPath = {}; private static readonly ROOT_FOLDER_UUID = '43711926-15c2-5ebf-8c24-5099fa9af3c3'; @@ -43,9 +32,42 @@ export class AllStatusesTraverser implements Traverser { encryptVersion: string ) => string | null; }, - private readonly baseFolderId: number + private readonly baseFolderId: number, + private readonly fileStatusesToFilter: Array, + private readonly folderStatusesToFilter: Array ) {} + static existingItems( + decrypt: { + decryptName: ( + name: string, + folderId: string, + encryptVersion: string + ) => string | null; + }, + baseFolderId: number + ): Traverser { + return new Traverser( + decrypt, + baseFolderId, + [ServerFileStatus.EXISTS], + [ServerFolderStatus.EXISTS] + ); + } + + static allItems( + decrypt: { + decryptName: ( + name: string, + folderId: string, + encryptVersion: string + ) => string | null; + }, + baseFolderId: number + ): Traverser { + return new Traverser(decrypt, baseFolderId, [], []); + } + private traverse(currentId: number, currentName = '') { if (!this.rawTree) return; @@ -57,42 +79,34 @@ export class AllStatusesTraverser implements Traverser { return folder.parentId === currentId; }); - filesInThisFolder - .map((file) => ({ - name: `${currentName}/${this.decrypt.decryptName( - file.name, - file.folderId.toString(), - file.encrypt_version - )}${file.type ? `.${file.type}` : ''}`, - file, - })) - .filter(({ name }) => { - const isValid = fileNameIsValid(name); - - if (!isValid) { + filesInThisFolder.forEach((file) => { + if (!this.fileStatusesToFilter.includes(file.status)) { + return; + } + + const decryptedName = this.decrypt.decryptName( + file.name, + file.folderId.toString(), + file.encrypt_version + ); + const extensionToAdd = file.type ? `.${file.type}` : ''; + + const relativeFilePath = `${currentName}/${decryptedName}${extensionToAdd}`; + + EitherTransformer.handleWithEither(() => + createFileFromServerFile(file, relativeFilePath) + ).fold( + (error) => { Logger.warn( - `REMOTE file with name ${name} will be ignored due an invalid name` + `[Traverser] File with path ${relativeFilePath} could not be created: `, + error ); - return false; + }, + (file) => { + this.collection[relativeFilePath] = file; } - - return true; - }) - .forEach(({ file, name }) => { - EitherTransformer.handleWithEither(() => - fileFromServerFile(name, file) - ).fold( - (error) => { - Logger.warn( - `[Traverser] File with path ${name} could not be created: `, - error - ); - }, - (file) => { - this.collection[name] = file; - } - ); - }); + ); + }); foldersInThisFolder.forEach((folder: ServerFolder) => { const plainName = @@ -106,15 +120,23 @@ export class AllStatusesTraverser implements Traverser { const name = `${currentName}/${plainName}`; - this.collection[name] = Folder.from({ - id: folder.id, - uuid: folder.uuid, - parentId: folder.parentId as number, - updatedAt: folder.updatedAt, - createdAt: folder.createdAt, - path: name, - status: folder.status, - }); + if (!this.folderStatusesToFilter.includes(folder.status)) { + return; + } + + EitherTransformer.handleWithEither(() => + createFolderFromServerFolder(folder, name) + ).fold( + (error) => { + Logger.warn( + `[Traverser] Folder with path ${name} could not be created: `, + error + ); + }, + (folder) => { + this.collection[name] = folder; + } + ); if (folder.status === ServerFolderStatus.EXISTS) { // The folders and the files from trashed or deleted folders @@ -133,7 +155,7 @@ export class AllStatusesTraverser implements Traverser { this.collection['/'] = Folder.from({ id: this.baseFolderId, - uuid: AllStatusesTraverser.ROOT_FOLDER_UUID, + uuid: Traverser.ROOT_FOLDER_UUID, parentId: null, updatedAt: new Date().toISOString(), createdAt: new Date().toISOString(), @@ -152,7 +174,7 @@ export class AllStatusesTraverser implements Traverser { this.collection['/'] = Folder.from({ id: this.baseFolderId, - uuid: AllStatusesTraverser.ROOT_FOLDER_UUID, + uuid: Traverser.ROOT_FOLDER_UUID, parentId: null, updatedAt: new Date().toISOString(), createdAt: new Date().toISOString(), diff --git a/src/workers/sync-engine/modules/items/application/TreeBuilder.ts b/src/workers/sync-engine/modules/items/application/TreeBuilder.ts index 81ca01488..2bbbb160e 100644 --- a/src/workers/sync-engine/modules/items/application/TreeBuilder.ts +++ b/src/workers/sync-engine/modules/items/application/TreeBuilder.ts @@ -1,7 +1,7 @@ import { File } from '../../files/domain/File'; import { Folder } from '../../folders/domain/Folder'; import { RemoteItemsGenerator } from './RemoteItemsGenerator'; -import { Traverser } from '../domain/Traverser'; +import { Traverser } from './Traverser'; export class TreeBuilder { constructor( diff --git a/src/workers/sync-engine/modules/items/domain/Traverser.ts b/src/workers/sync-engine/modules/items/domain/Traverser.ts deleted file mode 100644 index 7abf68ebf..000000000 --- a/src/workers/sync-engine/modules/items/domain/Traverser.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ServerFile } from 'workers/filesystems/domain/ServerFile'; -import { ServerFolder } from 'workers/filesystems/domain/ServerFolder'; -import { File } from '../../files/domain/File'; -import { Folder } from '../../folders/domain/Folder'; - -export interface Traverser { - run: (rawTree: { - files: Array; - folders: Array; - }) => Record; - - reset: () => void; -} diff --git a/src/workers/sync-engine/modules/items/test/application/Traverser.test.ts b/src/workers/sync-engine/modules/items/test/application/Traverser.test.ts index 2c4b023b8..f07a3feb4 100644 --- a/src/workers/sync-engine/modules/items/test/application/Traverser.test.ts +++ b/src/workers/sync-engine/modules/items/test/application/Traverser.test.ts @@ -1,7 +1,13 @@ import { ContentsIdMother } from '../../../contents/test/domain/ContentsIdMother'; -import { ServerFile } from '../../../../../filesystems/domain/ServerFile'; -import { ServerFolder } from '../../../../../filesystems/domain/ServerFolder'; -import { ExistingItemsTraverser } from '../../application/ExistingItemsTraverser'; +import { + ServerFile, + ServerFileStatus, +} from '../../../../../filesystems/domain/ServerFile'; +import { + ServerFolder, + ServerFolderStatus, +} from '../../../../../filesystems/domain/ServerFolder'; +import { Traverser } from '../../application/Traverser'; const fakeDecrypt = { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -23,7 +29,12 @@ describe('Traverser', () => { ], folders: [], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); @@ -52,7 +63,12 @@ describe('Traverser', () => { } as ServerFolder, ], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); @@ -77,7 +93,12 @@ describe('Traverser', () => { } as ServerFolder, ], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); @@ -105,7 +126,12 @@ describe('Traverser', () => { } as ServerFolder, ], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); @@ -137,7 +163,12 @@ describe('Traverser', () => { } as ServerFolder, ], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); @@ -176,7 +207,12 @@ describe('Traverser', () => { ], folders: [], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); @@ -198,10 +234,49 @@ describe('Traverser', () => { {} as ServerFolder, ], }; - const SUT = new ExistingItemsTraverser(fakeDecrypt, baseFolderId); + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); const result = SUT.run(rawTree); expect(Object.keys(result)).toStrictEqual(['/folder A', '/']); }); + + it('filters the files and folders depending on the filters set', () => { + const baseFolderId = 6; + const rawTree = { + files: [ + { + name: 'file A', + fileId: ContentsIdMother.raw(), + folderId: baseFolderId, + size: 67, + status: 'TRASHED', + } as ServerFile, + ], + folders: [ + { + id: 22491, + parentId: baseFolderId, + plain_name: 'folder A', + status: 'TRASHED', + uuid: 'fc790269-92ac-5990-b9e0-a08d6552bf0b', + } as ServerFolder, + ], + }; + const SUT = new Traverser( + fakeDecrypt, + baseFolderId, + [ServerFileStatus.EXISTS, ServerFileStatus.TRASHED], + [ServerFolderStatus.EXISTS] + ); + + const result = SUT.run(rawTree); + + expect(Object.keys(result)).toStrictEqual(['/file A', '/']); + }); }); diff --git a/src/workers/sync-engine/modules/shared/application/EitherTransformer.ts b/src/workers/sync-engine/modules/shared/application/EitherTransformer.ts index 59d6399f0..7916242a4 100644 --- a/src/workers/sync-engine/modules/shared/application/EitherTransformer.ts +++ b/src/workers/sync-engine/modules/shared/application/EitherTransformer.ts @@ -9,7 +9,7 @@ export class EitherTransformer { if (error instanceof Error) { return left(error); } - return left(new Error('unkown error')); + return left(new Error('unknown error')); } } } diff --git a/src/workers/sync-engine/modules/shared/domain/Path.ts b/src/workers/sync-engine/modules/shared/domain/Path.ts index a8fa22067..8bfe4a56a 100644 --- a/src/workers/sync-engine/modules/shared/domain/Path.ts +++ b/src/workers/sync-engine/modules/shared/domain/Path.ts @@ -2,11 +2,32 @@ import path from 'path'; import { ValueObject } from '../../../../shared/domain/ValueObject'; import { InvalidArgumentError } from '../../../../shared/domain/InvalidArgumentError'; +const isWindowsRootDirectory = /[a-zA-Z]:[\\/]/; +const containsNullCharacter = /\0/g; + export abstract class Path extends ValueObject { + private static readonly maliciousPathValidations = [ + (name: string) => name.includes('../'), + (name: string) => name.startsWith('..'), + (name: string) => isWindowsRootDirectory.test(name), + (name: string) => containsNullCharacter.test(name), + ]; + constructor(value: string) { super(value); this.ensurePathIsPosix(value); + this.ensurePathIsNotMalicious(value); + } + + private ensurePathIsNotMalicious(value: string) { + const isMalicious = Path.maliciousPathValidations.some((validation) => + validation(value) + ); + + if (isMalicious) { + throw new InvalidArgumentError(`Path ${value} might be malicious.`); + } } private ensurePathIsPosix(value: string) { diff --git a/src/workers/sync-engine/modules/shared/test/domain/Path.test.ts b/src/workers/sync-engine/modules/shared/test/domain/Path.test.ts new file mode 100644 index 000000000..bd7a8c88a --- /dev/null +++ b/src/workers/sync-engine/modules/shared/test/domain/Path.test.ts @@ -0,0 +1,29 @@ +import { Path } from '../../domain/Path'; + +class PathTestClass extends Path { + constructor(value: string) { + super(value); + } +} + +describe('Path', () => { + describe('Path must always be posix', () => { + it('root folder path / is valid', () => { + const path = '/'; + + expect(() => new PathTestClass(path)).not.toThrowError(); + }); + + it('throws an error when the path is win32', () => { + const win32Path = '\\C:\\usersInternxt'; + + expect(() => new PathTestClass(win32Path)).toThrowError(); + }); + }); + it.each(['/folder/file.........something', '/f..a.txt', '/f...text'])( + 'path with dots after the first position are valid', + (path) => { + expect(() => new PathTestClass(path)).not.toThrowError(); + } + ); +}); diff --git a/src/workers/utils/name-verification.ts b/src/workers/utils/name-verification.ts index c2fcf6f32..8444ee497 100644 --- a/src/workers/utils/name-verification.ts +++ b/src/workers/utils/name-verification.ts @@ -12,11 +12,11 @@ const validations = [ (name: string) => containsNullCharacter.test(name), ]; -const sanitazeRelativePath = (relativePath: string) => +const sanitizeRelativePath = (relativePath: string) => relativePath.replaceAll(path.sep, '/'); export const fileNameIsValid = (fileName: string): boolean => { - const sanitazedPath = sanitazeRelativePath(fileName); + const sanitatedPath = sanitizeRelativePath(fileName); - return validations.every((validation) => !validation(sanitazedPath)); + return validations.every((validation) => !validation(sanitatedPath)); }; From e2ab2b76533fcdc8978a1be329ae14afe11d0c9b Mon Sep 17 00:00:00 2001 From: Joan Vicens Date: Tue, 14 Nov 2023 10:57:02 +0100 Subject: [PATCH 040/188] [_] chore: generate trees (#414) --- .erb/configs/webpack.paths.ts | 4 +- .github/workflows/test.yml | 9 +- package.json | 8 +- .../main/analytics/drive-handlers.ts | 0 src/{ => apps}/main/analytics/handlers.ts | 1 - .../main/analytics/rudderstack-client.ts | 4 +- src/{ => apps}/main/analytics/service.ts | 2 +- .../main/analytics/user-handlers.ts | 0 src/{ => apps}/main/app-info/app-info.ts | 2 +- src/apps/main/app-info/handlers.ts | 22 + src/{ => apps}/main/auth/handlers.ts | 4 + src/{ => apps}/main/auth/refresh-token.ts | 0 src/{ => apps}/main/auth/service.ts | 6 +- src/{ => apps}/main/auto-launch/handlers.ts | 0 .../main/auto-launch/linux-desktop-entry.ts | 2 +- src/{ => apps}/main/auto-launch/service.ts | 0 .../background-processes/process-issues.ts | 8 +- .../main/background-processes/sync-engine.ts | 2 +- .../main/bug-report/BugReportResult.ts | 0 src/{ => apps}/main/bug-report/handlers.ts | 0 src/{ => apps}/main/bug-report/service.ts | 5 +- src/{ => apps}/main/config.ts | 0 src/{ => apps}/main/config/handlers.ts | 0 src/{ => apps}/main/config/service.ts | 0 src/{ => apps}/main/database/adapters/base.ts | 0 .../collections/DriveFileCollection.ts | 0 .../collections/DriveFolderCollection.ts | 0 src/{ => apps}/main/database/data-source.ts | 0 .../main/database/entities/DriveFile.ts | 0 .../main/database/entities/DriveFolder.ts | 0 src/{ => apps}/main/device/handlers.ts | 0 src/{ => apps}/main/device/service.ts | 0 src/{ => apps}/main/event-bus.ts | 0 src/{ => apps}/main/fordwardToWindows.ts | 4 +- src/{ => apps}/main/ipcs/NoEvents.ts | 0 src/{ => apps}/main/ipcs/ipcMainSyncEngine.ts | 0 src/{ => apps}/main/ipcs/mainDrive.ts | 4 +- src/{ => apps}/main/ipcs/mainVirtualDrive.ts | 0 src/{ => apps}/main/logger.ts | 0 src/{ => apps}/main/main.ts | 4 +- src/{ => apps}/main/migration/handlers.ts | 0 src/{ => apps}/main/migration/service.ts | 0 .../main/platform/DesktopPlatform.ts | 0 src/{ => apps}/main/platform/handlers.ts | 0 src/{ => apps}/main/preload.d.ts | 92 +-- src/{ => apps}/main/preload.js | 6 +- src/{ => apps}/main/quit.ts | 0 src/{ => apps}/main/realtime.ts | 0 .../remote-sync/RemoteSyncManager.test.ts | 7 +- .../main/remote-sync/RemoteSyncManager.ts | 0 src/{ => apps}/main/remote-sync/handlers.ts | 0 src/{ => apps}/main/remote-sync/helpers.ts | 0 .../create-and-upload-thumbnail.ts | 0 .../application/extract-pdf-page.ts | 0 .../obtain-image-to-thumbnail-it.ts | 0 .../thumbnails/application/resize-image.ts | 0 .../thumbnails/domain/ThumbnableExtension.ts | 0 .../thumbnails/domain/ThumbnailProperties.ts | 0 .../thumbnails/domain/ThumbnailUploader.ts | 0 .../main/thumbnails/handlers/index.ts | 0 .../handlers/remote-file-pull-completed.ts | 0 .../EnvironmentAndStorageThumbnailUploader.ts | 0 .../ThumbnailUploaderFactory.ts | 0 .../main/token-scheduler/TokenScheduler.ts | 0 .../token-scheduler/token-scheduler.test.ts | 0 src/{ => apps}/main/tray/handlers.ts | 0 src/{ => apps}/main/tray/tray.ts | 4 +- src/{ => apps}/main/types.ts | 0 src/{ => apps}/main/usage/Usage.ts | 0 src/{ => apps}/main/usage/handlers.ts | 0 src/{ => apps}/main/usage/service.ts | 0 src/{ => apps}/main/usage/serviceBuilder.ts | 0 src/{ => apps}/main/util.ts | 0 .../main/virutal-root-folder/handlers.ts | 0 .../main/virutal-root-folder/service.ts | 0 src/{ => apps}/main/windows/auth.ts | 0 src/{ => apps}/main/windows/feedback.ts | 0 src/{ => apps}/main/windows/index.ts | 0 src/{ => apps}/main/windows/migration.ts | 0 src/{ => apps}/main/windows/onboarding.ts | 0 src/{ => apps}/main/windows/process-issues.ts | 0 src/{ => apps}/main/windows/settings.ts | 0 src/{ => apps}/main/windows/widget.ts | 0 src/{ => apps}/renderer/App.css | 0 src/{ => apps}/renderer/App.tsx | 0 .../renderer/actions/shared-actions.ts | 0 .../renderer/actions/sync-error-actions.ts | 0 src/apps/renderer/actions/types.ts | 8 + src/{ => apps}/renderer/assets/error.svg | 0 src/{ => apps}/renderer/assets/file.svg | 0 src/{ => apps}/renderer/assets/folder.svg | 0 .../InstrumentSans/InstrumentSans-Bold.woff2 | Bin .../InstrumentSans-Medium.woff2 | Bin .../InstrumentSans-Regular.woff2 | Bin .../InstrumentSans-SemiBold.woff2 | Bin .../InstrumentSans[wdth,wght].woff2 | Bin .../assets/fonts/InstrumentSans/OFL.txt | 0 .../assets/fonts/InstrumentSans/font.css | 0 .../renderer/assets/icons/audio.svg | 0 src/{ => apps}/renderer/assets/icons/code.svg | 0 src/{ => apps}/renderer/assets/icons/csv.svg | 0 .../renderer/assets/icons/default.svg | 0 .../renderer/assets/icons/excel.svg | 0 .../renderer/assets/icons/figma.svg | 0 .../renderer/assets/icons/folder.svg | 0 .../renderer/assets/icons/getIcon.tsx | 0 .../renderer/assets/icons/illustrator.svg | 0 .../renderer/assets/icons/image.svg | 0 .../renderer/assets/icons/indesign.svg | 0 src/{ => apps}/renderer/assets/icons/pdf.svg | 0 .../renderer/assets/icons/photoshop.svg | 0 .../renderer/assets/icons/powerpoint.svg | 0 src/{ => apps}/renderer/assets/icons/ppt.svg | 0 .../renderer/assets/icons/sketch.svg | 0 src/{ => apps}/renderer/assets/icons/txt.svg | 0 .../renderer/assets/icons/video.svg | 0 src/{ => apps}/renderer/assets/icons/word.svg | 0 src/{ => apps}/renderer/assets/icons/zip.svg | 0 .../assets/illustrations/syncedStack-dark.png | Bin .../illustrations/syncedStack-light.png | Bin src/{ => apps}/renderer/assets/index.d.ts | 0 .../assets/migration/upload-error.svg | 0 .../renderer/assets/migration/widget.svg | 0 .../assets/onboarding/context-menu.svg | 0 .../assets/onboarding/finder/linux.svg | 0 .../assets/onboarding/finder/macos.svg | 0 .../assets/onboarding/finder/windows.svg | 0 .../folder-with-overlay-icons/offline/en.svg | 0 .../folder-with-overlay-icons/offline/es.svg | 0 .../folder-with-overlay-icons/offline/fr.svg | 0 .../folder-with-overlay-icons/online/en.svg | 0 .../folder-with-overlay-icons/online/es.svg | 0 .../folder-with-overlay-icons/online/fr.svg | 0 .../renderer/assets/onboarding/logo.svg | 0 .../assets/onboarding/mac-finder-widget.png | Bin .../renderer/assets/onboarding/widget.png | Bin src/{ => apps}/renderer/assets/play.svg | 0 src/{ => apps}/renderer/assets/spinner.svg | 0 src/{ => apps}/renderer/assets/stop.svg | 0 src/{ => apps}/renderer/assets/success.svg | 0 src/{ => apps}/renderer/assets/warn.svg | 0 .../Backups/BackupsFoldersSelector.tsx | 4 +- .../components/Backups/FatalError.tsx | 7 +- src/{ => apps}/renderer/components/Button.tsx | 0 .../renderer/components/Checkbox.tsx | 0 .../renderer/components/FileWithOperation.tsx | 0 .../renderer/components/PasswordInput.tsx | 0 src/{ => apps}/renderer/components/Select.tsx | 0 .../renderer/components/TextArea.tsx | 0 .../renderer/components/TextInput.tsx | 0 .../renderer/components/WindowTopBar.tsx | 0 .../renderer/context/DeviceContext.tsx | 0 .../renderer/context/LocalContext.tsx | 0 .../renderer/hooks/BackupFatalErrors.tsx | 0 .../renderer/hooks/ClientPlatform.tsx | 0 .../renderer/hooks/FatalErrorActions.ts | 2 - .../renderer/hooks/GeneralIssues.tsx | 3 +- .../renderer/hooks/ProcessIssues.tsx | 3 +- .../renderer/hooks/VirtualDriveStatus.tsx | 2 +- src/{ => apps}/renderer/hooks/useBackups.tsx | 0 src/{ => apps}/renderer/hooks/useConfig.tsx | 0 src/{ => apps}/renderer/hooks/useLanguage.tsx | 0 .../renderer/hooks/useOnSyncRunning.tsx | 2 +- .../renderer/hooks/useOnSyncStopped.tsx | 0 .../renderer/hooks/useSyncInfoSubscriber.tsx | 2 +- .../renderer/hooks/useSyncStatus.tsx | 3 +- .../renderer/hooks/useSyncStopped.tsx | 3 +- src/{ => apps}/renderer/hooks/useUsage.tsx | 2 +- src/{ => apps}/renderer/index.ejs | 0 src/{ => apps}/renderer/index.tsx | 0 .../renderer/localize/i18n.service.ts | 12 +- .../renderer/localize/locales/en.json | 0 .../renderer/localize/locales/es.json | 0 .../renderer/localize/locales/fr.json | 0 .../messages/backups/backups-actions-map.ts | 2 +- .../messages/backups/backups-fatal-errors.ts | 2 +- .../renderer/messages/general-error.ts | 2 +- .../renderer/messages/process-error.ts | 2 +- .../renderer/messages/process-fatal-error.ts | 2 +- .../renderer/pages/Feedback/index.tsx | 6 +- .../renderer/pages/Login/ErrorBanner.tsx | 0 src/{ => apps}/renderer/pages/Login/TwoFA.tsx | 0 .../renderer/pages/Login/WarningBanner.tsx | 0 src/{ => apps}/renderer/pages/Login/index.tsx | 10 +- .../renderer/pages/Login/service.ts | 2 +- src/{ => apps}/renderer/pages/Login/types.ts | 0 .../renderer/pages/Migration/config.tsx | 4 +- .../renderer/pages/Migration/helpers.tsx | 2 +- .../renderer/pages/Migration/index.tsx | 7 +- .../slides/DeleteOldDriveFolderSlide.tsx | 9 +- .../Migration/slides/MigrationFailedSlide.tsx | 4 +- .../renderer/pages/Onboarding/config.tsx | 4 +- .../renderer/pages/Onboarding/helpers.tsx | 2 +- .../renderer/pages/Onboarding/index.tsx | 5 +- .../slides/AvailableOfflineSlide.tsx | 2 +- .../slides/AvailableOnlineSlide.tsx | 3 +- .../pages/Onboarding/slides/BackupsSlide.tsx | 2 +- .../Onboarding/slides/ContextMenuSlide.tsx | 3 +- .../slides/FilesOrganizationSlide.tsx | 2 +- .../slides/OnboardingCompletedSlide.tsx | 2 +- .../pages/Onboarding/slides/WelcomeSlide.tsx | 2 +- .../renderer/pages/ProcessIssues/List.tsx | 53 +- .../pages/ProcessIssues/ReportModal.tsx | 13 +- .../renderer/pages/ProcessIssues/index.tsx | 5 +- .../renderer/pages/Settings/Account/Usage.tsx | 0 .../pages/Settings/Account/UserInfo.tsx | 2 +- .../renderer/pages/Settings/Account/index.tsx | 6 +- .../pages/Settings/General/AppInfo.tsx | 2 +- .../pages/Settings/General/DeviceName.tsx | 4 +- .../pages/Settings/General/LanguagePicker.tsx | 2 +- .../Settings/General/StartAutomatically.tsx | 0 .../pages/Settings/General/ThemePicker.tsx | 2 +- .../renderer/pages/Settings/General/index.tsx | 0 .../renderer/pages/Settings/Header.tsx | 0 .../renderer/pages/Settings/index.tsx | 0 .../pages/Widget/AnimationWrapper.tsx | 0 .../renderer/pages/Widget/Header.tsx | 0 src/{ => apps}/renderer/pages/Widget/Item.tsx | 10 +- .../renderer/pages/Widget/NoInfoToShow.tsx | 0 .../renderer/pages/Widget/SyncAction.tsx | 15 +- .../renderer/pages/Widget/SyncErrorBanner.tsx | 9 +- .../renderer/pages/Widget/SyncFailed.tsx | 0 .../renderer/pages/Widget/SyncInfo.tsx | 10 +- .../pages/Widget/VirtualDriveError.tsx | 0 .../renderer/pages/Widget/index.tsx | 2 - src/{ => apps}/renderer/utils/errors.ts | 0 src/{ => apps}/renderer/utils/http-request.ts | 0 src/{ => apps}/renderer/utils/path.ts | 0 src/apps/renderer/utils/query.ts | 5 + src/{ => apps}/renderer/utils/usage.ts | 0 src/{ => apps}/shared/FileTypes/FileTypes.ts | 0 src/{ => apps}/shared/HttpClient/Clients.ts | 0 .../shared/HttpClient/HttpClient.ts | 0 .../HttpClient/background-process-clients.ts} | 3 +- .../HttpClient/http-client.test.skip.ts | 0 .../shared/HttpClient/main-process-client.ts | 0 .../HttpClient/responses/file-created.ts | 0 src/{ => apps}/shared/IPC/IPCs.ts | 0 src/{ => apps}/shared/IPC/events/drive.ts | 0 .../shared/IPC/events/sync-engine.ts | 6 +- .../shared/IPC/events/virtual-drive.ts | 0 src/{ => apps}/shared/ItemKind.ts | 0 src/{ => apps}/shared/Locale/DayJsLocales.ts | 0 src/{ => apps}/shared/Locale/Language.ts | 0 src/{ => apps}/shared/fs/PathTypeChecker .ts | 0 .../shared/fs/ReadStreamToBuffer.ts | 0 .../shared/fs/ensure-folder-exists.ts | 0 .../shared/fs/write-readable-to-file.ts | 0 src/{workers => apps/shared}/types.ts | 0 src/{ => apps}/shared/types/Nullable.ts | 0 src/{ => apps}/shared/types/Primitives.ts | 0 src/apps/shared/types/Process.ts | 1 + src/{ => apps}/shared/types/Stopwatch.ts | 0 src/{ => apps}/shared/types/Theme.ts | 0 .../shared/types/VirtualDriveStatus.ts | 0 .../sync-engine/BindingManager.ts | 39 +- .../callbacks-controllers/buildControllers.ts | 3 +- .../controllers/AddController.ts | 20 +- .../controllers/CallbackController.ts | 17 +- .../controllers/DeleteController.ts | 6 +- .../controllers/DownloadFileController.ts | 13 +- .../NotifyPlaceholderHydrationFinished.ts | 4 +- .../controllers/RenameOrMoveController.ts | 8 +- .../offline/OfflineRenameOrMoveController.ts | 6 +- .../helpers/rawPathIsFolder.ts | 0 .../executeControllerWithFallback.ts | 0 .../DependencyContainer.ts | 2 - .../DependencyContainerFactory.ts | 20 +- .../boundaryBridge/BoundaryBridgeContainer.ts | 5 + .../boundaryBridge/build.ts | 19 + .../dependency-injection/common/clients.ts | 4 +- .../dependency-injection/common/crypt.ts | 0 .../dependency-injection/common/eventBus.ts | 6 +- .../common/eventRepository.ts | 4 +- .../common/localRootFolderPath.ts | 2 +- .../dependency-injection/common/mnemonic.ts | 2 +- .../dependency-injection/common/sdk.ts | 35 + .../dependency-injection/common/traverser.ts | 4 +- .../dependency-injection/common/user.ts | 4 +- .../common/virtualDrive.ts | 0 .../contents/ContentsContainer.ts | 11 + .../dependency-injection/contents/builder.ts | 26 +- .../files/FilesContainer.ts | 25 + .../dependency-injection/files/builder.ts | 126 ++++ .../folders/FoldersContainer.ts | 33 + .../dependency-injection/folders/builder.ts | 145 ++++ .../items/ItemsContainer.ts | 2 +- .../dependency-injection/items/builder.ts | 22 +- .../shared/SharedContainer.ts | 7 + .../dependency-injection/shared/builder.ts | 12 +- src/{workers => apps}/sync-engine/index.ts | 7 +- .../sync-engine/ipcRendererSyncEngine.ts | 4 +- src/{workers => apps}/utils/date.ts | 0 .../utils/file-is-on-folder.ts | 0 src/{workers => apps}/utils/http-request.ts | 2 +- src/{workers => apps}/utils/icon.ts | 2 +- src/{workers => apps}/utils/is-online.ts | 0 .../utils/name-verification.ts | 0 src/{workers => apps}/utils/reporting.ts | 2 +- .../utils/test/file-is-on-folder.test.ts | 0 .../utils/test/name-verification.test.ts | 0 .../utils/test/sensible-files.json | 0 src/{workers => apps}/utils/types/Tuple.ts | 0 src/context/desktop/app/domain/AppIssue.ts | 10 + src/context/desktop/sync/domain/SyncStatus.ts | 1 + .../desktop/sync/domain/SyncStoppedPayload.ts | 8 + .../shared/domain/AggregateRoot.ts | 4 +- .../shared/domain/DomainEvent.ts | 0 .../shared/domain/DomainEventSubscriber.ts} | 2 +- .../shared/domain/Either.ts | 0 .../shared/domain/EnumValueObject.ts | 0 .../shared/domain/InvalidArgumentError.ts | 0 .../shared}/domain/ServerFile.ts | 0 .../shared}/domain/ServerFolder.ts | 0 .../shared/domain/ValueObject.ts | 6 +- .../shared/infrastructure}/crypt.ts | 0 .../application/FileCreationOrchestrator.ts | 0 .../application/ContentsDownloader.ts | 18 +- .../contents/application/ContentsUploader.ts | 2 +- .../NotifyMainProcessHydrationFinished.ts | 4 +- .../ReadLocalFileContentsToBuffer.ts | 0 .../application/RetryContentsUploader.ts | 0 .../application/temporalFolderProvider.ts | 0 .../contents/domain/ContentsId.ts | 4 +- .../domain/ContentsManagersFactory.ts | 0 .../contents/domain/ContentsSize.ts | 0 .../contents/domain/LocalFileContents.ts | 4 +- .../contents/domain/LocalFileProvider.ts | 0 .../contents/domain/LocalFileWriter.ts | 0 .../contents/domain/RemoteFileContents.ts | 5 +- .../contentHandlers/ContentFileDownloader.ts | 0 .../contentHandlers/ContentFileUploader.ts | 0 .../events/ContentsDownloadedDomainEvent.ts | 2 +- ...onmentRemoteFileContentsManagersFactory.ts | 0 .../infrastructure/FSLocalFileProvider.ts | 0 .../infrastructure/FSLocalFileWriter.ts | 4 +- .../EnvironmentContentFileDownloader.ts | 2 +- .../upload/EnvironmentContentFileUploader.ts | 2 +- .../CreateFilePlaceholderOnDeletionFailed.ts | 6 +- .../files/application/FileCreator.ts | 16 +- .../application/FileCreatorFromServerFile.ts | 18 + .../files/application/FileDeleter.ts | 25 +- .../application/FileFinderByContentsId.ts | 2 +- .../files/application/FilePathUpdater.ts | 23 +- .../FilePlaceholderCreatorFromContentsId.ts | 6 +- .../application/FilesPlaceholderUpdater.ts} | 57 +- .../application/FilesPlaceholdersCreator.ts | 14 + .../files/application/RepositoryPopulator.ts | 12 + .../files/application/RetrieveAllFiles.ts | 0 .../files/application/SameFileWasMoved.ts | 20 +- .../application/WebdavFileMimeTypeResolver.ts | 0 .../virtual-drive}/files/domain/File.ts | 71 +- .../virtual-drive}/files/domain/FilePath.ts | 0 .../files/domain/FileRepository.ts | 13 + .../virtual-drive}/files/domain/FileSize.ts | 0 .../virtual-drive}/files/domain/FileStatus.ts | 4 +- .../files/domain/MimeTypesMap.ts | 0 .../virtual-drive/files/domain/OfflineFile.ts | 110 +++ .../files/domain/OldFileRepository.ts} | 7 +- .../files/domain/PlaceholderId.ts} | 0 .../domain/errors/ActionNotPermittedError.ts | 0 .../errors/FileActionCannotModifyExtension.ts | 0 .../FileActionOnlyCanAffectOneLevelError.ts | 0 .../domain/errors/FileAlreadyExistsError.ts | 0 ...leCannotBeMovedToTheOriginalFolderError.ts | 0 .../FileNameShouldBeEqualToOriginalError.ts | 0 .../FileNameShouldDifferFromOriginalError.ts | 0 .../files/domain/errors/FileNotFoundError.ts | 0 .../domain/errors/UnknownFileActionError.ts | 0 .../domain/events/FileCreatedDomainEvent.ts | 2 +- .../domain/events/FileDeletedDomainEvent.ts | 2 +- .../domain/events/FileMovedDomainEvent.ts | 2 +- .../domain/events/FileRenamedDomainEvent.ts | 2 +- .../events/OptimisticFileDeletionFailed.ts | 2 +- .../domain/file-systems/LocalFileSystem.ts | 7 + .../domain/file-systems/RemoteFileSystem.ts | 12 + .../infrastructure/InMemoryFileRepository.ts | 63 ++ .../infrastructure/NodeWinLocalFileSystem.ts | 37 + .../infrastructure/SDKRemoteFileSystem.ts | 77 ++ .../files/infrastructure/dtos/AddFileDTO.ts | 0 .../infrastructure/dtos/UpdateFileNameDTO.ts | 0 .../dtos/UpdateFileParentDirDTO.ts | 0 .../AllParentFoldersStatusIsExists.ts | 0 .../application/FolderByPartialSearcher.ts | 0 .../folders/application/FolderCreator.ts | 16 +- .../FolderCreatorFromServerFolder.ts | 19 + .../folders/application/FolderDeleter.ts | 18 +- .../folders/application/FolderFinder.ts | 4 +- .../folders/application/FolderMover.ts | 11 +- .../folders/application/FolderPathUpdater.ts | 6 +- .../folders/application/FolderRenamer.ts | 7 +- .../application/FolderRepositoryInitiator.ts | 14 + .../application/FoldersPlaceholderCreator.ts | 14 + .../Offline/OfflineFolderCreator.ts | 2 +- .../application/Offline/OfflineFolderMover.ts | 7 +- .../Offline/OfflineFolderPathUpdater.ts | 2 +- .../Offline/OfflineFolderRenamer.ts | 0 .../folders/application/RetrieveAllFolders.ts | 0 .../SynchronizeOfflineModifications.ts | 12 +- ...nizeOfflineModificationsOnFolderCreated.ts | 6 +- .../application/UpdatePlaceholderFolder.ts | 51 +- .../virtual-drive}/folders/domain/Folder.ts | 38 +- .../folders/domain/FolderPath.ts | 0 .../folders}/domain/FolderPlaceholderId.ts | 0 .../folders/domain/FolderRepository.ts | 13 + .../folders/domain/FolderStatus.ts | 4 +- .../folders/domain/FolderUuid.ts | 4 +- .../folders/domain/ManagedFolderRepository.ts | 0 .../folders/domain/OfflineFolder.ts | 16 +- .../folders/domain/OfflineFolderRepository.ts | 9 + .../folders/domain/OldFolderRepository.ts} | 7 +- .../domain/errors/ActionNotPermittedError.ts | 0 .../domain/errors/FolderNotFoundError.ts | 0 .../domain/events/FolderCreatedDomainEvent.ts | 2 +- .../domain/events/FolderRenamedDomainEvent.ts | 2 +- .../domain/file-systems/LocalFileSystem.ts | 5 + .../domain/file-systems/RemoteFileSystem.ts | 12 + .../infrastructure/HttpRemoteFileSystem.ts | 104 +++ .../InMemoryFolderRepository.ts | 58 ++ .../InMemoryOfflineFolderRepository.ts | 47 ++ .../infrastructure/NodeWinLocalFileSystem.ts | 24 + .../infrastructure/dtos/CreateFolderDTO.ts | 5 + .../dtos/UpdateFolderNameDTO.ts | 0 .../application/FileCreatorFromServerFile.ts | 2 +- .../FolderCreatorFromServerFolder.ts | 2 +- .../items/application/ItemsSearcher.ts | 0 .../items/application/RemoteItemsGenerator.ts | 7 +- .../items/application/Traverser.ts | 154 ++++ .../items/application/TreeBuilder.ts | 9 +- .../virtual-drive/items/domain/FileNode.ts | 22 + .../virtual-drive/items/domain/FolderNode.ts | 33 + .../items/domain/ItemsIndexedByPath.ts | 0 .../virtual-drive/items/domain/NameDecrypt.ts | 7 + .../virtual-drive/items/domain/Node.ts | 4 + .../virtual-drive/items/domain/Tree.ts | 77 ++ .../infrastructure/CryptoJsNameDecrypt.ts | 12 + .../AbsolutePathToRelativeConverter.ts | 0 .../application/AllWebdavItemsSearcher.ts | 8 +- .../shared/application/EitherTransformer.ts | 2 +- .../shared/application/LocalFileIdProvider.ts | 0 .../application/PlatformPathConverter.ts | 0 .../RelativePathToAbsoluteConverter.ts | 0 .../WebdavUnknownItemTypeSearcher.ts | 8 +- .../shared/domain/BucketEntry.ts | 2 +- .../shared/domain/BucketEntryId.ts | 4 +- .../virtual-drive}/shared/domain/Crypt.ts | 4 +- .../shared/domain/DelayQueue.ts | 0 .../virtual-drive}/shared/domain/EventBus.ts | 2 +- .../shared/domain/EventRepository.ts | 2 +- .../shared/domain/MapObserver.ts | 0 .../virtual-drive}/shared/domain/Path.ts | 4 +- .../infrastructure/DomainEventSubscribers.ts | 18 + .../infrastructure/EnvironmentDownloader.ts | 2 +- .../shared/infrastructure/EventRecorder.ts | 2 +- .../infrastructure/InMemoryEventHistory.ts | 13 +- .../shared/infrastructure/NodeJsEventBus.ts | 2 +- .../thumbnails/domain/ThumbanailContentId.ts | 0 .../thumbnails/domain/Thumbnail.ts | 4 +- .../thumbnails/domain/ThumbnailDownloader.ts | 0 .../EnvironmentThumbnailDownloader.ts | 0 .../BytesInBinaryToInternacionalSystem.ts | 0 .../DecrementDriveUsageOnFileDeleted.ts | 6 +- .../FreeSpacePerEnvironmentCalculator.ts | 0 .../IncrementDriveUsageOnFileCreated.ts | 6 +- .../application/UsedSpaceCalculator.ts | 0 .../application/UserUsageDecrementer.ts | 0 .../application/UserUsageIncrementer.ts | 0 .../userUsage/domain/UserUsage.ts | 0 .../userUsage/domain/UserUsageRepository.ts | 0 .../CachedHttpUserUsageRepository.ts | 0 .../infrastrucutre/dtos/UserUsageLimitDTO.ts | 0 src/main/analytics/backup-handlers.ts | 84 --- src/main/app-info/AvaliableAppQuery.ts | 3 - src/main/app-info/handlers.ts | 14 - src/main/app-info/service.ts | 18 - src/main/background-processes/backups.ts | 298 -------- src/main/background-processes/sync.ts | 50 -- .../types/BackupFatalError.ts | 7 - .../actions/backsups-error-actions.ts | 32 - src/renderer/actions/types.ts | 9 - src/renderer/hooks/BackupStatus.tsx | 5 - .../Settings/Backups/BackupsFolderList.tsx | 253 ------- .../Settings/Backups/BackupsPreferences.tsx | 227 ------ src/renderer/pages/Settings/Backups/index.tsx | 41 - src/renderer/pages/Widget/BackupsBanner.tsx | 194 ----- .../pages/Widget/BackupsErrorBanner.tsx | 48 -- src/renderer/utils/backups-progress.ts | 11 - src/renderer/utils/query.ts | 18 - src/shared/types/Process.ts | 1 - src/workers/backups/backups.ts | 149 ---- src/workers/backups/index.ts | 249 ------- src/workers/backups/process.ts | 435 ----------- src/workers/backups/test/backups.test.ts | 191 ----- src/workers/filesystems/domain/FileSystem.ts | 92 --- src/workers/filesystems/domain/Transfer.ts | 4 - src/workers/filesystems/local-filesystem.ts | 362 --------- src/workers/filesystems/remote-filesystem.ts | 698 ------------------ .../test/__mocks__/FileSystemMock.ts | 109 --- .../boundaryBridge/BoundaryBridgeContainer.ts | 9 - .../boundaryBridge/build.ts | 66 -- .../contents/ContentsContainer.ts | 9 - .../files/FilesContainer.ts | 29 - .../dependency-injection/files/builder.ts | 123 --- .../folders/FoldersContainer.ts | 33 - .../dependency-injection/folders/builder.ts | 122 --- .../placeholders/PlaceholdersContainer.ts | 7 - .../placeholders/builder.ts | 21 - .../shared/SharedContainer.ts | 9 - .../application/SyncPlaceholders.ts | 44 -- .../application/TreePlaceholderCreator.ts | 43 -- .../test/__mocks__/LocalFileWriterMock.ts | 10 - .../test/__mocks__/LocationProviderMock.ts | 7 - .../application/FileByPartialSearcher.ts | 10 - .../modules/files/application/FileClearer.ts | 10 - .../modules/files/application/FileSearcher.ts | 16 - .../LocalRepositoryRepositoryRefresher.ts | 14 - .../files/domain/ManagedFileRepository.ts | 7 - .../infrastructure/HttpFileRepository.ts | 246 ------ .../test/__mocks__/FileRepositoryMock.ts | 61 -- .../test/application/FileCreator.test.ts | 123 --- .../test/application/FilePathUpdater.test.ts | 53 -- .../infrastructure/HttpFileRepository.test.ts | 87 --- .../folders/application/FolderClearer.ts | 10 - .../folders/application/FolderSearcher.ts | 14 - .../folders/domain/OfflineFolderRepository.ts | 8 - .../infrastructure/HttpFolderRepository.ts | 226 ------ .../InMemoryOfflineFolderRepository.ts | 41 - .../test/__mocks__/FolderRepositoryMock.ts | 65 -- .../HttpFolderRepository.test.ts | 50 -- .../modules/items/application/Traverser.ts | 187 ----- .../placeholders/domain/CommonPlaceholder.ts | 8 - .../placeholders/domain/PlaceholderCreator.ts | 7 - .../VirtualDrivePlaceholderCreator.ts | 46 -- .../test/__mock__/PlaceholderCreatorMock.ts | 16 - .../shared/domain/OfflineActionsQueue.ts | 10 - .../modules/shared/domain/WebdavItem.ts | 21 - .../infrastructure/DomainEventSubscribers.ts | 18 - {src/test => tests}/LanguagePicker.e2e.ts | 0 .../__mocks__/ContentFileDownloaderMock.ts | 2 +- .../__mocks__/ContentFileUploaderMock.ts | 4 +- .../contents/__mocks__/LocalFileWriterMock.ts | 10 + .../__mocks__/LocationProviderMock.ts | 7 + .../contents}/__mocks__/ReadableHelloWorld.ts | 0 .../RemoteFileContentsManagersFactoryMock.ts | 10 +- .../DownloadStrategyFunctionMock.ts | 0 .../environment/UploadStrategyFunctionMock.ts | 0 .../application/ContentsDownloader._test.ts | 18 +- .../contents}/domain/ContentsIdMother.ts | 3 +- .../contents}/domain/ContentsSizeMother.ts | 2 +- .../contents}/domain/FileContentsMother.ts | 2 +- .../EnvironmentContentFileDownloader.test.ts | 4 +- .../EnvironmentContentFileUploader.test.ts | 2 +- .../files/__mocks__/FileRepositoryMock.ts | 30 + .../files/__mocks__/LocalFileSystemMock.ts | 15 + .../files/__mocks__/RemoteFileSystemMock.ts | 29 + .../files/application/FileCreator.test.ts | 141 ++++ .../files}/application/FileDeleter.test.ts | 42 +- .../files/application/FilePathUpdater.test.ts | 120 +++ .../virtual-drive/files}/domain/FileMother.ts | 7 +- .../files}/domain/FilePath.test.ts | 2 +- .../files}/domain/FilePathMother.ts | 4 +- .../files}/domain/FileSize.test.ts | 2 +- .../files}/infrastructure/ServerFileMother.ts | 4 +- .../folders}/__mocks__/FolderFinderMock.ts | 0 .../__mocks__/FolderLocalFileSystemMock.ts | 10 + .../__mocks__/FolderRemoteFileSystemMock.ts | 26 + .../folders/__mocks__/FolderRepositoryMock.ts | 33 + .../application/FolderCreator.test.ts | 61 +- .../application/FolderDeleter.test.ts | 44 +- .../folders}/application/FolderMover.test.ts | 23 +- .../SynchronizeOfflineModifications.test.ts | 82 +- .../folders}/domain/FolderMother.ts | 11 +- .../folders}/domain/FolderPath.test.ts | 2 +- .../folders}/domain/OfflineFolderMother.ts | 6 +- .../items}/application/Traverser.test.ts | 117 +-- .../items/infrastructure/FakeNameDecrypt.ts | 13 + .../items}/persistance/ServerFolderMother.ts | 4 +- .../shared}/__mock__/EventBusMock.ts | 6 +- .../shared/__mock__/EventRepositoryMock.ts | 14 + .../__mock__/IpcRendererSyncEngineMock.ts | 7 +- .../AbsolutePathToRelativeConverter.test.ts | 2 +- .../application/PlatformPathConverter.test.ts | 2 +- .../virtual-drive/shared}/domain/FakeCrypt.ts | 2 +- .../virtual-drive/shared}/domain/Path.test.ts | 2 +- ...BytesInBinaryToInternacionalSystem.test.ts | 2 +- .../fixtures/AccessResponse.json | 0 {src/test => tests}/fixtures/errors.ts | 19 +- {src/test => tests}/issues.e2e.ts | 23 +- .../main/thumbnails/fixtures/1000x1000.jpg | Bin .../main/thumbnails/fixtures/result.png | Bin .../main/thumbnails/fixtures/source.pdf | Bin .../test => tests}/main/thumbnails/helpers.ts | 0 .../main/thumbnails/resize-image.test.ts | 8 +- {src/test => tests}/onboarding.e2e.ts | 0 {src/test => tests}/playwright.config.ts | 0 {src/test => tests}/selectors.ts | 0 {src/test => tests}/unauthorized.e2e.ts | 0 {src/test => tests}/utils.ts | 0 tsconfig.json | 7 +- 599 files changed, 2800 insertions(+), 6452 deletions(-) rename src/{ => apps}/main/analytics/drive-handlers.ts (100%) rename src/{ => apps}/main/analytics/handlers.ts (65%) rename src/{ => apps}/main/analytics/rudderstack-client.ts (73%) rename src/{ => apps}/main/analytics/service.ts (99%) rename src/{ => apps}/main/analytics/user-handlers.ts (100%) rename src/{ => apps}/main/app-info/app-info.ts (76%) create mode 100644 src/apps/main/app-info/handlers.ts rename src/{ => apps}/main/auth/handlers.ts (96%) rename src/{ => apps}/main/auth/refresh-token.ts (100%) rename src/{ => apps}/main/auth/service.ts (96%) rename src/{ => apps}/main/auto-launch/handlers.ts (100%) rename src/{ => apps}/main/auto-launch/linux-desktop-entry.ts (94%) rename src/{ => apps}/main/auto-launch/service.ts (100%) rename src/{ => apps}/main/background-processes/process-issues.ts (98%) rename src/{ => apps}/main/background-processes/sync-engine.ts (98%) rename src/{ => apps}/main/bug-report/BugReportResult.ts (100%) rename src/{ => apps}/main/bug-report/handlers.ts (100%) rename src/{ => apps}/main/bug-report/service.ts (96%) rename src/{ => apps}/main/config.ts (100%) rename src/{ => apps}/main/config/handlers.ts (100%) rename src/{ => apps}/main/config/service.ts (100%) rename src/{ => apps}/main/database/adapters/base.ts (100%) rename src/{ => apps}/main/database/collections/DriveFileCollection.ts (100%) rename src/{ => apps}/main/database/collections/DriveFolderCollection.ts (100%) rename src/{ => apps}/main/database/data-source.ts (100%) rename src/{ => apps}/main/database/entities/DriveFile.ts (100%) rename src/{ => apps}/main/database/entities/DriveFolder.ts (100%) rename src/{ => apps}/main/device/handlers.ts (100%) rename src/{ => apps}/main/device/service.ts (100%) rename src/{ => apps}/main/event-bus.ts (100%) rename src/{ => apps}/main/fordwardToWindows.ts (98%) rename src/{ => apps}/main/ipcs/NoEvents.ts (100%) rename src/{ => apps}/main/ipcs/ipcMainSyncEngine.ts (100%) rename src/{ => apps}/main/ipcs/mainDrive.ts (100%) rename src/{ => apps}/main/ipcs/mainVirtualDrive.ts (100%) rename src/{ => apps}/main/logger.ts (100%) rename src/{ => apps}/main/main.ts (97%) rename src/{ => apps}/main/migration/handlers.ts (100%) rename src/{ => apps}/main/migration/service.ts (100%) rename src/{ => apps}/main/platform/DesktopPlatform.ts (100%) rename src/{ => apps}/main/platform/handlers.ts (100%) rename src/{ => apps}/main/preload.d.ts (71%) rename src/{ => apps}/main/preload.js (99%) rename src/{ => apps}/main/quit.ts (100%) rename src/{ => apps}/main/realtime.ts (100%) rename src/{ => apps}/main/remote-sync/RemoteSyncManager.test.ts (97%) rename src/{ => apps}/main/remote-sync/RemoteSyncManager.ts (100%) rename src/{ => apps}/main/remote-sync/handlers.ts (100%) rename src/{ => apps}/main/remote-sync/helpers.ts (100%) rename src/{ => apps}/main/thumbnails/application/create-and-upload-thumbnail.ts (100%) rename src/{ => apps}/main/thumbnails/application/extract-pdf-page.ts (100%) rename src/{ => apps}/main/thumbnails/application/obtain-image-to-thumbnail-it.ts (100%) rename src/{ => apps}/main/thumbnails/application/resize-image.ts (100%) rename src/{ => apps}/main/thumbnails/domain/ThumbnableExtension.ts (100%) rename src/{ => apps}/main/thumbnails/domain/ThumbnailProperties.ts (100%) rename src/{ => apps}/main/thumbnails/domain/ThumbnailUploader.ts (100%) rename src/{ => apps}/main/thumbnails/handlers/index.ts (100%) rename src/{ => apps}/main/thumbnails/handlers/remote-file-pull-completed.ts (100%) rename src/{ => apps}/main/thumbnails/infrastructure/EnvironmentAndStorageThumbnailUploader.ts (100%) rename src/{ => apps}/main/thumbnails/infrastructure/ThumbnailUploaderFactory.ts (100%) rename src/{ => apps}/main/token-scheduler/TokenScheduler.ts (100%) rename src/{ => apps}/main/token-scheduler/token-scheduler.test.ts (100%) rename src/{ => apps}/main/tray/handlers.ts (100%) rename src/{ => apps}/main/tray/tray.ts (97%) rename src/{ => apps}/main/types.ts (100%) rename src/{ => apps}/main/usage/Usage.ts (100%) rename src/{ => apps}/main/usage/handlers.ts (100%) rename src/{ => apps}/main/usage/service.ts (100%) rename src/{ => apps}/main/usage/serviceBuilder.ts (100%) rename src/{ => apps}/main/util.ts (100%) rename src/{ => apps}/main/virutal-root-folder/handlers.ts (100%) rename src/{ => apps}/main/virutal-root-folder/service.ts (100%) rename src/{ => apps}/main/windows/auth.ts (100%) rename src/{ => apps}/main/windows/feedback.ts (100%) rename src/{ => apps}/main/windows/index.ts (100%) rename src/{ => apps}/main/windows/migration.ts (100%) rename src/{ => apps}/main/windows/onboarding.ts (100%) rename src/{ => apps}/main/windows/process-issues.ts (100%) rename src/{ => apps}/main/windows/settings.ts (100%) rename src/{ => apps}/main/windows/widget.ts (100%) rename src/{ => apps}/renderer/App.css (100%) rename src/{ => apps}/renderer/App.tsx (100%) rename src/{ => apps}/renderer/actions/shared-actions.ts (100%) rename src/{ => apps}/renderer/actions/sync-error-actions.ts (100%) create mode 100644 src/apps/renderer/actions/types.ts rename src/{ => apps}/renderer/assets/error.svg (100%) rename src/{ => apps}/renderer/assets/file.svg (100%) rename src/{ => apps}/renderer/assets/folder.svg (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/InstrumentSans-Bold.woff2 (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/InstrumentSans-Medium.woff2 (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/InstrumentSans-Regular.woff2 (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/InstrumentSans-SemiBold.woff2 (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/InstrumentSans[wdth,wght].woff2 (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/OFL.txt (100%) rename src/{ => apps}/renderer/assets/fonts/InstrumentSans/font.css (100%) rename src/{ => apps}/renderer/assets/icons/audio.svg (100%) rename src/{ => apps}/renderer/assets/icons/code.svg (100%) rename src/{ => apps}/renderer/assets/icons/csv.svg (100%) rename src/{ => apps}/renderer/assets/icons/default.svg (100%) rename src/{ => apps}/renderer/assets/icons/excel.svg (100%) rename src/{ => apps}/renderer/assets/icons/figma.svg (100%) rename src/{ => apps}/renderer/assets/icons/folder.svg (100%) rename src/{ => apps}/renderer/assets/icons/getIcon.tsx (100%) rename src/{ => apps}/renderer/assets/icons/illustrator.svg (100%) rename src/{ => apps}/renderer/assets/icons/image.svg (100%) rename src/{ => apps}/renderer/assets/icons/indesign.svg (100%) rename src/{ => apps}/renderer/assets/icons/pdf.svg (100%) rename src/{ => apps}/renderer/assets/icons/photoshop.svg (100%) rename src/{ => apps}/renderer/assets/icons/powerpoint.svg (100%) rename src/{ => apps}/renderer/assets/icons/ppt.svg (100%) rename src/{ => apps}/renderer/assets/icons/sketch.svg (100%) rename src/{ => apps}/renderer/assets/icons/txt.svg (100%) rename src/{ => apps}/renderer/assets/icons/video.svg (100%) rename src/{ => apps}/renderer/assets/icons/word.svg (100%) rename src/{ => apps}/renderer/assets/icons/zip.svg (100%) rename src/{ => apps}/renderer/assets/illustrations/syncedStack-dark.png (100%) rename src/{ => apps}/renderer/assets/illustrations/syncedStack-light.png (100%) rename src/{ => apps}/renderer/assets/index.d.ts (100%) rename src/{ => apps}/renderer/assets/migration/upload-error.svg (100%) rename src/{ => apps}/renderer/assets/migration/widget.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/context-menu.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/finder/linux.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/finder/macos.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/finder/windows.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/folder-with-overlay-icons/offline/en.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/folder-with-overlay-icons/offline/es.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/folder-with-overlay-icons/offline/fr.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/folder-with-overlay-icons/online/en.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/folder-with-overlay-icons/online/es.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/folder-with-overlay-icons/online/fr.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/logo.svg (100%) rename src/{ => apps}/renderer/assets/onboarding/mac-finder-widget.png (100%) rename src/{ => apps}/renderer/assets/onboarding/widget.png (100%) rename src/{ => apps}/renderer/assets/play.svg (100%) rename src/{ => apps}/renderer/assets/spinner.svg (100%) rename src/{ => apps}/renderer/assets/stop.svg (100%) rename src/{ => apps}/renderer/assets/success.svg (100%) rename src/{ => apps}/renderer/assets/warn.svg (100%) rename src/{ => apps}/renderer/components/Backups/BackupsFoldersSelector.tsx (97%) rename src/{ => apps}/renderer/components/Backups/FatalError.tsx (85%) rename src/{ => apps}/renderer/components/Button.tsx (100%) rename src/{ => apps}/renderer/components/Checkbox.tsx (100%) rename src/{ => apps}/renderer/components/FileWithOperation.tsx (100%) rename src/{ => apps}/renderer/components/PasswordInput.tsx (100%) rename src/{ => apps}/renderer/components/Select.tsx (100%) rename src/{ => apps}/renderer/components/TextArea.tsx (100%) rename src/{ => apps}/renderer/components/TextInput.tsx (100%) rename src/{ => apps}/renderer/components/WindowTopBar.tsx (100%) rename src/{ => apps}/renderer/context/DeviceContext.tsx (100%) rename src/{ => apps}/renderer/context/LocalContext.tsx (100%) rename src/{ => apps}/renderer/hooks/BackupFatalErrors.tsx (100%) rename src/{ => apps}/renderer/hooks/ClientPlatform.tsx (100%) rename src/{ => apps}/renderer/hooks/FatalErrorActions.ts (84%) rename src/{ => apps}/renderer/hooks/GeneralIssues.tsx (88%) rename src/{ => apps}/renderer/hooks/ProcessIssues.tsx (88%) rename src/{ => apps}/renderer/hooks/VirtualDriveStatus.tsx (92%) rename src/{ => apps}/renderer/hooks/useBackups.tsx (100%) rename src/{ => apps}/renderer/hooks/useConfig.tsx (100%) rename src/{ => apps}/renderer/hooks/useLanguage.tsx (100%) rename src/{ => apps}/renderer/hooks/useOnSyncRunning.tsx (77%) rename src/{ => apps}/renderer/hooks/useOnSyncStopped.tsx (100%) rename src/{ => apps}/renderer/hooks/useSyncInfoSubscriber.tsx (96%) rename src/{ => apps}/renderer/hooks/useSyncStatus.tsx (93%) rename src/{ => apps}/renderer/hooks/useSyncStopped.tsx (82%) rename src/{ => apps}/renderer/hooks/useUsage.tsx (94%) rename src/{ => apps}/renderer/index.ejs (100%) rename src/{ => apps}/renderer/index.tsx (100%) rename src/{ => apps}/renderer/localize/i18n.service.ts (84%) rename src/{ => apps}/renderer/localize/locales/en.json (100%) rename src/{ => apps}/renderer/localize/locales/es.json (100%) rename src/{ => apps}/renderer/localize/locales/fr.json (100%) rename src/{ => apps}/renderer/messages/backups/backups-actions-map.ts (86%) rename src/{ => apps}/renderer/messages/backups/backups-fatal-errors.ts (88%) rename src/{ => apps}/renderer/messages/general-error.ts (88%) rename src/{ => apps}/renderer/messages/process-error.ts (95%) rename src/{ => apps}/renderer/messages/process-fatal-error.ts (92%) rename src/{ => apps}/renderer/pages/Feedback/index.tsx (95%) rename src/{ => apps}/renderer/pages/Login/ErrorBanner.tsx (100%) rename src/{ => apps}/renderer/pages/Login/TwoFA.tsx (100%) rename src/{ => apps}/renderer/pages/Login/WarningBanner.tsx (100%) rename src/{ => apps}/renderer/pages/Login/index.tsx (96%) rename src/{ => apps}/renderer/pages/Login/service.ts (97%) rename src/{ => apps}/renderer/pages/Login/types.ts (100%) rename src/{ => apps}/renderer/pages/Migration/config.tsx (99%) rename src/{ => apps}/renderer/pages/Migration/helpers.tsx (99%) rename src/{ => apps}/renderer/pages/Migration/index.tsx (96%) rename src/{ => apps}/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx (84%) rename src/{ => apps}/renderer/pages/Migration/slides/MigrationFailedSlide.tsx (92%) rename src/{ => apps}/renderer/pages/Onboarding/config.tsx (98%) rename src/{ => apps}/renderer/pages/Onboarding/helpers.tsx (99%) rename src/{ => apps}/renderer/pages/Onboarding/index.tsx (95%) rename src/{ => apps}/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx (91%) rename src/{ => apps}/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx (91%) rename src/{ => apps}/renderer/pages/Onboarding/slides/BackupsSlide.tsx (92%) rename src/{ => apps}/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx (93%) rename src/{ => apps}/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx (92%) rename src/{ => apps}/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx (97%) rename src/{ => apps}/renderer/pages/Onboarding/slides/WelcomeSlide.tsx (91%) rename src/{ => apps}/renderer/pages/ProcessIssues/List.tsx (83%) rename src/{ => apps}/renderer/pages/ProcessIssues/ReportModal.tsx (94%) rename src/{ => apps}/renderer/pages/ProcessIssues/index.tsx (96%) rename src/{ => apps}/renderer/pages/Settings/Account/Usage.tsx (100%) rename src/{ => apps}/renderer/pages/Settings/Account/UserInfo.tsx (96%) rename src/{ => apps}/renderer/pages/Settings/Account/index.tsx (90%) rename src/{ => apps}/renderer/pages/Settings/General/AppInfo.tsx (96%) rename src/{ => apps}/renderer/pages/Settings/General/DeviceName.tsx (97%) rename src/{ => apps}/renderer/pages/Settings/General/LanguagePicker.tsx (96%) rename src/{ => apps}/renderer/pages/Settings/General/StartAutomatically.tsx (100%) rename src/{ => apps}/renderer/pages/Settings/General/ThemePicker.tsx (96%) rename src/{ => apps}/renderer/pages/Settings/General/index.tsx (100%) rename src/{ => apps}/renderer/pages/Settings/Header.tsx (100%) rename src/{ => apps}/renderer/pages/Settings/index.tsx (100%) rename src/{ => apps}/renderer/pages/Widget/AnimationWrapper.tsx (100%) rename src/{ => apps}/renderer/pages/Widget/Header.tsx (100%) rename src/{ => apps}/renderer/pages/Widget/Item.tsx (98%) rename src/{ => apps}/renderer/pages/Widget/NoInfoToShow.tsx (100%) rename src/{ => apps}/renderer/pages/Widget/SyncAction.tsx (91%) rename src/{ => apps}/renderer/pages/Widget/SyncErrorBanner.tsx (90%) rename src/{ => apps}/renderer/pages/Widget/SyncFailed.tsx (100%) rename src/{ => apps}/renderer/pages/Widget/SyncInfo.tsx (80%) rename src/{ => apps}/renderer/pages/Widget/VirtualDriveError.tsx (100%) rename src/{ => apps}/renderer/pages/Widget/index.tsx (90%) rename src/{ => apps}/renderer/utils/errors.ts (100%) rename src/{ => apps}/renderer/utils/http-request.ts (100%) rename src/{ => apps}/renderer/utils/path.ts (100%) create mode 100644 src/apps/renderer/utils/query.ts rename src/{ => apps}/renderer/utils/usage.ts (100%) rename src/{ => apps}/shared/FileTypes/FileTypes.ts (100%) rename src/{ => apps}/shared/HttpClient/Clients.ts (100%) rename src/{ => apps}/shared/HttpClient/HttpClient.ts (100%) rename src/{shared/HttpClient/backgroud-process-clients.ts => apps/shared/HttpClient/background-process-clients.ts} (88%) rename src/{ => apps}/shared/HttpClient/http-client.test.skip.ts (100%) rename src/{ => apps}/shared/HttpClient/main-process-client.ts (100%) rename src/{ => apps}/shared/HttpClient/responses/file-created.ts (100%) rename src/{ => apps}/shared/IPC/IPCs.ts (100%) rename src/{ => apps}/shared/IPC/events/drive.ts (100%) rename src/{ => apps}/shared/IPC/events/sync-engine.ts (94%) rename src/{ => apps}/shared/IPC/events/virtual-drive.ts (100%) rename src/{ => apps}/shared/ItemKind.ts (100%) rename src/{ => apps}/shared/Locale/DayJsLocales.ts (100%) rename src/{ => apps}/shared/Locale/Language.ts (100%) rename src/{ => apps}/shared/fs/PathTypeChecker .ts (100%) rename src/{ => apps}/shared/fs/ReadStreamToBuffer.ts (100%) rename src/{ => apps}/shared/fs/ensure-folder-exists.ts (100%) rename src/{ => apps}/shared/fs/write-readable-to-file.ts (100%) rename src/{workers => apps/shared}/types.ts (100%) rename src/{ => apps}/shared/types/Nullable.ts (100%) rename src/{ => apps}/shared/types/Primitives.ts (100%) create mode 100644 src/apps/shared/types/Process.ts rename src/{ => apps}/shared/types/Stopwatch.ts (100%) rename src/{ => apps}/shared/types/Theme.ts (100%) rename src/{ => apps}/shared/types/VirtualDriveStatus.ts (100%) rename src/{workers => apps}/sync-engine/BindingManager.ts (86%) rename src/{workers => apps}/sync-engine/callbacks-controllers/buildControllers.ts (96%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/AddController.ts (77%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/CallbackController.ts (63%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/DeleteController.ts (85%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/DownloadFileController.ts (70%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/NotifyPlaceholderHydrationFinished.ts (66%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/RenameOrMoveController.ts (77%) rename src/{workers => apps}/sync-engine/callbacks-controllers/controllers/offline/OfflineRenameOrMoveController.ts (79%) rename src/{workers => apps}/sync-engine/callbacks-controllers/helpers/rawPathIsFolder.ts (100%) rename src/{workers => apps}/sync-engine/callbacks-controllers/middlewares/executeControllerWithFallback.ts (100%) rename src/{workers => apps}/sync-engine/dependency-injection/DependencyContainer.ts (86%) rename src/{workers => apps}/sync-engine/dependency-injection/DependencyContainerFactory.ts (80%) create mode 100644 src/apps/sync-engine/dependency-injection/boundaryBridge/BoundaryBridgeContainer.ts create mode 100644 src/apps/sync-engine/dependency-injection/boundaryBridge/build.ts rename src/{workers => apps}/sync-engine/dependency-injection/common/clients.ts (71%) create mode 100644 src/apps/sync-engine/dependency-injection/common/crypt.ts rename src/{workers => apps}/sync-engine/dependency-injection/common/eventBus.ts (65%) rename src/{workers => apps}/sync-engine/dependency-injection/common/eventRepository.ts (63%) rename src/{workers => apps}/sync-engine/dependency-injection/common/localRootFolderPath.ts (88%) rename src/{workers => apps}/sync-engine/dependency-injection/common/mnemonic.ts (89%) create mode 100644 src/apps/sync-engine/dependency-injection/common/sdk.ts rename src/{workers => apps}/sync-engine/dependency-injection/common/traverser.ts (76%) rename src/{workers => apps}/sync-engine/dependency-injection/common/user.ts (79%) rename src/{workers => apps}/sync-engine/dependency-injection/common/virtualDrive.ts (100%) create mode 100644 src/apps/sync-engine/dependency-injection/contents/ContentsContainer.ts rename src/{workers => apps}/sync-engine/dependency-injection/contents/builder.ts (58%) create mode 100644 src/apps/sync-engine/dependency-injection/files/FilesContainer.ts create mode 100644 src/apps/sync-engine/dependency-injection/files/builder.ts create mode 100644 src/apps/sync-engine/dependency-injection/folders/FoldersContainer.ts create mode 100644 src/apps/sync-engine/dependency-injection/folders/builder.ts rename src/{workers => apps}/sync-engine/dependency-injection/items/ItemsContainer.ts (55%) rename src/{workers => apps}/sync-engine/dependency-injection/items/builder.ts (54%) create mode 100644 src/apps/sync-engine/dependency-injection/shared/SharedContainer.ts rename src/{workers => apps}/sync-engine/dependency-injection/shared/builder.ts (56%) rename src/{workers => apps}/sync-engine/index.ts (93%) rename src/{workers => apps}/sync-engine/ipcRendererSyncEngine.ts (58%) rename src/{workers => apps}/utils/date.ts (100%) rename src/{workers => apps}/utils/file-is-on-folder.ts (100%) rename src/{workers => apps}/utils/http-request.ts (91%) rename src/{workers => apps}/utils/icon.ts (70%) rename src/{workers => apps}/utils/is-online.ts (100%) rename src/{workers => apps}/utils/name-verification.ts (100%) rename src/{workers => apps}/utils/reporting.ts (91%) rename src/{workers => apps}/utils/test/file-is-on-folder.test.ts (100%) rename src/{workers => apps}/utils/test/name-verification.test.ts (100%) rename src/{workers => apps}/utils/test/sensible-files.json (100%) rename src/{workers => apps}/utils/types/Tuple.ts (100%) create mode 100644 src/context/desktop/app/domain/AppIssue.ts create mode 100644 src/context/desktop/sync/domain/SyncStatus.ts create mode 100644 src/context/desktop/sync/domain/SyncStoppedPayload.ts rename src/{workers/sync-engine/modules => context}/shared/domain/AggregateRoot.ts (76%) rename src/{workers/sync-engine/modules => context}/shared/domain/DomainEvent.ts (100%) rename src/{workers/sync-engine/modules/shared/domain/WebdavDomainEventSubscriber.ts => context/shared/domain/DomainEventSubscriber.ts} (67%) rename src/{workers/sync-engine/modules => context}/shared/domain/Either.ts (100%) rename src/{workers => context}/shared/domain/EnumValueObject.ts (100%) rename src/{workers => context}/shared/domain/InvalidArgumentError.ts (100%) rename src/{workers/filesystems => context/shared}/domain/ServerFile.ts (100%) rename src/{workers/filesystems => context/shared}/domain/ServerFolder.ts (100%) rename src/{workers => context}/shared/domain/ValueObject.ts (82%) rename src/{workers/utils => context/shared/infrastructure}/crypt.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/boundaryBridge/application/FileCreationOrchestrator.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/application/ContentsDownloader.ts (93%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/application/ContentsUploader.ts (97%) rename src/{workers/sync-engine/modules/placeholders => context/virtual-drive/contents}/application/NotifyMainProcessHydrationFinished.ts (83%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/application/ReadLocalFileContentsToBuffer.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/application/RetryContentsUploader.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/application/temporalFolderProvider.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/ContentsId.ts (68%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/ContentsManagersFactory.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/ContentsSize.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/LocalFileContents.ts (94%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/LocalFileProvider.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/LocalFileWriter.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/RemoteFileContents.ts (84%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/contentHandlers/ContentFileDownloader.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/contentHandlers/ContentFileUploader.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/domain/events/ContentsDownloadedDomainEvent.ts (94%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/infrastructure/EnvironmentRemoteFileContentsManagersFactory.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/infrastructure/FSLocalFileProvider.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/infrastructure/FSLocalFileWriter.ts (80%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/infrastructure/download/EnvironmentContentFileDownloader.ts (96%) rename src/{workers/sync-engine/modules => context/virtual-drive}/contents/infrastructure/upload/EnvironmentContentFileUploader.ts (96%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/CreateFilePlaceholderOnDeletionFailed.ts (70%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/FileCreator.ts (74%) create mode 100644 src/context/virtual-drive/files/application/FileCreatorFromServerFile.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/FileDeleter.ts (72%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/FileFinderByContentsId.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/FilePathUpdater.ts (79%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/FilePlaceholderCreatorFromContentsId.ts (64%) rename src/{workers/sync-engine/modules/boundaryBridge/application/UpdatePlaceholderFile.ts => context/virtual-drive/files/application/FilesPlaceholderUpdater.ts} (58%) create mode 100644 src/context/virtual-drive/files/application/FilesPlaceholdersCreator.ts create mode 100644 src/context/virtual-drive/files/application/RepositoryPopulator.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/RetrieveAllFiles.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/SameFileWasMoved.ts (68%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/application/WebdavFileMimeTypeResolver.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/File.ts (76%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/FilePath.ts (100%) create mode 100644 src/context/virtual-drive/files/domain/FileRepository.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/FileSize.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/FileStatus.ts (89%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/MimeTypesMap.ts (100%) create mode 100644 src/context/virtual-drive/files/domain/OfflineFile.ts rename src/{workers/sync-engine/modules/files/domain/FileRepository.ts => context/virtual-drive/files/domain/OldFileRepository.ts} (68%) rename src/{workers/sync-engine/modules/placeholders/domain/FilePlaceholderId.ts => context/virtual-drive/files/domain/PlaceholderId.ts} (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/ActionNotPermittedError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileActionCannotModifyExtension.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileActionOnlyCanAffectOneLevelError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileAlreadyExistsError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileCannotBeMovedToTheOriginalFolderError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileNameShouldBeEqualToOriginalError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileNameShouldDifferFromOriginalError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/FileNotFoundError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/errors/UnknownFileActionError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/events/FileCreatedDomainEvent.ts (91%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/events/FileDeletedDomainEvent.ts (89%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/events/FileMovedDomainEvent.ts (87%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/events/FileRenamedDomainEvent.ts (83%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/domain/events/OptimisticFileDeletionFailed.ts (82%) create mode 100644 src/context/virtual-drive/files/domain/file-systems/LocalFileSystem.ts create mode 100644 src/context/virtual-drive/files/domain/file-systems/RemoteFileSystem.ts create mode 100644 src/context/virtual-drive/files/infrastructure/InMemoryFileRepository.ts create mode 100644 src/context/virtual-drive/files/infrastructure/NodeWinLocalFileSystem.ts create mode 100644 src/context/virtual-drive/files/infrastructure/SDKRemoteFileSystem.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/files/infrastructure/dtos/AddFileDTO.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/infrastructure/dtos/UpdateFileNameDTO.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/files/infrastructure/dtos/UpdateFileParentDirDTO.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/AllParentFoldersStatusIsExists.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderByPartialSearcher.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderCreator.ts (67%) create mode 100644 src/context/virtual-drive/folders/application/FolderCreatorFromServerFolder.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderDeleter.ts (71%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderFinder.ts (81%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderMover.ts (74%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderPathUpdater.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/FolderRenamer.ts (68%) create mode 100644 src/context/virtual-drive/folders/application/FolderRepositoryInitiator.ts create mode 100644 src/context/virtual-drive/folders/application/FoldersPlaceholderCreator.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/Offline/OfflineFolderCreator.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/Offline/OfflineFolderMover.ts (88%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/Offline/OfflineFolderPathUpdater.ts (95%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/Offline/OfflineFolderRenamer.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/RetrieveAllFolders.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/SynchronizeOfflineModifications.ts (81%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/application/SynchronizeOfflineModificationsOnFolderCreated.ts (71%) rename src/{workers/sync-engine/modules/boundaryBridge => context/virtual-drive/folders}/application/UpdatePlaceholderFolder.ts (71%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/Folder.ts (85%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/FolderPath.ts (100%) rename src/{workers/sync-engine/modules/placeholders => context/virtual-drive/folders}/domain/FolderPlaceholderId.ts (100%) create mode 100644 src/context/virtual-drive/folders/domain/FolderRepository.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/FolderStatus.ts (88%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/FolderUuid.ts (72%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/ManagedFolderRepository.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/OfflineFolder.ts (85%) create mode 100644 src/context/virtual-drive/folders/domain/OfflineFolderRepository.ts rename src/{workers/sync-engine/modules/folders/domain/FolderRepository.ts => context/virtual-drive/folders/domain/OldFolderRepository.ts} (69%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/errors/ActionNotPermittedError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/errors/FolderNotFoundError.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/events/FolderCreatedDomainEvent.ts (83%) rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/domain/events/FolderRenamedDomainEvent.ts (90%) create mode 100644 src/context/virtual-drive/folders/domain/file-systems/LocalFileSystem.ts create mode 100644 src/context/virtual-drive/folders/domain/file-systems/RemoteFileSystem.ts create mode 100644 src/context/virtual-drive/folders/infrastructure/HttpRemoteFileSystem.ts create mode 100644 src/context/virtual-drive/folders/infrastructure/InMemoryFolderRepository.ts create mode 100644 src/context/virtual-drive/folders/infrastructure/InMemoryOfflineFolderRepository.ts create mode 100644 src/context/virtual-drive/folders/infrastructure/NodeWinLocalFileSystem.ts create mode 100644 src/context/virtual-drive/folders/infrastructure/dtos/CreateFolderDTO.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/folders/infrastructure/dtos/UpdateFolderNameDTO.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/items/application/FileCreatorFromServerFile.ts (85%) rename src/{workers/sync-engine/modules => context/virtual-drive}/items/application/FolderCreatorFromServerFolder.ts (83%) rename src/{workers/sync-engine/modules => context/virtual-drive}/items/application/ItemsSearcher.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/items/application/RemoteItemsGenerator.ts (90%) create mode 100644 src/context/virtual-drive/items/application/Traverser.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/items/application/TreeBuilder.ts (58%) create mode 100644 src/context/virtual-drive/items/domain/FileNode.ts create mode 100644 src/context/virtual-drive/items/domain/FolderNode.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/items/domain/ItemsIndexedByPath.ts (100%) create mode 100644 src/context/virtual-drive/items/domain/NameDecrypt.ts create mode 100644 src/context/virtual-drive/items/domain/Node.ts create mode 100644 src/context/virtual-drive/items/domain/Tree.ts create mode 100644 src/context/virtual-drive/items/infrastructure/CryptoJsNameDecrypt.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/AbsolutePathToRelativeConverter.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/AllWebdavItemsSearcher.ts (70%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/EitherTransformer.ts (82%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/LocalFileIdProvider.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/PlatformPathConverter.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/RelativePathToAbsoluteConverter.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/application/WebdavUnknownItemTypeSearcher.ts (62%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/BucketEntry.ts (85%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/BucketEntryId.ts (69%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/Crypt.ts (86%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/DelayQueue.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/EventBus.ts (77%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/EventRepository.ts (68%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/MapObserver.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/domain/Path.ts (90%) create mode 100644 src/context/virtual-drive/shared/infrastructure/DomainEventSubscribers.ts rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/infrastructure/EnvironmentDownloader.ts (96%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/infrastructure/EventRecorder.ts (90%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/infrastructure/InMemoryEventHistory.ts (66%) rename src/{workers/sync-engine/modules => context/virtual-drive}/shared/infrastructure/NodeJsEventBus.ts (90%) rename src/{workers/sync-engine/modules => context/virtual-drive}/thumbnails/domain/ThumbanailContentId.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/thumbnails/domain/Thumbnail.ts (87%) rename src/{workers/sync-engine/modules => context/virtual-drive}/thumbnails/domain/ThumbnailDownloader.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/thumbnails/infrastructrue/EnvironmentThumbnailDownloader.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/BytesInBinaryToInternacionalSystem.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/DecrementDriveUsageOnFileDeleted.ts (71%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/FreeSpacePerEnvironmentCalculator.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/IncrementDriveUsageOnFileCreated.ts (67%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/UsedSpaceCalculator.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/UserUsageDecrementer.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/application/UserUsageIncrementer.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/domain/UserUsage.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/domain/UserUsageRepository.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/infrastrucutre/CachedHttpUserUsageRepository.ts (100%) rename src/{workers/sync-engine/modules => context/virtual-drive}/userUsage/infrastrucutre/dtos/UserUsageLimitDTO.ts (100%) delete mode 100644 src/main/analytics/backup-handlers.ts delete mode 100644 src/main/app-info/AvaliableAppQuery.ts delete mode 100644 src/main/app-info/handlers.ts delete mode 100644 src/main/app-info/service.ts delete mode 100644 src/main/background-processes/backups.ts delete mode 100644 src/main/background-processes/sync.ts delete mode 100644 src/main/background-processes/types/BackupFatalError.ts delete mode 100644 src/renderer/actions/backsups-error-actions.ts delete mode 100644 src/renderer/actions/types.ts delete mode 100644 src/renderer/hooks/BackupStatus.tsx delete mode 100644 src/renderer/pages/Settings/Backups/BackupsFolderList.tsx delete mode 100644 src/renderer/pages/Settings/Backups/BackupsPreferences.tsx delete mode 100644 src/renderer/pages/Settings/Backups/index.tsx delete mode 100644 src/renderer/pages/Widget/BackupsBanner.tsx delete mode 100644 src/renderer/pages/Widget/BackupsErrorBanner.tsx delete mode 100644 src/renderer/utils/backups-progress.ts delete mode 100644 src/renderer/utils/query.ts delete mode 100644 src/shared/types/Process.ts delete mode 100644 src/workers/backups/backups.ts delete mode 100644 src/workers/backups/index.ts delete mode 100644 src/workers/backups/process.ts delete mode 100644 src/workers/backups/test/backups.test.ts delete mode 100644 src/workers/filesystems/domain/FileSystem.ts delete mode 100644 src/workers/filesystems/domain/Transfer.ts delete mode 100644 src/workers/filesystems/local-filesystem.ts delete mode 100644 src/workers/filesystems/remote-filesystem.ts delete mode 100644 src/workers/filesystems/test/__mocks__/FileSystemMock.ts delete mode 100644 src/workers/sync-engine/dependency-injection/boundaryBridge/BoundaryBridgeContainer.ts delete mode 100644 src/workers/sync-engine/dependency-injection/boundaryBridge/build.ts delete mode 100644 src/workers/sync-engine/dependency-injection/contents/ContentsContainer.ts delete mode 100644 src/workers/sync-engine/dependency-injection/files/FilesContainer.ts delete mode 100644 src/workers/sync-engine/dependency-injection/files/builder.ts delete mode 100644 src/workers/sync-engine/dependency-injection/folders/FoldersContainer.ts delete mode 100644 src/workers/sync-engine/dependency-injection/folders/builder.ts delete mode 100644 src/workers/sync-engine/dependency-injection/placeholders/PlaceholdersContainer.ts delete mode 100644 src/workers/sync-engine/dependency-injection/placeholders/builder.ts delete mode 100644 src/workers/sync-engine/dependency-injection/shared/SharedContainer.ts delete mode 100644 src/workers/sync-engine/modules/boundaryBridge/application/SyncPlaceholders.ts delete mode 100644 src/workers/sync-engine/modules/boundaryBridge/application/TreePlaceholderCreator.ts delete mode 100644 src/workers/sync-engine/modules/contents/test/__mocks__/LocalFileWriterMock.ts delete mode 100644 src/workers/sync-engine/modules/contents/test/__mocks__/LocationProviderMock.ts delete mode 100644 src/workers/sync-engine/modules/files/application/FileByPartialSearcher.ts delete mode 100644 src/workers/sync-engine/modules/files/application/FileClearer.ts delete mode 100644 src/workers/sync-engine/modules/files/application/FileSearcher.ts delete mode 100644 src/workers/sync-engine/modules/files/application/LocalRepositoryRepositoryRefresher.ts delete mode 100644 src/workers/sync-engine/modules/files/domain/ManagedFileRepository.ts delete mode 100644 src/workers/sync-engine/modules/files/infrastructure/HttpFileRepository.ts delete mode 100644 src/workers/sync-engine/modules/files/test/__mocks__/FileRepositoryMock.ts delete mode 100644 src/workers/sync-engine/modules/files/test/application/FileCreator.test.ts delete mode 100644 src/workers/sync-engine/modules/files/test/application/FilePathUpdater.test.ts delete mode 100644 src/workers/sync-engine/modules/files/test/infrastructure/HttpFileRepository.test.ts delete mode 100644 src/workers/sync-engine/modules/folders/application/FolderClearer.ts delete mode 100644 src/workers/sync-engine/modules/folders/application/FolderSearcher.ts delete mode 100644 src/workers/sync-engine/modules/folders/domain/OfflineFolderRepository.ts delete mode 100644 src/workers/sync-engine/modules/folders/infrastructure/HttpFolderRepository.ts delete mode 100644 src/workers/sync-engine/modules/folders/infrastructure/InMemoryOfflineFolderRepository.ts delete mode 100644 src/workers/sync-engine/modules/folders/test/__mocks__/FolderRepositoryMock.ts delete mode 100644 src/workers/sync-engine/modules/folders/test/infrastructure/HttpFolderRepository.test.ts delete mode 100644 src/workers/sync-engine/modules/items/application/Traverser.ts delete mode 100644 src/workers/sync-engine/modules/placeholders/domain/CommonPlaceholder.ts delete mode 100644 src/workers/sync-engine/modules/placeholders/domain/PlaceholderCreator.ts delete mode 100644 src/workers/sync-engine/modules/placeholders/infrastructure/VirtualDrivePlaceholderCreator.ts delete mode 100644 src/workers/sync-engine/modules/placeholders/test/__mock__/PlaceholderCreatorMock.ts delete mode 100644 src/workers/sync-engine/modules/shared/domain/OfflineActionsQueue.ts delete mode 100644 src/workers/sync-engine/modules/shared/domain/WebdavItem.ts delete mode 100644 src/workers/sync-engine/modules/shared/infrastructure/DomainEventSubscribers.ts rename {src/test => tests}/LanguagePicker.e2e.ts (100%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/__mocks__/ContentFileDownloaderMock.ts (85%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/__mocks__/ContentFileUploaderMock.ts (76%) create mode 100644 tests/context/virtual-drive/contents/__mocks__/LocalFileWriterMock.ts create mode 100644 tests/context/virtual-drive/contents/__mocks__/LocationProviderMock.ts rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/__mocks__/ReadableHelloWorld.ts (100%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/__mocks__/RemoteFileContentsManagersFactoryMock.ts (53%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/__mocks__/environment/DownloadStrategyFunctionMock.ts (100%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/__mocks__/environment/UploadStrategyFunctionMock.ts (100%) rename src/workers/sync-engine/modules/contents/test/application/ContentsDownloader.test.ts => tests/context/virtual-drive/contents/application/ContentsDownloader._test.ts (73%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/domain/ContentsIdMother.ts (76%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/domain/ContentsSizeMother.ts (71%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/domain/FileContentsMother.ts (74%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/infrastructure/download/EnvironmentContentFileDownloader.test.ts (91%) rename {src/workers/sync-engine/modules/contents/test => tests/context/virtual-drive/contents}/infrastructure/upload/EnvironmentContentFileUploader.test.ts (96%) create mode 100644 tests/context/virtual-drive/files/__mocks__/FileRepositoryMock.ts create mode 100644 tests/context/virtual-drive/files/__mocks__/LocalFileSystemMock.ts create mode 100644 tests/context/virtual-drive/files/__mocks__/RemoteFileSystemMock.ts create mode 100644 tests/context/virtual-drive/files/application/FileCreator.test.ts rename {src/workers/sync-engine/modules/files/test => tests/context/virtual-drive/files}/application/FileDeleter.test.ts (53%) create mode 100644 tests/context/virtual-drive/files/application/FilePathUpdater.test.ts rename {src/workers/sync-engine/modules/files/test => tests/context/virtual-drive/files}/domain/FileMother.ts (82%) rename {src/workers/sync-engine/modules/files/test => tests/context/virtual-drive/files}/domain/FilePath.test.ts (91%) rename {src/workers/sync-engine/modules/files/test => tests/context/virtual-drive/files}/domain/FilePathMother.ts (74%) rename {src/workers/sync-engine/modules/files/test => tests/context/virtual-drive/files}/domain/FileSize.test.ts (88%) rename {src/workers/sync-engine/modules/files/test => tests/context/virtual-drive/files}/infrastructure/ServerFileMother.ts (81%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/__mocks__/FolderFinderMock.ts (100%) create mode 100644 tests/context/virtual-drive/folders/__mocks__/FolderLocalFileSystemMock.ts create mode 100644 tests/context/virtual-drive/folders/__mocks__/FolderRemoteFileSystemMock.ts create mode 100644 tests/context/virtual-drive/folders/__mocks__/FolderRepositoryMock.ts rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/application/FolderCreator.test.ts (50%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/application/FolderDeleter.test.ts (58%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/application/FolderMover.test.ts (61%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/application/SynchronizeOfflineModifications.test.ts (53%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/domain/FolderMother.ts (85%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/domain/FolderPath.test.ts (75%) rename {src/workers/sync-engine/modules/folders/test => tests/context/virtual-drive/folders}/domain/OfflineFolderMother.ts (71%) rename {src/workers/sync-engine/modules/items/test => tests/context/virtual-drive/items}/application/Traverser.test.ts (69%) create mode 100644 tests/context/virtual-drive/items/infrastructure/FakeNameDecrypt.ts rename {src/workers/sync-engine/modules/items/test => tests/context/virtual-drive/items}/persistance/ServerFolderMother.ts (84%) rename {src/workers/sync-engine/modules/shared/test => tests/context/virtual-drive/shared}/__mock__/EventBusMock.ts (73%) create mode 100644 tests/context/virtual-drive/shared/__mock__/EventRepositoryMock.ts rename {src/workers/sync-engine/modules/shared/test => tests/context/virtual-drive/shared}/__mock__/IpcRendererSyncEngineMock.ts (83%) rename {src/workers/sync-engine/modules/shared/test => tests/context/virtual-drive/shared}/application/AbsolutePathToRelativeConverter.test.ts (71%) rename {src/workers/sync-engine/modules/shared/test => tests/context/virtual-drive/shared}/application/PlatformPathConverter.test.ts (80%) rename {src/workers/sync-engine/modules/shared/test => tests/context/virtual-drive/shared}/domain/FakeCrypt.ts (80%) rename {src/workers/sync-engine/modules/shared/test => tests/context/virtual-drive/shared}/domain/Path.test.ts (89%) rename {src/workers/sync-engine/modules/userUsage/test => tests/context/virtual-drive/user-usage}/application/BytesInBinaryToInternacionalSystem.test.ts (89%) rename {src/test => tests}/fixtures/AccessResponse.json (100%) rename {src/test => tests}/fixtures/errors.ts (68%) rename {src/test => tests}/issues.e2e.ts (94%) rename {src/test => tests}/main/thumbnails/fixtures/1000x1000.jpg (100%) rename {src/test => tests}/main/thumbnails/fixtures/result.png (100%) rename {src/test => tests}/main/thumbnails/fixtures/source.pdf (100%) rename {src/test => tests}/main/thumbnails/helpers.ts (100%) rename {src/test => tests}/main/thumbnails/resize-image.test.ts (84%) rename {src/test => tests}/onboarding.e2e.ts (100%) rename {src/test => tests}/playwright.config.ts (100%) rename {src/test => tests}/selectors.ts (100%) rename {src/test => tests}/unauthorized.e2e.ts (100%) rename {src/test => tests}/utils.ts (100%) diff --git a/.erb/configs/webpack.paths.ts b/.erb/configs/webpack.paths.ts index 3e55b485d..4de2a5a95 100644 --- a/.erb/configs/webpack.paths.ts +++ b/.erb/configs/webpack.paths.ts @@ -4,12 +4,12 @@ const rootPath = path.join(__dirname, '../..'); const dllPath = path.join(__dirname, '../dll'); -const srcPath = path.join(rootPath, 'src'); +const srcPath = path.join(rootPath, 'src', 'apps'); const srcMainPath = path.join(srcPath, 'main'); const srcRendererPath = path.join(srcPath, 'renderer'); const srcSyncPath = path.join(srcPath, 'workers', 'sync'); const srcBackupsPath = path.join(srcPath, 'workers', 'backups'); -const srcSyncEnginePath = path.join(srcPath, 'workers', 'sync-engine'); +const srcSyncEnginePath = path.join(srcPath, 'sync-engine'); const releasePath = path.join(rootPath, 'release'); const appPath = path.join(releasePath, 'app'); diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 75175e11c..cf8d99f13 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,15 +5,16 @@ on: [pull_request] jobs: test: name: 🧪 Lint and test - runs-on: ubuntu-latest + runs-on: windows-latest steps: - name: Check out Git repository uses: actions/checkout@v2 - name: Use Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 + cache: 'yarn' - name: Create .npmrc file run: | echo "registry=https://registry.yarnpkg.com/" > .npmrc @@ -28,8 +29,6 @@ jobs: install-command: yarn --ignore-scripts --frozen-lockfile - name: Lint run: yarn run lint - - name: Typescript check - run: yarn run type-check - name: Build processes run: yarn build:main && yarn build:renderer - name: Run test diff --git a/package.json b/package.json index a1a5c0e5f..66ad6cb43 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,9 @@ "url": "https://github.com/internxt/drive-desktop" }, "scripts": { - "build": "concurrently \"npm run build:main\" \"npm run build:renderer\" \"npm run build:backups\" \"npm run build:sync-engine\"", + "build": "concurrently \"npm run build:main\" \"npm run build:renderer\" \"npm run build:sync-engine\"", "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts", "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts", - "build:backups": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.backups.ts", "build:sync-engine": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.sync-engine.ts", "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app", "lint": "cross-env NODE_ENV=development eslint . --ext .ts,.tsx", @@ -19,11 +18,10 @@ "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never", "publish": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish always", "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts && opencollective-postinstall", - "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:backups && npm run start:sync-engine && npm run start:renderer", - "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts", + "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:sync-engine && npm run start:renderer", + "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/apps/main/main.ts", "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts", "start:sync": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.sync.ts", - "start:backups": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.backups.ts", "start:sync-engine": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.sync-engine.ts", "test": "jest && playwright test --config=src/test", "test:unit": "jest --silent", diff --git a/src/main/analytics/drive-handlers.ts b/src/apps/main/analytics/drive-handlers.ts similarity index 100% rename from src/main/analytics/drive-handlers.ts rename to src/apps/main/analytics/drive-handlers.ts diff --git a/src/main/analytics/handlers.ts b/src/apps/main/analytics/handlers.ts similarity index 65% rename from src/main/analytics/handlers.ts rename to src/apps/main/analytics/handlers.ts index 20ad76e7c..d0655aafe 100644 --- a/src/main/analytics/handlers.ts +++ b/src/apps/main/analytics/handlers.ts @@ -1,3 +1,2 @@ import './user-handlers'; -import './backup-handlers'; import './drive-handlers'; diff --git a/src/main/analytics/rudderstack-client.ts b/src/apps/main/analytics/rudderstack-client.ts similarity index 73% rename from src/main/analytics/rudderstack-client.ts rename to src/apps/main/analytics/rudderstack-client.ts index 9a324d532..d6cd52af8 100644 --- a/src/main/analytics/rudderstack-client.ts +++ b/src/apps/main/analytics/rudderstack-client.ts @@ -4,11 +4,11 @@ const WRITE_KEY = process.env.RUDDERSTACK_KEY; const DATA_PLANE_URL = process.env.RUDDERSTACK_DATA_PLANE_URL; if (!WRITE_KEY) { - throw Error('[CONFIG] Missing ANALITICS WRITE KEY'); + throw Error('[CONFIG] Missing ANALYTICS WRITE KEY'); } if (!DATA_PLANE_URL) { - throw Error('[CONFIG] Missing ANALITICS URL'); + throw Error('[CONFIG] Missing ANALYTICS URL'); } const client = new Analytics(WRITE_KEY, `${DATA_PLANE_URL}`); diff --git a/src/main/analytics/service.ts b/src/apps/main/analytics/service.ts similarity index 99% rename from src/main/analytics/service.ts rename to src/apps/main/analytics/service.ts index 3ad509198..4cc906c6d 100644 --- a/src/main/analytics/service.ts +++ b/src/apps/main/analytics/service.ts @@ -1,4 +1,4 @@ -import packageJson from '../../../package.json'; +import packageJson from '../../../../package.json'; import ConfigStore from '../config'; import { client } from './rudderstack-client'; import os from 'os'; diff --git a/src/main/analytics/user-handlers.ts b/src/apps/main/analytics/user-handlers.ts similarity index 100% rename from src/main/analytics/user-handlers.ts rename to src/apps/main/analytics/user-handlers.ts diff --git a/src/main/app-info/app-info.ts b/src/apps/main/app-info/app-info.ts similarity index 76% rename from src/main/app-info/app-info.ts rename to src/apps/main/app-info/app-info.ts index 64eb91053..d7fbf1a6f 100644 --- a/src/main/app-info/app-info.ts +++ b/src/apps/main/app-info/app-info.ts @@ -1,4 +1,4 @@ -import packageJson from '../../../package.json'; +import packageJson from '../../../../package.json'; export type AppInfo = { name: 'drive-desktop'; diff --git a/src/apps/main/app-info/handlers.ts b/src/apps/main/app-info/handlers.ts new file mode 100644 index 000000000..0f0b19fce --- /dev/null +++ b/src/apps/main/app-info/handlers.ts @@ -0,0 +1,22 @@ +import { ipcMain, app } from 'electron'; + +ipcMain.handle('get-path', (_, path) => { + const result = app.getPath(path); + return result; +}); + +ipcMain.handle('APP:TEMPORAL_FILES_FOLDER', () => { + return app.getPath('temp'); +}); + +ipcMain.handle('APP:PREFERRED_LANGUAGE', (): Array => { + const canObtainPreferredLanguage = Object.keys(app).includes( + 'getPreferredSystemLanguage' + ); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + if (canObtainPreferredLanguage) return app.getPreferredSystemLanguage(); + + return ['en']; +}); diff --git a/src/main/auth/handlers.ts b/src/apps/main/auth/handlers.ts similarity index 96% rename from src/main/auth/handlers.ts rename to src/apps/main/auth/handlers.ts index 42ffbd1a0..47e102e47 100644 --- a/src/main/auth/handlers.ts +++ b/src/apps/main/auth/handlers.ts @@ -43,6 +43,10 @@ ipcMain.handle('get-headers-for-new-api', () => getNewApiHeaders()); ipcMain.handle('get-new-token', () => obtainToken('newToken')); +ipcMain.handle('get-token', () => { + return obtainToken('bearerToken'); +}); + export function onUserUnauthorized() { eventBus.emit('USER_WAS_UNAUTHORIZED'); diff --git a/src/main/auth/refresh-token.ts b/src/apps/main/auth/refresh-token.ts similarity index 100% rename from src/main/auth/refresh-token.ts rename to src/apps/main/auth/refresh-token.ts diff --git a/src/main/auth/service.ts b/src/apps/main/auth/service.ts similarity index 96% rename from src/main/auth/service.ts rename to src/apps/main/auth/service.ts index 315c0958b..57c110a03 100644 --- a/src/main/auth/service.ts +++ b/src/apps/main/auth/service.ts @@ -1,15 +1,15 @@ import { safeStorage } from 'electron'; import Logger from 'electron-log'; -import packageConfig from '../../../package.json'; +import packageConfig from '../../../../package.json'; import ConfigStore, { defaults, fieldsToSave } from '../config'; import { User } from '../types'; const TOKEN_ENCODING = 'latin1'; const tokensKeys = ['bearerToken', 'newToken'] as const; -type TokenKey = typeof tokensKeys[number]; -type EncryptedTokenKey = `${typeof tokensKeys[number]}Encrypted`; +type TokenKey = (typeof tokensKeys)[number]; +type EncryptedTokenKey = `${(typeof tokensKeys)[number]}Encrypted`; export function encryptToken() { const bearerTokenEncrypted = ConfigStore.get('bearerTokenEncrypted'); diff --git a/src/main/auto-launch/handlers.ts b/src/apps/main/auto-launch/handlers.ts similarity index 100% rename from src/main/auto-launch/handlers.ts rename to src/apps/main/auto-launch/handlers.ts diff --git a/src/main/auto-launch/linux-desktop-entry.ts b/src/apps/main/auto-launch/linux-desktop-entry.ts similarity index 94% rename from src/main/auto-launch/linux-desktop-entry.ts rename to src/apps/main/auto-launch/linux-desktop-entry.ts index 223256409..afba1ab0e 100644 --- a/src/main/auto-launch/linux-desktop-entry.ts +++ b/src/apps/main/auto-launch/linux-desktop-entry.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import os from 'os'; -import packageJson from '../../../package.json'; +import packageJson from '../../../../package.json'; const fileName = `${packageJson.name}.desktop`; const desktopFilePath = `${os.homedir()}/.config/autostart`; diff --git a/src/main/auto-launch/service.ts b/src/apps/main/auto-launch/service.ts similarity index 100% rename from src/main/auto-launch/service.ts rename to src/apps/main/auto-launch/service.ts diff --git a/src/main/background-processes/process-issues.ts b/src/apps/main/background-processes/process-issues.ts similarity index 98% rename from src/main/background-processes/process-issues.ts rename to src/apps/main/background-processes/process-issues.ts index cdec67929..7ac5006e2 100644 --- a/src/main/background-processes/process-issues.ts +++ b/src/apps/main/background-processes/process-issues.ts @@ -1,12 +1,12 @@ import { ipcMain } from 'electron'; +import eventBus from '../event-bus'; +import { broadcastToWindows } from '../windows'; import { + ProcessIssue, GeneralIssue, ProcessInfoUpdatePayload, - ProcessIssue, -} from '../../workers/types'; -import eventBus from '../event-bus'; -import { broadcastToWindows } from '../windows'; +} from '../../shared/types'; let processIssues: ProcessIssue[] = []; let generalIssues: GeneralIssue[] = []; diff --git a/src/main/background-processes/sync-engine.ts b/src/apps/main/background-processes/sync-engine.ts similarity index 98% rename from src/main/background-processes/sync-engine.ts rename to src/apps/main/background-processes/sync-engine.ts index c5e4b8de7..0149fcbb3 100644 --- a/src/main/background-processes/sync-engine.ts +++ b/src/apps/main/background-processes/sync-engine.ts @@ -30,7 +30,7 @@ function spawnSyncEngineWorker() { worker .loadFile( process.env.NODE_ENV === 'development' - ? '../../release/app/dist/sync-engine/index.html' + ? '../../../release/app/dist/sync-engine/index.html' : `${path.join(__dirname, '..', 'sync-engine')}/index.html` ) .then(() => { diff --git a/src/main/bug-report/BugReportResult.ts b/src/apps/main/bug-report/BugReportResult.ts similarity index 100% rename from src/main/bug-report/BugReportResult.ts rename to src/apps/main/bug-report/BugReportResult.ts diff --git a/src/main/bug-report/handlers.ts b/src/apps/main/bug-report/handlers.ts similarity index 100% rename from src/main/bug-report/handlers.ts rename to src/apps/main/bug-report/handlers.ts diff --git a/src/main/bug-report/service.ts b/src/apps/main/bug-report/service.ts similarity index 96% rename from src/main/bug-report/service.ts rename to src/apps/main/bug-report/service.ts index 14fca69bd..be6a87c3e 100644 --- a/src/main/bug-report/service.ts +++ b/src/apps/main/bug-report/service.ts @@ -5,13 +5,14 @@ import { createReadStream } from 'fs'; import fs from 'fs/promises'; import path from 'path'; -import packageJson from '../../../package.json'; -import { ErrorDetails } from '../../workers/types'; +import packageJson from '../../../../package.json'; import { obtainToken } from '../auth/service'; import { BugReportResult } from './BugReportResult'; import * as Sentry from '@sentry/electron/main'; import { User } from '../types'; import Logger from 'electron-log'; +import { ErrorDetails } from '../../shared/types'; + /** * Reports an error to Sentry from the main process * diff --git a/src/main/config.ts b/src/apps/main/config.ts similarity index 100% rename from src/main/config.ts rename to src/apps/main/config.ts diff --git a/src/main/config/handlers.ts b/src/apps/main/config/handlers.ts similarity index 100% rename from src/main/config/handlers.ts rename to src/apps/main/config/handlers.ts diff --git a/src/main/config/service.ts b/src/apps/main/config/service.ts similarity index 100% rename from src/main/config/service.ts rename to src/apps/main/config/service.ts diff --git a/src/main/database/adapters/base.ts b/src/apps/main/database/adapters/base.ts similarity index 100% rename from src/main/database/adapters/base.ts rename to src/apps/main/database/adapters/base.ts diff --git a/src/main/database/collections/DriveFileCollection.ts b/src/apps/main/database/collections/DriveFileCollection.ts similarity index 100% rename from src/main/database/collections/DriveFileCollection.ts rename to src/apps/main/database/collections/DriveFileCollection.ts diff --git a/src/main/database/collections/DriveFolderCollection.ts b/src/apps/main/database/collections/DriveFolderCollection.ts similarity index 100% rename from src/main/database/collections/DriveFolderCollection.ts rename to src/apps/main/database/collections/DriveFolderCollection.ts diff --git a/src/main/database/data-source.ts b/src/apps/main/database/data-source.ts similarity index 100% rename from src/main/database/data-source.ts rename to src/apps/main/database/data-source.ts diff --git a/src/main/database/entities/DriveFile.ts b/src/apps/main/database/entities/DriveFile.ts similarity index 100% rename from src/main/database/entities/DriveFile.ts rename to src/apps/main/database/entities/DriveFile.ts diff --git a/src/main/database/entities/DriveFolder.ts b/src/apps/main/database/entities/DriveFolder.ts similarity index 100% rename from src/main/database/entities/DriveFolder.ts rename to src/apps/main/database/entities/DriveFolder.ts diff --git a/src/main/device/handlers.ts b/src/apps/main/device/handlers.ts similarity index 100% rename from src/main/device/handlers.ts rename to src/apps/main/device/handlers.ts diff --git a/src/main/device/service.ts b/src/apps/main/device/service.ts similarity index 100% rename from src/main/device/service.ts rename to src/apps/main/device/service.ts diff --git a/src/main/event-bus.ts b/src/apps/main/event-bus.ts similarity index 100% rename from src/main/event-bus.ts rename to src/apps/main/event-bus.ts diff --git a/src/main/fordwardToWindows.ts b/src/apps/main/fordwardToWindows.ts similarity index 98% rename from src/main/fordwardToWindows.ts rename to src/apps/main/fordwardToWindows.ts index a2d1461d6..b0cc9f986 100644 --- a/src/main/fordwardToWindows.ts +++ b/src/apps/main/fordwardToWindows.ts @@ -1,6 +1,6 @@ -import { FileErrorInfo } from 'shared/IPC/events/drive'; -import { ipcMainDrive } from './ipcs/mainDrive'; import { broadcastToWindows } from './windows'; +import { ipcMainDrive } from './ipcs/mainDrive'; +import { FileErrorInfo } from '../shared/IPC/events/drive'; ipcMainDrive.on('FILE_DELETED', (_, payload) => { const { nameWithExtension } = payload; diff --git a/src/main/ipcs/NoEvents.ts b/src/apps/main/ipcs/NoEvents.ts similarity index 100% rename from src/main/ipcs/NoEvents.ts rename to src/apps/main/ipcs/NoEvents.ts diff --git a/src/main/ipcs/ipcMainSyncEngine.ts b/src/apps/main/ipcs/ipcMainSyncEngine.ts similarity index 100% rename from src/main/ipcs/ipcMainSyncEngine.ts rename to src/apps/main/ipcs/ipcMainSyncEngine.ts diff --git a/src/main/ipcs/mainDrive.ts b/src/apps/main/ipcs/mainDrive.ts similarity index 100% rename from src/main/ipcs/mainDrive.ts rename to src/apps/main/ipcs/mainDrive.ts index 58cdcdd87..ffd4169ff 100644 --- a/src/main/ipcs/mainDrive.ts +++ b/src/apps/main/ipcs/mainDrive.ts @@ -1,7 +1,7 @@ import { ipcMain } from 'electron'; -import { DriveEvents } from '../../shared/IPC/events/drive'; -import { CustomIpc } from '../../shared/IPC/IPCs'; import { NoEvents } from './NoEvents'; +import { CustomIpc } from '../../shared/IPC/IPCs'; +import { DriveEvents } from '../../shared/IPC/events/drive'; export type IpcMainDrive = CustomIpc; diff --git a/src/main/ipcs/mainVirtualDrive.ts b/src/apps/main/ipcs/mainVirtualDrive.ts similarity index 100% rename from src/main/ipcs/mainVirtualDrive.ts rename to src/apps/main/ipcs/mainVirtualDrive.ts diff --git a/src/main/logger.ts b/src/apps/main/logger.ts similarity index 100% rename from src/main/logger.ts rename to src/apps/main/logger.ts diff --git a/src/main/main.ts b/src/apps/main/main.ts similarity index 97% rename from src/main/main.ts rename to src/apps/main/main.ts index 7830a6089..29975eb81 100644 --- a/src/main/main.ts +++ b/src/apps/main/main.ts @@ -35,7 +35,7 @@ import './remote-sync/handlers'; import { app, nativeTheme } from 'electron'; import Logger from 'electron-log'; import { autoUpdater } from 'electron-updater'; -import packageJson from '../../package.json'; +import packageJson from '../../../package.json'; import eventBus from './event-bus'; import * as Sentry from '@sentry/electron/main'; import { AppDataSource } from './database/data-source'; @@ -50,9 +50,9 @@ import configStore from './config'; import { getTray, setTrayStatus } from './tray/tray'; import { openOnboardingWindow } from './windows/onboarding'; import { reportError } from './bug-report/service'; -import { Theme } from 'shared/types/Theme'; import { setCleanUpFunction } from './quit'; import { stopSyncEngineWatcher } from './background-processes/sync-engine'; +import { Theme } from '../shared/types/Theme'; Logger.log(`Running ${packageJson.version}`); diff --git a/src/main/migration/handlers.ts b/src/apps/main/migration/handlers.ts similarity index 100% rename from src/main/migration/handlers.ts rename to src/apps/main/migration/handlers.ts diff --git a/src/main/migration/service.ts b/src/apps/main/migration/service.ts similarity index 100% rename from src/main/migration/service.ts rename to src/apps/main/migration/service.ts diff --git a/src/main/platform/DesktopPlatform.ts b/src/apps/main/platform/DesktopPlatform.ts similarity index 100% rename from src/main/platform/DesktopPlatform.ts rename to src/apps/main/platform/DesktopPlatform.ts diff --git a/src/main/platform/handlers.ts b/src/apps/main/platform/handlers.ts similarity index 100% rename from src/main/platform/handlers.ts rename to src/apps/main/platform/handlers.ts diff --git a/src/main/preload.d.ts b/src/apps/main/preload.d.ts similarity index 71% rename from src/main/preload.d.ts rename to src/apps/main/preload.d.ts index ce1be4c90..7168f9129 100644 --- a/src/main/preload.d.ts +++ b/src/apps/main/preload.d.ts @@ -1,7 +1,5 @@ declare interface Window { electron: { - query: typeof import('./app-info/service').executeQuery; - getConfigKey(key: import('./config/service').StoredValues): Promise; listenToConfigKeyChange( @@ -13,6 +11,32 @@ declare interface Window { pathChanged(path: string): void; + getGeneralIssues: () => Promise< + import('../../apps/shared/types').GeneralIssue[] + >; + + onGeneralIssuesChanged: ( + func: (value: import('../../apps/shared/types').GeneralIssue[]) => void + ) => () => void; + + onSyncStopped: ( + func: ( + value: import('../../context/desktop/sync/domain/SyncStoppedPayload').SyncStoppedPayload + ) => void + ) => () => void; + + getProcessIssues(): Promise; + + onProcessIssuesChanged( + func: (value: import('apps/shared/types').ProcessIssue[]) => void + ): () => void; + + onSyncInfoUpdate( + func: ( + value: import('apps/shared/types').ProcessInfoUpdatePayload + ) => void + ): () => void; + userIsUnauthorized(): void; userLoggedIn( @@ -49,38 +73,9 @@ declare interface Window { stopSyncProcess(): void; - getSyncStatus(): Promise< - import('main/background-processes/sync').SyncStatus - >; - - onSyncStatusChanged( - func: (value: import('main/background-processes/sync').SyncStatus) => void - ): () => void; - - onSyncStopped( - func: ( - value: import('main/background-processes/sync').SyncStoppedPayload - ) => void - ): () => void; - - onSyncInfoUpdate( - func: (value: import('../workers/types').ProcessInfoUpdatePayload) => void - ): () => void; - moveSyncFolderToDesktop(): Promise< typeof import('../main/migration/service').moveSyncFolderToDesktop >; - getProcessIssues(): Promise; - - onProcessIssuesChanged( - func: (value: import('../workers/types').ProcessIssue[]) => void - ): () => void; - - getGeneralIssues(): Promise; - - onGeneralIssuesChanged( - func: (value: import('../workers/types').GeneralIssue[]) => void - ): () => void; openProcessIssuesWindow(): void; @@ -106,16 +101,6 @@ declare interface Window { stopBackupsProcess(): void; - getBackupsStatus(): Promise< - import('main/background-processes/backups').BackupsStatus - >; - - onBackupsStatusChanged( - func: ( - value: import('main/background-processes/backups').BackupsStatus - ) => void - ): () => void; - getVirtualDriveRoot(): Promise; chooseSyncRootWithDialog: typeof import('./virutal-root-folder/service').chooseSyncRootWithDialog; @@ -142,32 +127,8 @@ declare interface Window { getLastBackupTimestamp: () => Promise; - getLastBackupExitReason: () => Promise< - import('../main/background-processes/backups').BackupExitReason | null - >; - - onBackupProgress( - func: ( - value: import('main/background-processes/backups').BackupProgress - ) => void - ): () => void; - - getBackupFatalErrors(): Promise< - Array< - import('../main/background-processes/types/BackupFatalError').BackupFatalError - > - >; - deleteBackupError(folderId: number): Promise; - onBackupFatalErrorsChanged( - func: ( - value: Array< - import('../main/background-processes/types/BackupFatalError').BackupFatalError - > - ) => void - ): () => void; - changeBackupPath: typeof import('../main/device/service').changeBackupPath; getFolderPath: typeof import('../main/device/service').getPathFromDialog; @@ -205,5 +166,6 @@ declare interface Window { retryVirtualDriveMount(): void; startRemoteSync: () => Promise; openUrl: (url: string) => Promise; + getPreferredAppLanguage: () => Promise>; }; } diff --git a/src/main/preload.js b/src/apps/main/preload.js similarity index 99% rename from src/main/preload.js rename to src/apps/main/preload.js index 70cb93ab0..e988efa87 100644 --- a/src/main/preload.js +++ b/src/apps/main/preload.js @@ -2,9 +2,6 @@ const { contextBridge, ipcRenderer } = require('electron'); const path = require('path'); contextBridge.exposeInMainWorld('electron', { - query(query) { - return ipcRenderer.invoke('execute-app-query', query); - }, getConfigKey(key) { return ipcRenderer.invoke('get-config-key', key); }, @@ -296,5 +293,8 @@ contextBridge.exposeInMainWorld('electron', { openUrl: (url) => { ipcRenderer.invoke('open-url', url); }, + getPreferredAppLanguage() { + return ipcRenderer.invoke('APP:PREFERRED_LANGUAGE'); + }, path, }); diff --git a/src/main/quit.ts b/src/apps/main/quit.ts similarity index 100% rename from src/main/quit.ts rename to src/apps/main/quit.ts diff --git a/src/main/realtime.ts b/src/apps/main/realtime.ts similarity index 100% rename from src/main/realtime.ts rename to src/apps/main/realtime.ts diff --git a/src/main/remote-sync/RemoteSyncManager.test.ts b/src/apps/main/remote-sync/RemoteSyncManager.test.ts similarity index 97% rename from src/main/remote-sync/RemoteSyncManager.test.ts rename to src/apps/main/remote-sync/RemoteSyncManager.test.ts index e6ac83436..6cce45eed 100644 --- a/src/main/remote-sync/RemoteSyncManager.test.ts +++ b/src/apps/main/remote-sync/RemoteSyncManager.test.ts @@ -6,13 +6,14 @@ jest.mock('@sentry/electron/main', () => ({ jest.mock('electron'); jest.mock('electron-store'); jest.mock('axios'); -import { DatabaseCollectionAdapter } from 'main/database/adapters/base'; -import { DriveFile } from 'main/database/entities/DriveFile'; -import { DriveFolder } from 'main/database/entities/DriveFolder'; + import { RemoteSyncManager } from './RemoteSyncManager'; import { RemoteSyncedFile, RemoteSyncedFolder } from './helpers'; import * as uuid from 'uuid'; import axios from 'axios'; +import { DatabaseCollectionAdapter } from '../database/adapters/base'; +import { DriveFile } from '../database/entities/DriveFile'; +import { DriveFolder } from '../database/entities/DriveFolder'; const mockedAxios = axios as jest.Mocked; diff --git a/src/main/remote-sync/RemoteSyncManager.ts b/src/apps/main/remote-sync/RemoteSyncManager.ts similarity index 100% rename from src/main/remote-sync/RemoteSyncManager.ts rename to src/apps/main/remote-sync/RemoteSyncManager.ts diff --git a/src/main/remote-sync/handlers.ts b/src/apps/main/remote-sync/handlers.ts similarity index 100% rename from src/main/remote-sync/handlers.ts rename to src/apps/main/remote-sync/handlers.ts diff --git a/src/main/remote-sync/helpers.ts b/src/apps/main/remote-sync/helpers.ts similarity index 100% rename from src/main/remote-sync/helpers.ts rename to src/apps/main/remote-sync/helpers.ts diff --git a/src/main/thumbnails/application/create-and-upload-thumbnail.ts b/src/apps/main/thumbnails/application/create-and-upload-thumbnail.ts similarity index 100% rename from src/main/thumbnails/application/create-and-upload-thumbnail.ts rename to src/apps/main/thumbnails/application/create-and-upload-thumbnail.ts diff --git a/src/main/thumbnails/application/extract-pdf-page.ts b/src/apps/main/thumbnails/application/extract-pdf-page.ts similarity index 100% rename from src/main/thumbnails/application/extract-pdf-page.ts rename to src/apps/main/thumbnails/application/extract-pdf-page.ts diff --git a/src/main/thumbnails/application/obtain-image-to-thumbnail-it.ts b/src/apps/main/thumbnails/application/obtain-image-to-thumbnail-it.ts similarity index 100% rename from src/main/thumbnails/application/obtain-image-to-thumbnail-it.ts rename to src/apps/main/thumbnails/application/obtain-image-to-thumbnail-it.ts diff --git a/src/main/thumbnails/application/resize-image.ts b/src/apps/main/thumbnails/application/resize-image.ts similarity index 100% rename from src/main/thumbnails/application/resize-image.ts rename to src/apps/main/thumbnails/application/resize-image.ts diff --git a/src/main/thumbnails/domain/ThumbnableExtension.ts b/src/apps/main/thumbnails/domain/ThumbnableExtension.ts similarity index 100% rename from src/main/thumbnails/domain/ThumbnableExtension.ts rename to src/apps/main/thumbnails/domain/ThumbnableExtension.ts diff --git a/src/main/thumbnails/domain/ThumbnailProperties.ts b/src/apps/main/thumbnails/domain/ThumbnailProperties.ts similarity index 100% rename from src/main/thumbnails/domain/ThumbnailProperties.ts rename to src/apps/main/thumbnails/domain/ThumbnailProperties.ts diff --git a/src/main/thumbnails/domain/ThumbnailUploader.ts b/src/apps/main/thumbnails/domain/ThumbnailUploader.ts similarity index 100% rename from src/main/thumbnails/domain/ThumbnailUploader.ts rename to src/apps/main/thumbnails/domain/ThumbnailUploader.ts diff --git a/src/main/thumbnails/handlers/index.ts b/src/apps/main/thumbnails/handlers/index.ts similarity index 100% rename from src/main/thumbnails/handlers/index.ts rename to src/apps/main/thumbnails/handlers/index.ts diff --git a/src/main/thumbnails/handlers/remote-file-pull-completed.ts b/src/apps/main/thumbnails/handlers/remote-file-pull-completed.ts similarity index 100% rename from src/main/thumbnails/handlers/remote-file-pull-completed.ts rename to src/apps/main/thumbnails/handlers/remote-file-pull-completed.ts diff --git a/src/main/thumbnails/infrastructure/EnvironmentAndStorageThumbnailUploader.ts b/src/apps/main/thumbnails/infrastructure/EnvironmentAndStorageThumbnailUploader.ts similarity index 100% rename from src/main/thumbnails/infrastructure/EnvironmentAndStorageThumbnailUploader.ts rename to src/apps/main/thumbnails/infrastructure/EnvironmentAndStorageThumbnailUploader.ts diff --git a/src/main/thumbnails/infrastructure/ThumbnailUploaderFactory.ts b/src/apps/main/thumbnails/infrastructure/ThumbnailUploaderFactory.ts similarity index 100% rename from src/main/thumbnails/infrastructure/ThumbnailUploaderFactory.ts rename to src/apps/main/thumbnails/infrastructure/ThumbnailUploaderFactory.ts diff --git a/src/main/token-scheduler/TokenScheduler.ts b/src/apps/main/token-scheduler/TokenScheduler.ts similarity index 100% rename from src/main/token-scheduler/TokenScheduler.ts rename to src/apps/main/token-scheduler/TokenScheduler.ts diff --git a/src/main/token-scheduler/token-scheduler.test.ts b/src/apps/main/token-scheduler/token-scheduler.test.ts similarity index 100% rename from src/main/token-scheduler/token-scheduler.test.ts rename to src/apps/main/token-scheduler/token-scheduler.test.ts diff --git a/src/main/tray/handlers.ts b/src/apps/main/tray/handlers.ts similarity index 100% rename from src/main/tray/handlers.ts rename to src/apps/main/tray/handlers.ts diff --git a/src/main/tray/tray.ts b/src/apps/main/tray/tray.ts similarity index 97% rename from src/main/tray/tray.ts rename to src/apps/main/tray/tray.ts index 98e97107b..7104e5298 100644 --- a/src/main/tray/tray.ts +++ b/src/apps/main/tray/tray.ts @@ -1,6 +1,6 @@ import { app, Menu, nativeImage, Tray } from 'electron'; import path from 'path'; -import PackageJson from '../../../package.json'; +import PackageJson from '../../../../package.json'; import eventBus from '../event-bus'; import { getOrCreateWidged, @@ -119,7 +119,7 @@ export const setTrayStatus = (status: TrayMenuState) => { export function setupTrayIcon() { const RESOURCES_PATH = app.isPackaged ? path.join(process.resourcesPath, 'assets') - : path.join(__dirname, '../../../assets'); + : path.join(__dirname, '../../../../assets'); const iconsPath = path.join(RESOURCES_PATH, 'tray'); diff --git a/src/main/types.ts b/src/apps/main/types.ts similarity index 100% rename from src/main/types.ts rename to src/apps/main/types.ts diff --git a/src/main/usage/Usage.ts b/src/apps/main/usage/Usage.ts similarity index 100% rename from src/main/usage/Usage.ts rename to src/apps/main/usage/Usage.ts diff --git a/src/main/usage/handlers.ts b/src/apps/main/usage/handlers.ts similarity index 100% rename from src/main/usage/handlers.ts rename to src/apps/main/usage/handlers.ts diff --git a/src/main/usage/service.ts b/src/apps/main/usage/service.ts similarity index 100% rename from src/main/usage/service.ts rename to src/apps/main/usage/service.ts diff --git a/src/main/usage/serviceBuilder.ts b/src/apps/main/usage/serviceBuilder.ts similarity index 100% rename from src/main/usage/serviceBuilder.ts rename to src/apps/main/usage/serviceBuilder.ts diff --git a/src/main/util.ts b/src/apps/main/util.ts similarity index 100% rename from src/main/util.ts rename to src/apps/main/util.ts diff --git a/src/main/virutal-root-folder/handlers.ts b/src/apps/main/virutal-root-folder/handlers.ts similarity index 100% rename from src/main/virutal-root-folder/handlers.ts rename to src/apps/main/virutal-root-folder/handlers.ts diff --git a/src/main/virutal-root-folder/service.ts b/src/apps/main/virutal-root-folder/service.ts similarity index 100% rename from src/main/virutal-root-folder/service.ts rename to src/apps/main/virutal-root-folder/service.ts diff --git a/src/main/windows/auth.ts b/src/apps/main/windows/auth.ts similarity index 100% rename from src/main/windows/auth.ts rename to src/apps/main/windows/auth.ts diff --git a/src/main/windows/feedback.ts b/src/apps/main/windows/feedback.ts similarity index 100% rename from src/main/windows/feedback.ts rename to src/apps/main/windows/feedback.ts diff --git a/src/main/windows/index.ts b/src/apps/main/windows/index.ts similarity index 100% rename from src/main/windows/index.ts rename to src/apps/main/windows/index.ts diff --git a/src/main/windows/migration.ts b/src/apps/main/windows/migration.ts similarity index 100% rename from src/main/windows/migration.ts rename to src/apps/main/windows/migration.ts diff --git a/src/main/windows/onboarding.ts b/src/apps/main/windows/onboarding.ts similarity index 100% rename from src/main/windows/onboarding.ts rename to src/apps/main/windows/onboarding.ts diff --git a/src/main/windows/process-issues.ts b/src/apps/main/windows/process-issues.ts similarity index 100% rename from src/main/windows/process-issues.ts rename to src/apps/main/windows/process-issues.ts diff --git a/src/main/windows/settings.ts b/src/apps/main/windows/settings.ts similarity index 100% rename from src/main/windows/settings.ts rename to src/apps/main/windows/settings.ts diff --git a/src/main/windows/widget.ts b/src/apps/main/windows/widget.ts similarity index 100% rename from src/main/windows/widget.ts rename to src/apps/main/windows/widget.ts diff --git a/src/renderer/App.css b/src/apps/renderer/App.css similarity index 100% rename from src/renderer/App.css rename to src/apps/renderer/App.css diff --git a/src/renderer/App.tsx b/src/apps/renderer/App.tsx similarity index 100% rename from src/renderer/App.tsx rename to src/apps/renderer/App.tsx diff --git a/src/renderer/actions/shared-actions.ts b/src/apps/renderer/actions/shared-actions.ts similarity index 100% rename from src/renderer/actions/shared-actions.ts rename to src/apps/renderer/actions/shared-actions.ts diff --git a/src/renderer/actions/sync-error-actions.ts b/src/apps/renderer/actions/sync-error-actions.ts similarity index 100% rename from src/renderer/actions/sync-error-actions.ts rename to src/apps/renderer/actions/sync-error-actions.ts diff --git a/src/apps/renderer/actions/types.ts b/src/apps/renderer/actions/types.ts new file mode 100644 index 000000000..3bb177c6e --- /dev/null +++ b/src/apps/renderer/actions/types.ts @@ -0,0 +1,8 @@ +import { ProcessFatalErrorName } from '../../shared/types'; + +export interface Action { + name: string; + func: (() => void) | ((error: undefined) => Promise); +} + +export type FatalErrorActionMap = Record; diff --git a/src/renderer/assets/error.svg b/src/apps/renderer/assets/error.svg similarity index 100% rename from src/renderer/assets/error.svg rename to src/apps/renderer/assets/error.svg diff --git a/src/renderer/assets/file.svg b/src/apps/renderer/assets/file.svg similarity index 100% rename from src/renderer/assets/file.svg rename to src/apps/renderer/assets/file.svg diff --git a/src/renderer/assets/folder.svg b/src/apps/renderer/assets/folder.svg similarity index 100% rename from src/renderer/assets/folder.svg rename to src/apps/renderer/assets/folder.svg diff --git a/src/renderer/assets/fonts/InstrumentSans/InstrumentSans-Bold.woff2 b/src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-Bold.woff2 similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/InstrumentSans-Bold.woff2 rename to src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-Bold.woff2 diff --git a/src/renderer/assets/fonts/InstrumentSans/InstrumentSans-Medium.woff2 b/src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-Medium.woff2 similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/InstrumentSans-Medium.woff2 rename to src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-Medium.woff2 diff --git a/src/renderer/assets/fonts/InstrumentSans/InstrumentSans-Regular.woff2 b/src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-Regular.woff2 similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/InstrumentSans-Regular.woff2 rename to src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-Regular.woff2 diff --git a/src/renderer/assets/fonts/InstrumentSans/InstrumentSans-SemiBold.woff2 b/src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-SemiBold.woff2 similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/InstrumentSans-SemiBold.woff2 rename to src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans-SemiBold.woff2 diff --git a/src/renderer/assets/fonts/InstrumentSans/InstrumentSans[wdth,wght].woff2 b/src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans[wdth,wght].woff2 similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/InstrumentSans[wdth,wght].woff2 rename to src/apps/renderer/assets/fonts/InstrumentSans/InstrumentSans[wdth,wght].woff2 diff --git a/src/renderer/assets/fonts/InstrumentSans/OFL.txt b/src/apps/renderer/assets/fonts/InstrumentSans/OFL.txt similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/OFL.txt rename to src/apps/renderer/assets/fonts/InstrumentSans/OFL.txt diff --git a/src/renderer/assets/fonts/InstrumentSans/font.css b/src/apps/renderer/assets/fonts/InstrumentSans/font.css similarity index 100% rename from src/renderer/assets/fonts/InstrumentSans/font.css rename to src/apps/renderer/assets/fonts/InstrumentSans/font.css diff --git a/src/renderer/assets/icons/audio.svg b/src/apps/renderer/assets/icons/audio.svg similarity index 100% rename from src/renderer/assets/icons/audio.svg rename to src/apps/renderer/assets/icons/audio.svg diff --git a/src/renderer/assets/icons/code.svg b/src/apps/renderer/assets/icons/code.svg similarity index 100% rename from src/renderer/assets/icons/code.svg rename to src/apps/renderer/assets/icons/code.svg diff --git a/src/renderer/assets/icons/csv.svg b/src/apps/renderer/assets/icons/csv.svg similarity index 100% rename from src/renderer/assets/icons/csv.svg rename to src/apps/renderer/assets/icons/csv.svg diff --git a/src/renderer/assets/icons/default.svg b/src/apps/renderer/assets/icons/default.svg similarity index 100% rename from src/renderer/assets/icons/default.svg rename to src/apps/renderer/assets/icons/default.svg diff --git a/src/renderer/assets/icons/excel.svg b/src/apps/renderer/assets/icons/excel.svg similarity index 100% rename from src/renderer/assets/icons/excel.svg rename to src/apps/renderer/assets/icons/excel.svg diff --git a/src/renderer/assets/icons/figma.svg b/src/apps/renderer/assets/icons/figma.svg similarity index 100% rename from src/renderer/assets/icons/figma.svg rename to src/apps/renderer/assets/icons/figma.svg diff --git a/src/renderer/assets/icons/folder.svg b/src/apps/renderer/assets/icons/folder.svg similarity index 100% rename from src/renderer/assets/icons/folder.svg rename to src/apps/renderer/assets/icons/folder.svg diff --git a/src/renderer/assets/icons/getIcon.tsx b/src/apps/renderer/assets/icons/getIcon.tsx similarity index 100% rename from src/renderer/assets/icons/getIcon.tsx rename to src/apps/renderer/assets/icons/getIcon.tsx diff --git a/src/renderer/assets/icons/illustrator.svg b/src/apps/renderer/assets/icons/illustrator.svg similarity index 100% rename from src/renderer/assets/icons/illustrator.svg rename to src/apps/renderer/assets/icons/illustrator.svg diff --git a/src/renderer/assets/icons/image.svg b/src/apps/renderer/assets/icons/image.svg similarity index 100% rename from src/renderer/assets/icons/image.svg rename to src/apps/renderer/assets/icons/image.svg diff --git a/src/renderer/assets/icons/indesign.svg b/src/apps/renderer/assets/icons/indesign.svg similarity index 100% rename from src/renderer/assets/icons/indesign.svg rename to src/apps/renderer/assets/icons/indesign.svg diff --git a/src/renderer/assets/icons/pdf.svg b/src/apps/renderer/assets/icons/pdf.svg similarity index 100% rename from src/renderer/assets/icons/pdf.svg rename to src/apps/renderer/assets/icons/pdf.svg diff --git a/src/renderer/assets/icons/photoshop.svg b/src/apps/renderer/assets/icons/photoshop.svg similarity index 100% rename from src/renderer/assets/icons/photoshop.svg rename to src/apps/renderer/assets/icons/photoshop.svg diff --git a/src/renderer/assets/icons/powerpoint.svg b/src/apps/renderer/assets/icons/powerpoint.svg similarity index 100% rename from src/renderer/assets/icons/powerpoint.svg rename to src/apps/renderer/assets/icons/powerpoint.svg diff --git a/src/renderer/assets/icons/ppt.svg b/src/apps/renderer/assets/icons/ppt.svg similarity index 100% rename from src/renderer/assets/icons/ppt.svg rename to src/apps/renderer/assets/icons/ppt.svg diff --git a/src/renderer/assets/icons/sketch.svg b/src/apps/renderer/assets/icons/sketch.svg similarity index 100% rename from src/renderer/assets/icons/sketch.svg rename to src/apps/renderer/assets/icons/sketch.svg diff --git a/src/renderer/assets/icons/txt.svg b/src/apps/renderer/assets/icons/txt.svg similarity index 100% rename from src/renderer/assets/icons/txt.svg rename to src/apps/renderer/assets/icons/txt.svg diff --git a/src/renderer/assets/icons/video.svg b/src/apps/renderer/assets/icons/video.svg similarity index 100% rename from src/renderer/assets/icons/video.svg rename to src/apps/renderer/assets/icons/video.svg diff --git a/src/renderer/assets/icons/word.svg b/src/apps/renderer/assets/icons/word.svg similarity index 100% rename from src/renderer/assets/icons/word.svg rename to src/apps/renderer/assets/icons/word.svg diff --git a/src/renderer/assets/icons/zip.svg b/src/apps/renderer/assets/icons/zip.svg similarity index 100% rename from src/renderer/assets/icons/zip.svg rename to src/apps/renderer/assets/icons/zip.svg diff --git a/src/renderer/assets/illustrations/syncedStack-dark.png b/src/apps/renderer/assets/illustrations/syncedStack-dark.png similarity index 100% rename from src/renderer/assets/illustrations/syncedStack-dark.png rename to src/apps/renderer/assets/illustrations/syncedStack-dark.png diff --git a/src/renderer/assets/illustrations/syncedStack-light.png b/src/apps/renderer/assets/illustrations/syncedStack-light.png similarity index 100% rename from src/renderer/assets/illustrations/syncedStack-light.png rename to src/apps/renderer/assets/illustrations/syncedStack-light.png diff --git a/src/renderer/assets/index.d.ts b/src/apps/renderer/assets/index.d.ts similarity index 100% rename from src/renderer/assets/index.d.ts rename to src/apps/renderer/assets/index.d.ts diff --git a/src/renderer/assets/migration/upload-error.svg b/src/apps/renderer/assets/migration/upload-error.svg similarity index 100% rename from src/renderer/assets/migration/upload-error.svg rename to src/apps/renderer/assets/migration/upload-error.svg diff --git a/src/renderer/assets/migration/widget.svg b/src/apps/renderer/assets/migration/widget.svg similarity index 100% rename from src/renderer/assets/migration/widget.svg rename to src/apps/renderer/assets/migration/widget.svg diff --git a/src/renderer/assets/onboarding/context-menu.svg b/src/apps/renderer/assets/onboarding/context-menu.svg similarity index 100% rename from src/renderer/assets/onboarding/context-menu.svg rename to src/apps/renderer/assets/onboarding/context-menu.svg diff --git a/src/renderer/assets/onboarding/finder/linux.svg b/src/apps/renderer/assets/onboarding/finder/linux.svg similarity index 100% rename from src/renderer/assets/onboarding/finder/linux.svg rename to src/apps/renderer/assets/onboarding/finder/linux.svg diff --git a/src/renderer/assets/onboarding/finder/macos.svg b/src/apps/renderer/assets/onboarding/finder/macos.svg similarity index 100% rename from src/renderer/assets/onboarding/finder/macos.svg rename to src/apps/renderer/assets/onboarding/finder/macos.svg diff --git a/src/renderer/assets/onboarding/finder/windows.svg b/src/apps/renderer/assets/onboarding/finder/windows.svg similarity index 100% rename from src/renderer/assets/onboarding/finder/windows.svg rename to src/apps/renderer/assets/onboarding/finder/windows.svg diff --git a/src/renderer/assets/onboarding/folder-with-overlay-icons/offline/en.svg b/src/apps/renderer/assets/onboarding/folder-with-overlay-icons/offline/en.svg similarity index 100% rename from src/renderer/assets/onboarding/folder-with-overlay-icons/offline/en.svg rename to src/apps/renderer/assets/onboarding/folder-with-overlay-icons/offline/en.svg diff --git a/src/renderer/assets/onboarding/folder-with-overlay-icons/offline/es.svg b/src/apps/renderer/assets/onboarding/folder-with-overlay-icons/offline/es.svg similarity index 100% rename from src/renderer/assets/onboarding/folder-with-overlay-icons/offline/es.svg rename to src/apps/renderer/assets/onboarding/folder-with-overlay-icons/offline/es.svg diff --git a/src/renderer/assets/onboarding/folder-with-overlay-icons/offline/fr.svg b/src/apps/renderer/assets/onboarding/folder-with-overlay-icons/offline/fr.svg similarity index 100% rename from src/renderer/assets/onboarding/folder-with-overlay-icons/offline/fr.svg rename to src/apps/renderer/assets/onboarding/folder-with-overlay-icons/offline/fr.svg diff --git a/src/renderer/assets/onboarding/folder-with-overlay-icons/online/en.svg b/src/apps/renderer/assets/onboarding/folder-with-overlay-icons/online/en.svg similarity index 100% rename from src/renderer/assets/onboarding/folder-with-overlay-icons/online/en.svg rename to src/apps/renderer/assets/onboarding/folder-with-overlay-icons/online/en.svg diff --git a/src/renderer/assets/onboarding/folder-with-overlay-icons/online/es.svg b/src/apps/renderer/assets/onboarding/folder-with-overlay-icons/online/es.svg similarity index 100% rename from src/renderer/assets/onboarding/folder-with-overlay-icons/online/es.svg rename to src/apps/renderer/assets/onboarding/folder-with-overlay-icons/online/es.svg diff --git a/src/renderer/assets/onboarding/folder-with-overlay-icons/online/fr.svg b/src/apps/renderer/assets/onboarding/folder-with-overlay-icons/online/fr.svg similarity index 100% rename from src/renderer/assets/onboarding/folder-with-overlay-icons/online/fr.svg rename to src/apps/renderer/assets/onboarding/folder-with-overlay-icons/online/fr.svg diff --git a/src/renderer/assets/onboarding/logo.svg b/src/apps/renderer/assets/onboarding/logo.svg similarity index 100% rename from src/renderer/assets/onboarding/logo.svg rename to src/apps/renderer/assets/onboarding/logo.svg diff --git a/src/renderer/assets/onboarding/mac-finder-widget.png b/src/apps/renderer/assets/onboarding/mac-finder-widget.png similarity index 100% rename from src/renderer/assets/onboarding/mac-finder-widget.png rename to src/apps/renderer/assets/onboarding/mac-finder-widget.png diff --git a/src/renderer/assets/onboarding/widget.png b/src/apps/renderer/assets/onboarding/widget.png similarity index 100% rename from src/renderer/assets/onboarding/widget.png rename to src/apps/renderer/assets/onboarding/widget.png diff --git a/src/renderer/assets/play.svg b/src/apps/renderer/assets/play.svg similarity index 100% rename from src/renderer/assets/play.svg rename to src/apps/renderer/assets/play.svg diff --git a/src/renderer/assets/spinner.svg b/src/apps/renderer/assets/spinner.svg similarity index 100% rename from src/renderer/assets/spinner.svg rename to src/apps/renderer/assets/spinner.svg diff --git a/src/renderer/assets/stop.svg b/src/apps/renderer/assets/stop.svg similarity index 100% rename from src/renderer/assets/stop.svg rename to src/apps/renderer/assets/stop.svg diff --git a/src/renderer/assets/success.svg b/src/apps/renderer/assets/success.svg similarity index 100% rename from src/renderer/assets/success.svg rename to src/apps/renderer/assets/success.svg diff --git a/src/renderer/assets/warn.svg b/src/apps/renderer/assets/warn.svg similarity index 100% rename from src/renderer/assets/warn.svg rename to src/apps/renderer/assets/warn.svg diff --git a/src/renderer/components/Backups/BackupsFoldersSelector.tsx b/src/apps/renderer/components/Backups/BackupsFoldersSelector.tsx similarity index 97% rename from src/renderer/components/Backups/BackupsFoldersSelector.tsx rename to src/apps/renderer/components/Backups/BackupsFoldersSelector.tsx index 7ab385e8b..07d2e3838 100644 --- a/src/renderer/components/Backups/BackupsFoldersSelector.tsx +++ b/src/apps/renderer/components/Backups/BackupsFoldersSelector.tsx @@ -1,10 +1,8 @@ import React, { useState } from 'react'; import FolderIcon from '../../assets/folder.svg'; - import Button from '../Button'; import { UilMinus, UilPlus } from '@iconscout/react-unicons'; -import { useTranslationContext } from 'renderer/context/LocalContext'; -import { reportError } from 'renderer/utils/errors'; +import { useTranslationContext } from '../../context/LocalContext'; export type BackupFolder = { path: string; diff --git a/src/renderer/components/Backups/FatalError.tsx b/src/apps/renderer/components/Backups/FatalError.tsx similarity index 85% rename from src/renderer/components/Backups/FatalError.tsx rename to src/apps/renderer/components/Backups/FatalError.tsx index ace51606f..887ca9084 100644 --- a/src/renderer/components/Backups/FatalError.tsx +++ b/src/apps/renderer/components/Backups/FatalError.tsx @@ -1,9 +1,8 @@ -import { useTranslationContext } from 'renderer/context/LocalContext'; - -import { ProcessFatalErrorName } from '../../../workers/types'; +import { ProcessFatalErrorName } from '../../../shared/types'; import ErrorIcon from '../../assets/error.svg'; +import { useTranslationContext } from '../../context/LocalContext'; import messages from '../../messages/process-fatal-error'; -import Button from 'renderer/components/Button'; +import Button from '../Button'; export function FatalError({ errorName, diff --git a/src/renderer/components/Button.tsx b/src/apps/renderer/components/Button.tsx similarity index 100% rename from src/renderer/components/Button.tsx rename to src/apps/renderer/components/Button.tsx diff --git a/src/renderer/components/Checkbox.tsx b/src/apps/renderer/components/Checkbox.tsx similarity index 100% rename from src/renderer/components/Checkbox.tsx rename to src/apps/renderer/components/Checkbox.tsx diff --git a/src/renderer/components/FileWithOperation.tsx b/src/apps/renderer/components/FileWithOperation.tsx similarity index 100% rename from src/renderer/components/FileWithOperation.tsx rename to src/apps/renderer/components/FileWithOperation.tsx diff --git a/src/renderer/components/PasswordInput.tsx b/src/apps/renderer/components/PasswordInput.tsx similarity index 100% rename from src/renderer/components/PasswordInput.tsx rename to src/apps/renderer/components/PasswordInput.tsx diff --git a/src/renderer/components/Select.tsx b/src/apps/renderer/components/Select.tsx similarity index 100% rename from src/renderer/components/Select.tsx rename to src/apps/renderer/components/Select.tsx diff --git a/src/renderer/components/TextArea.tsx b/src/apps/renderer/components/TextArea.tsx similarity index 100% rename from src/renderer/components/TextArea.tsx rename to src/apps/renderer/components/TextArea.tsx diff --git a/src/renderer/components/TextInput.tsx b/src/apps/renderer/components/TextInput.tsx similarity index 100% rename from src/renderer/components/TextInput.tsx rename to src/apps/renderer/components/TextInput.tsx diff --git a/src/renderer/components/WindowTopBar.tsx b/src/apps/renderer/components/WindowTopBar.tsx similarity index 100% rename from src/renderer/components/WindowTopBar.tsx rename to src/apps/renderer/components/WindowTopBar.tsx diff --git a/src/renderer/context/DeviceContext.tsx b/src/apps/renderer/context/DeviceContext.tsx similarity index 100% rename from src/renderer/context/DeviceContext.tsx rename to src/apps/renderer/context/DeviceContext.tsx diff --git a/src/renderer/context/LocalContext.tsx b/src/apps/renderer/context/LocalContext.tsx similarity index 100% rename from src/renderer/context/LocalContext.tsx rename to src/apps/renderer/context/LocalContext.tsx diff --git a/src/renderer/hooks/BackupFatalErrors.tsx b/src/apps/renderer/hooks/BackupFatalErrors.tsx similarity index 100% rename from src/renderer/hooks/BackupFatalErrors.tsx rename to src/apps/renderer/hooks/BackupFatalErrors.tsx diff --git a/src/renderer/hooks/ClientPlatform.tsx b/src/apps/renderer/hooks/ClientPlatform.tsx similarity index 100% rename from src/renderer/hooks/ClientPlatform.tsx rename to src/apps/renderer/hooks/ClientPlatform.tsx diff --git a/src/renderer/hooks/FatalErrorActions.ts b/src/apps/renderer/hooks/FatalErrorActions.ts similarity index 84% rename from src/renderer/hooks/FatalErrorActions.ts rename to src/apps/renderer/hooks/FatalErrorActions.ts index 58bfdacf5..405c61472 100644 --- a/src/renderer/hooks/FatalErrorActions.ts +++ b/src/apps/renderer/hooks/FatalErrorActions.ts @@ -1,13 +1,11 @@ import { useEffect, useState } from 'react'; import { Process } from '../../shared/types/Process'; -import { backupsErrorActions } from '../actions/backsups-error-actions'; import { syncErrorActions } from '../actions/sync-error-actions'; import { FatalErrorActionMap } from '../actions/types'; const actionsMap: Record = { SYNC: syncErrorActions, - BACKUPS: backupsErrorActions, }; export default function useFatalErrorActions( diff --git a/src/renderer/hooks/GeneralIssues.tsx b/src/apps/renderer/hooks/GeneralIssues.tsx similarity index 88% rename from src/renderer/hooks/GeneralIssues.tsx rename to src/apps/renderer/hooks/GeneralIssues.tsx index 84b1e1cff..986445c6b 100644 --- a/src/renderer/hooks/GeneralIssues.tsx +++ b/src/apps/renderer/hooks/GeneralIssues.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from 'react'; - -import { GeneralIssue } from '../../workers/types'; +import { GeneralIssue } from '../../shared/types'; export default function useGeneralIssues() { const [generalIssues, setGeneralIssues] = useState([]); diff --git a/src/renderer/hooks/ProcessIssues.tsx b/src/apps/renderer/hooks/ProcessIssues.tsx similarity index 88% rename from src/renderer/hooks/ProcessIssues.tsx rename to src/apps/renderer/hooks/ProcessIssues.tsx index 70e4f03c4..581fcacb5 100644 --- a/src/renderer/hooks/ProcessIssues.tsx +++ b/src/apps/renderer/hooks/ProcessIssues.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from 'react'; - -import { ProcessIssue } from '../../workers/types'; +import { ProcessIssue } from '../../shared/types'; export default function useProcessIssues() { const [processIssues, setProcessIssues] = useState([]); diff --git a/src/renderer/hooks/VirtualDriveStatus.tsx b/src/apps/renderer/hooks/VirtualDriveStatus.tsx similarity index 92% rename from src/renderer/hooks/VirtualDriveStatus.tsx rename to src/apps/renderer/hooks/VirtualDriveStatus.tsx index 3a69d5b10..6acd47a5d 100644 --- a/src/renderer/hooks/VirtualDriveStatus.tsx +++ b/src/apps/renderer/hooks/VirtualDriveStatus.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { reportError } from 'renderer/utils/errors'; +import { reportError } from '../utils/errors'; import { VirtualDriveStatus } from '../../shared/types/VirtualDriveStatus'; export default function useVirtualDriveStatus() { diff --git a/src/renderer/hooks/useBackups.tsx b/src/apps/renderer/hooks/useBackups.tsx similarity index 100% rename from src/renderer/hooks/useBackups.tsx rename to src/apps/renderer/hooks/useBackups.tsx diff --git a/src/renderer/hooks/useConfig.tsx b/src/apps/renderer/hooks/useConfig.tsx similarity index 100% rename from src/renderer/hooks/useConfig.tsx rename to src/apps/renderer/hooks/useConfig.tsx diff --git a/src/renderer/hooks/useLanguage.tsx b/src/apps/renderer/hooks/useLanguage.tsx similarity index 100% rename from src/renderer/hooks/useLanguage.tsx rename to src/apps/renderer/hooks/useLanguage.tsx diff --git a/src/renderer/hooks/useOnSyncRunning.tsx b/src/apps/renderer/hooks/useOnSyncRunning.tsx similarity index 77% rename from src/renderer/hooks/useOnSyncRunning.tsx rename to src/apps/renderer/hooks/useOnSyncRunning.tsx index c6c86df56..288d1743b 100644 --- a/src/renderer/hooks/useOnSyncRunning.tsx +++ b/src/apps/renderer/hooks/useOnSyncRunning.tsx @@ -1,4 +1,4 @@ -import { SyncStatus } from 'main/background-processes/sync'; +import { SyncStatus } from '../../../context/desktop/sync/domain/SyncStatus'; import useSyncStatus from './useSyncStatus'; export function useOnSyncRunning(fn: () => void) { diff --git a/src/renderer/hooks/useOnSyncStopped.tsx b/src/apps/renderer/hooks/useOnSyncStopped.tsx similarity index 100% rename from src/renderer/hooks/useOnSyncStopped.tsx rename to src/apps/renderer/hooks/useOnSyncStopped.tsx diff --git a/src/renderer/hooks/useSyncInfoSubscriber.tsx b/src/apps/renderer/hooks/useSyncInfoSubscriber.tsx similarity index 96% rename from src/renderer/hooks/useSyncInfoSubscriber.tsx rename to src/apps/renderer/hooks/useSyncInfoSubscriber.tsx index e1b521dd3..d8b2049ee 100644 --- a/src/renderer/hooks/useSyncInfoSubscriber.tsx +++ b/src/apps/renderer/hooks/useSyncInfoSubscriber.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { ProcessInfoUpdatePayload } from '../../workers/types'; +import { ProcessInfoUpdatePayload } from '../../shared/types'; export function useSyncInfoSubscriber() { const [processInfoUpdatedPayload, setProcessInfoUpdatedPayload] = useState< diff --git a/src/renderer/hooks/useSyncStatus.tsx b/src/apps/renderer/hooks/useSyncStatus.tsx similarity index 93% rename from src/renderer/hooks/useSyncStatus.tsx rename to src/apps/renderer/hooks/useSyncStatus.tsx index 84c90c31f..1775900ee 100644 --- a/src/renderer/hooks/useSyncStatus.tsx +++ b/src/apps/renderer/hooks/useSyncStatus.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from 'react'; - -import { SyncStatus } from '../../main/background-processes/sync'; +import { SyncStatus } from '../../../context/desktop/sync/domain/SyncStatus'; export default function useSyncStatus( onChange?: (curentState: SyncStatus) => void diff --git a/src/renderer/hooks/useSyncStopped.tsx b/src/apps/renderer/hooks/useSyncStopped.tsx similarity index 82% rename from src/renderer/hooks/useSyncStopped.tsx rename to src/apps/renderer/hooks/useSyncStopped.tsx index 98ad00c58..09acb92f4 100644 --- a/src/renderer/hooks/useSyncStopped.tsx +++ b/src/apps/renderer/hooks/useSyncStopped.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from 'react'; - -import { SyncStoppedPayload } from '../../main/background-processes/sync'; +import { SyncStoppedPayload } from '../../../context/desktop/sync/domain/SyncStoppedPayload'; export default function useSyncStopped(): [ SyncStoppedPayload | null, diff --git a/src/renderer/hooks/useUsage.tsx b/src/apps/renderer/hooks/useUsage.tsx similarity index 94% rename from src/renderer/hooks/useUsage.tsx rename to src/apps/renderer/hooks/useUsage.tsx index 233c0a6bb..2ab83a2d8 100644 --- a/src/renderer/hooks/useUsage.tsx +++ b/src/apps/renderer/hooks/useUsage.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Usage } from '../../main/usage/usage'; +import { Usage } from '../../main/usage/Usage'; export default function useUsage() { const [usage, setUsage] = useState(); diff --git a/src/renderer/index.ejs b/src/apps/renderer/index.ejs similarity index 100% rename from src/renderer/index.ejs rename to src/apps/renderer/index.ejs diff --git a/src/renderer/index.tsx b/src/apps/renderer/index.tsx similarity index 100% rename from src/renderer/index.tsx rename to src/apps/renderer/index.tsx diff --git a/src/renderer/localize/i18n.service.ts b/src/apps/renderer/localize/i18n.service.ts similarity index 84% rename from src/renderer/localize/i18n.service.ts rename to src/apps/renderer/localize/i18n.service.ts index 6bb2de5e6..549c1c98a 100644 --- a/src/renderer/localize/i18n.service.ts +++ b/src/apps/renderer/localize/i18n.service.ts @@ -1,14 +1,13 @@ import dayjs from 'dayjs'; import i18next from 'i18next'; import { initReactI18next } from 'react-i18next'; -import { getConfigKey, queryApp } from 'renderer/utils/query'; - import DayJsLocales from '../../shared/Locale/DayJsLocales'; import { DEFAULT_LANGUAGE, - isLanguage, Language, + isLanguage, } from '../../shared/Locale/Language'; +import { getConfigKey } from '../utils/query'; const languageDetection = (callback: (lang: Language | undefined) => void) => { const run = async () => { @@ -20,10 +19,11 @@ const languageDetection = (callback: (lang: Language | undefined) => void) => { return; } - const systemLangs = await queryApp('getPreferredSystemLanguages'); - const parsed = systemLangs.map((l) => l.split('-')[0]); + const systemLangs = await window.electron.getPreferredAppLanguage(); + const parsed = systemLangs.map((l: string) => l.split('-')[0]); - const preferedLanguageAvailable = parsed.find(isLanguage); + const preferedLanguageAvailable = + (parsed.find(isLanguage) as Language) || undefined; const language = preferedLanguageAvailable || DEFAULT_LANGUAGE; diff --git a/src/renderer/localize/locales/en.json b/src/apps/renderer/localize/locales/en.json similarity index 100% rename from src/renderer/localize/locales/en.json rename to src/apps/renderer/localize/locales/en.json diff --git a/src/renderer/localize/locales/es.json b/src/apps/renderer/localize/locales/es.json similarity index 100% rename from src/renderer/localize/locales/es.json rename to src/apps/renderer/localize/locales/es.json diff --git a/src/renderer/localize/locales/fr.json b/src/apps/renderer/localize/locales/fr.json similarity index 100% rename from src/renderer/localize/locales/fr.json rename to src/apps/renderer/localize/locales/fr.json diff --git a/src/renderer/messages/backups/backups-actions-map.ts b/src/apps/renderer/messages/backups/backups-actions-map.ts similarity index 86% rename from src/renderer/messages/backups/backups-actions-map.ts rename to src/apps/renderer/messages/backups/backups-actions-map.ts index f0841532d..54c98dd93 100644 --- a/src/renderer/messages/backups/backups-actions-map.ts +++ b/src/apps/renderer/messages/backups/backups-actions-map.ts @@ -1,4 +1,4 @@ -import { ProcessFatalErrorName } from '../../../workers/types'; +import { ProcessFatalErrorName } from '../../../shared/types'; export type FaltalErrorAction = { name: string; fn: () => void }; diff --git a/src/renderer/messages/backups/backups-fatal-errors.ts b/src/apps/renderer/messages/backups/backups-fatal-errors.ts similarity index 88% rename from src/renderer/messages/backups/backups-fatal-errors.ts rename to src/apps/renderer/messages/backups/backups-fatal-errors.ts index 74789118e..ba0a0e946 100644 --- a/src/renderer/messages/backups/backups-fatal-errors.ts +++ b/src/apps/renderer/messages/backups/backups-fatal-errors.ts @@ -1,4 +1,4 @@ -import { ProcessFatalErrorName } from '../../../workers/types'; +import { ProcessFatalErrorName } from '../../../shared/types'; import processFatalErrors from '../process-fatal-error'; const messages: Partial> = { diff --git a/src/renderer/messages/general-error.ts b/src/apps/renderer/messages/general-error.ts similarity index 88% rename from src/renderer/messages/general-error.ts rename to src/apps/renderer/messages/general-error.ts index 946cba500..d0e98fec8 100644 --- a/src/renderer/messages/general-error.ts +++ b/src/apps/renderer/messages/general-error.ts @@ -1,4 +1,4 @@ -import { GeneralErrorName } from '../../workers/types'; +import { GeneralErrorName } from '../../shared/types'; type GeneralErrorMessages = Record; diff --git a/src/renderer/messages/process-error.ts b/src/apps/renderer/messages/process-error.ts similarity index 95% rename from src/renderer/messages/process-error.ts rename to src/apps/renderer/messages/process-error.ts index d3c0b267e..90b76900b 100644 --- a/src/renderer/messages/process-error.ts +++ b/src/apps/renderer/messages/process-error.ts @@ -1,4 +1,4 @@ -import { ProcessErrorName } from '../../workers/types'; +import { ProcessErrorName } from '../../shared/types'; type ProcessErrorMessages = Record; diff --git a/src/renderer/messages/process-fatal-error.ts b/src/apps/renderer/messages/process-fatal-error.ts similarity index 92% rename from src/renderer/messages/process-fatal-error.ts rename to src/apps/renderer/messages/process-fatal-error.ts index fe23c3349..06b493ec8 100644 --- a/src/renderer/messages/process-fatal-error.ts +++ b/src/apps/renderer/messages/process-fatal-error.ts @@ -1,4 +1,4 @@ -import { ProcessFatalErrorName } from '../../workers/types'; +import { ProcessFatalErrorName } from '../../shared/types'; const messages: Record = { NO_INTERNET: 'issues.error-messages.no-internet', diff --git a/src/renderer/pages/Feedback/index.tsx b/src/apps/renderer/pages/Feedback/index.tsx similarity index 95% rename from src/renderer/pages/Feedback/index.tsx rename to src/apps/renderer/pages/Feedback/index.tsx index 0e918cf8d..45070821f 100644 --- a/src/renderer/pages/Feedback/index.tsx +++ b/src/apps/renderer/pages/Feedback/index.tsx @@ -1,10 +1,10 @@ import { useState } from 'react'; import Button from '../../components/Button'; import { useTranslationContext } from '../../context/LocalContext'; -import { reportError } from 'renderer/utils/errors'; import { ChatsCircle } from 'phosphor-react'; -import WindowTopBar from 'renderer/components/WindowTopBar'; -import TextArea from 'renderer/components/TextArea'; +import WindowTopBar from '../../components/WindowTopBar'; +import TextArea from '../../components/TextArea'; +import { reportError } from '../../utils/errors'; const CHARACTERS_LIMIT = 1000; export default function Feedback() { diff --git a/src/renderer/pages/Login/ErrorBanner.tsx b/src/apps/renderer/pages/Login/ErrorBanner.tsx similarity index 100% rename from src/renderer/pages/Login/ErrorBanner.tsx rename to src/apps/renderer/pages/Login/ErrorBanner.tsx diff --git a/src/renderer/pages/Login/TwoFA.tsx b/src/apps/renderer/pages/Login/TwoFA.tsx similarity index 100% rename from src/renderer/pages/Login/TwoFA.tsx rename to src/apps/renderer/pages/Login/TwoFA.tsx diff --git a/src/renderer/pages/Login/WarningBanner.tsx b/src/apps/renderer/pages/Login/WarningBanner.tsx similarity index 100% rename from src/renderer/pages/Login/WarningBanner.tsx rename to src/apps/renderer/pages/Login/WarningBanner.tsx diff --git a/src/renderer/pages/Login/index.tsx b/src/apps/renderer/pages/Login/index.tsx similarity index 96% rename from src/renderer/pages/Login/index.tsx rename to src/apps/renderer/pages/Login/index.tsx index 4afe0e1cf..f2eef050e 100644 --- a/src/renderer/pages/Login/index.tsx +++ b/src/apps/renderer/pages/Login/index.tsx @@ -1,15 +1,15 @@ import { useEffect, useRef, useState } from 'react'; -import packageJson from '../../../../package.json'; +import packageJson from '../../../../../package.json'; import { useTranslationContext } from '../../context/LocalContext'; import ErrorBanner from './ErrorBanner'; import { accessRequest, hashPassword, loginRequest } from './service'; import TwoFA from './TwoFA'; import { LoginState } from './types'; import WarningBanner from './WarningBanner'; -import TextInput from 'renderer/components/TextInput'; -import PasswordInput from 'renderer/components/PasswordInput'; -import WindowTopBar from 'renderer/components/WindowTopBar'; -import Button from 'renderer/components/Button'; +import Button from '../../components/Button'; +import PasswordInput from '../../components/PasswordInput'; +import TextInput from '../../components/TextInput'; +import WindowTopBar from '../../components/WindowTopBar'; const TOWFA_ERROR_MESSAGE = 'Wrong 2-factor auth code'; diff --git a/src/renderer/pages/Login/service.ts b/src/apps/renderer/pages/Login/service.ts similarity index 97% rename from src/renderer/pages/Login/service.ts rename to src/apps/renderer/pages/Login/service.ts index 4be5d9774..7ea74ab21 100644 --- a/src/renderer/pages/Login/service.ts +++ b/src/apps/renderer/pages/Login/service.ts @@ -1,6 +1,6 @@ import CryptoJS from 'crypto-js'; -import packageConfig from '../../../../package.json'; +import packageConfig from '../../../../../package.json'; import { User } from '../../../main/types'; export function hashPassword(password: string, sKey: string): string { diff --git a/src/renderer/pages/Login/types.ts b/src/apps/renderer/pages/Login/types.ts similarity index 100% rename from src/renderer/pages/Login/types.ts rename to src/apps/renderer/pages/Login/types.ts diff --git a/src/renderer/pages/Migration/config.tsx b/src/apps/renderer/pages/Migration/config.tsx similarity index 99% rename from src/renderer/pages/Migration/config.tsx rename to src/apps/renderer/pages/Migration/config.tsx index 85b346856..f31a68a33 100644 --- a/src/renderer/pages/Migration/config.tsx +++ b/src/apps/renderer/pages/Migration/config.tsx @@ -1,6 +1,4 @@ -import { useTranslationContext } from 'renderer/context/LocalContext'; import { MigrationSlide, UploadSuccessAnimation } from './helpers'; -import Button from 'renderer/components/Button'; import { SideImageAnimation, SideTextAnimation, @@ -18,6 +16,8 @@ import { DeleteOldDriveFolderSlide } from './slides/DeleteOldDriveFolderSlide'; import { AvailableOnlineSlide } from '../Onboarding/slides/AvailableOnlineSlide'; import { ContextMenuSlide } from '../Onboarding/slides/ContextMenuSlide'; import { AvailableOfflineSlide } from '../Onboarding/slides/AvailableOfflineSlide'; +import { useTranslationContext } from '../../context/LocalContext'; +import Button from '../../components/Button'; export const SLIDES: MigrationSlide[] = [ { diff --git a/src/renderer/pages/Migration/helpers.tsx b/src/apps/renderer/pages/Migration/helpers.tsx similarity index 99% rename from src/renderer/pages/Migration/helpers.tsx rename to src/apps/renderer/pages/Migration/helpers.tsx index 4cb8c2663..d4b73270f 100644 --- a/src/renderer/pages/Migration/helpers.tsx +++ b/src/apps/renderer/pages/Migration/helpers.tsx @@ -1,4 +1,4 @@ -import { LocalContextProps } from 'renderer/context/LocalContext'; +import { LocalContextProps } from '../../context/LocalContext'; export type MigrationSlideProps = { onGoNextSlide: () => void; diff --git a/src/renderer/pages/Migration/index.tsx b/src/apps/renderer/pages/Migration/index.tsx similarity index 96% rename from src/renderer/pages/Migration/index.tsx rename to src/apps/renderer/pages/Migration/index.tsx index 2a49a0a41..5afb9e4e7 100644 --- a/src/renderer/pages/Migration/index.tsx +++ b/src/apps/renderer/pages/Migration/index.tsx @@ -1,10 +1,9 @@ import { useMemo, useState } from 'react'; import { SLIDES } from './config'; - -import { useTranslationContext } from 'renderer/context/LocalContext'; import { MigrationSlideProps } from './helpers'; -import { reportError } from 'renderer/utils/errors'; -import useClientPlatform from 'renderer/hooks/ClientPlatform'; +import { useTranslationContext } from '../../context/LocalContext'; +import useClientPlatform from '../../hooks/ClientPlatform'; +import { reportError } from '../../utils/errors'; const totalSlides = SLIDES.length - 3; diff --git a/src/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx b/src/apps/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx similarity index 84% rename from src/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx rename to src/apps/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx index 088420c0c..20f67591f 100644 --- a/src/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx +++ b/src/apps/renderer/pages/Migration/slides/DeleteOldDriveFolderSlide.tsx @@ -1,15 +1,16 @@ import React from 'react'; import { MigrationSlideProps } from '../helpers'; -import { - SideTextAnimation, - getPlatformPhraseTranslationKey, -} from 'renderer/pages/Onboarding/helpers'; +import { SideTextAnimation } from '../../Onboarding/helpers'; export type DeleteOldDriveFolderSlideProps = MigrationSlideProps; export const DeleteOldDriveFolderSlide: React.FC< DeleteOldDriveFolderSlideProps > = (props) => { + function getPlatformPhraseTranslationKey(_platform: string): any { + throw new Error('Function not implemented.'); + } + return (
diff --git a/src/renderer/pages/Migration/slides/MigrationFailedSlide.tsx b/src/apps/renderer/pages/Migration/slides/MigrationFailedSlide.tsx similarity index 92% rename from src/renderer/pages/Migration/slides/MigrationFailedSlide.tsx rename to src/apps/renderer/pages/Migration/slides/MigrationFailedSlide.tsx index 61776a681..993a6b606 100644 --- a/src/renderer/pages/Migration/slides/MigrationFailedSlide.tsx +++ b/src/apps/renderer/pages/Migration/slides/MigrationFailedSlide.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { MigrationSlideProps } from '../helpers'; -import { SideTextAnimation } from 'renderer/pages/Onboarding/helpers'; import { XCircle } from 'phosphor-react'; -import Button from 'renderer/components/Button'; +import { SideTextAnimation } from '../../Onboarding/helpers'; +import Button from '../../../components/Button'; export type MigrationFailedSlideProps = MigrationSlideProps; diff --git a/src/renderer/pages/Onboarding/config.tsx b/src/apps/renderer/pages/Onboarding/config.tsx similarity index 98% rename from src/renderer/pages/Onboarding/config.tsx rename to src/apps/renderer/pages/Onboarding/config.tsx index d03603e97..b5e46a356 100644 --- a/src/renderer/pages/Onboarding/config.tsx +++ b/src/apps/renderer/pages/Onboarding/config.tsx @@ -6,7 +6,6 @@ import { ContextMenuSlide } from './slides/ContextMenuSlide'; import { WelcomeSlide } from './slides/WelcomeSlide'; import { FilesOrganizationSlide } from './slides/FilesOrganizationSlide'; -import { useTranslationContext } from 'renderer/context/LocalContext'; import { // BackupsSVG, OnboardingSlide, @@ -16,10 +15,11 @@ import { getOfflineImageSvg, getOnlineImageSvg, } from './helpers'; -import Button from 'renderer/components/Button'; import ContextMenuSvg from '../../assets/onboarding/context-menu.svg'; import { OnboardingCompletedSlide } from './slides/OnboardingCompletedSlide'; +import Button from '../../components/Button'; +import { useTranslationContext } from '../../context/LocalContext'; export const SLIDES: OnboardingSlide[] = [ { name: 'Welcome Slide', diff --git a/src/renderer/pages/Onboarding/helpers.tsx b/src/apps/renderer/pages/Onboarding/helpers.tsx similarity index 99% rename from src/renderer/pages/Onboarding/helpers.tsx rename to src/apps/renderer/pages/Onboarding/helpers.tsx index 3c0c95623..f5860eb98 100644 --- a/src/renderer/pages/Onboarding/helpers.tsx +++ b/src/apps/renderer/pages/Onboarding/helpers.tsx @@ -13,7 +13,7 @@ import AvailableOfflineImageFrench from '../../assets/onboarding/folder-with-ove import MacOSFinderImage from '../../assets/onboarding/finder/macos.svg'; import LinuxFinderImage from '../../assets/onboarding/finder/linux.svg'; import WindowsFinderImage from '../../assets/onboarding/finder/windows.svg'; -import { BackupFolder } from 'renderer/components/Backups/BackupsFoldersSelector'; +import { BackupFolder } from '../../components/Backups/BackupsFoldersSelector'; export type OnboardingSlideProps = { onGoNextSlide: () => void; diff --git a/src/renderer/pages/Onboarding/index.tsx b/src/apps/renderer/pages/Onboarding/index.tsx similarity index 95% rename from src/renderer/pages/Onboarding/index.tsx rename to src/apps/renderer/pages/Onboarding/index.tsx index 4f77355a4..6b2d50918 100644 --- a/src/renderer/pages/Onboarding/index.tsx +++ b/src/apps/renderer/pages/Onboarding/index.tsx @@ -3,9 +3,8 @@ import { SLIDES } from './config'; import { BackupFolder, BackupsFoldersSelector, -} from 'renderer/components/Backups/BackupsFoldersSelector'; -import { reportError } from 'renderer/utils/errors'; -import useClientPlatform from 'renderer/hooks/ClientPlatform'; +} from '../../components/Backups/BackupsFoldersSelector'; +import useClientPlatform from '../../hooks/ClientPlatform'; // Slide 1 is welcome slide, last slide is summary, doesn't count const totalSlides = SLIDES.length - 2; diff --git a/src/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx similarity index 91% rename from src/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx index 10c189e80..edab94808 100644 --- a/src/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/AvailableOfflineSlide.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useTranslationContext } from 'renderer/context/LocalContext'; +import { useTranslationContext } from '../../../context/LocalContext'; export const AvailableOfflineSlide: React.FC = () => { const { translate } = useTranslationContext(); diff --git a/src/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx similarity index 91% rename from src/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx index aa1eee8d7..7d884fc16 100644 --- a/src/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/AvailableOnlineSlide.tsx @@ -1,6 +1,5 @@ import React from 'react'; - -import { useTranslationContext } from 'renderer/context/LocalContext'; +import { useTranslationContext } from '../../../context/LocalContext'; export const AvailableOnlineSlide: React.FC = () => { const { translate } = useTranslationContext(); diff --git a/src/renderer/pages/Onboarding/slides/BackupsSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/BackupsSlide.tsx similarity index 92% rename from src/renderer/pages/Onboarding/slides/BackupsSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/BackupsSlide.tsx index 6e0b4fc1e..c3e90ceba 100644 --- a/src/renderer/pages/Onboarding/slides/BackupsSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/BackupsSlide.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { OnboardingSlideProps } from '../helpers'; -import { useTranslationContext } from 'renderer/context/LocalContext'; +import { useTranslationContext } from '../../../context/LocalContext'; export type BackupsSlideProps = OnboardingSlideProps; diff --git a/src/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx similarity index 93% rename from src/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx index 82e3651d1..e5ca770e0 100644 --- a/src/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/ContextMenuSlide.tsx @@ -1,6 +1,5 @@ import React from 'react'; - -import { useTranslationContext } from 'renderer/context/LocalContext'; +import { useTranslationContext } from '../../../context/LocalContext'; export const ContextMenuSlide: React.FC = () => { const { translate } = useTranslationContext(); diff --git a/src/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx similarity index 92% rename from src/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx index 27ae0547a..5b957d94d 100644 --- a/src/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/FilesOrganizationSlide.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { useTranslationContext } from 'renderer/context/LocalContext'; import { OnboardingSlideProps, getPlatformName } from '../helpers'; +import { useTranslationContext } from '../../../context/LocalContext'; export type FilesOrganizationSlideProps = OnboardingSlideProps; diff --git a/src/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx similarity index 97% rename from src/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx index 6a990c3d1..c4cf2e0fb 100644 --- a/src/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/OnboardingCompletedSlide.tsx @@ -1,10 +1,10 @@ import { CheckCircle } from 'phosphor-react'; import React from 'react'; -import { useTranslationContext } from 'renderer/context/LocalContext'; import { OnboardingSlideProps, getPlatformPhraseTranslationKey, } from '../helpers'; +import { useTranslationContext } from '../../../context/LocalContext'; export type OnboardingCompletedSlideProps = OnboardingSlideProps; diff --git a/src/renderer/pages/Onboarding/slides/WelcomeSlide.tsx b/src/apps/renderer/pages/Onboarding/slides/WelcomeSlide.tsx similarity index 91% rename from src/renderer/pages/Onboarding/slides/WelcomeSlide.tsx rename to src/apps/renderer/pages/Onboarding/slides/WelcomeSlide.tsx index 949c9818e..25bfbacc9 100644 --- a/src/renderer/pages/Onboarding/slides/WelcomeSlide.tsx +++ b/src/apps/renderer/pages/Onboarding/slides/WelcomeSlide.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { useTranslationContext } from 'renderer/context/LocalContext'; import { OnboardingSlideProps } from '../helpers'; +import { useTranslationContext } from '../../../context/LocalContext'; export type WelcomeSlideProps = OnboardingSlideProps; diff --git a/src/renderer/pages/ProcessIssues/List.tsx b/src/apps/renderer/pages/ProcessIssues/List.tsx similarity index 83% rename from src/renderer/pages/ProcessIssues/List.tsx rename to src/apps/renderer/pages/ProcessIssues/List.tsx index d037a3b2b..a6887aade 100644 --- a/src/renderer/pages/ProcessIssues/List.tsx +++ b/src/apps/renderer/pages/ProcessIssues/List.tsx @@ -1,46 +1,31 @@ import { CaretDown } from '@phosphor-icons/react'; import { AnimatePresence, motion } from 'framer-motion'; import { useState } from 'react'; -import { useTranslationContext } from 'renderer/context/LocalContext'; - -import { BackupFatalError } from '../../../main/background-processes/types/BackupFatalError'; -import { - GeneralErrorName, - GeneralIssue, - ProcessErrorName, - ProcessIssue, -} from '../../../workers/types'; -import { Action } from '../../actions/types'; import FileIcon from '../../assets/file.svg'; import Spinner from '../../assets/spinner.svg'; import WarnIcon from '../../assets/warn.svg'; -import useFatalErrorActions from '../../hooks/FatalErrorActions'; import { generalErrors } from '../../messages/general-error'; import { shortMessages } from '../../messages/process-error'; import { getBaseName } from '../../utils/path'; -import { FatalError } from '../../components/Backups/FatalError'; +import { + GeneralIssue, + ProcessIssue, + ProcessErrorName, + GeneralErrorName, +} from '../../../shared/types'; +import { useTranslationContext } from '../../context/LocalContext'; export default function ProcessIssuesList({ selectedTab, processIssues, - backupFatalErrors, - showBackupFatalErrors, onClickOnErrorInfo, generalIssues, }: { generalIssues: GeneralIssue[]; processIssues: ProcessIssue[]; - backupFatalErrors: BackupFatalError[]; - showBackupFatalErrors: boolean; selectedTab: 'SYNC' | 'BACKUPS' | 'GENERAL'; onClickOnErrorInfo: (errorClicked: Pick) => void; }) { - const { translate } = useTranslationContext(); - const [isLoading, setIsLoading] = useState(false); - const fatalErrorActionMap = useFatalErrorActions( - showBackupFatalErrors ? 'BACKUPS' : 'SYNC' - ); - const [selectedErrorName, setSelectedErrorName] = useState< ProcessErrorName | GeneralErrorName | null >(null); @@ -90,21 +75,12 @@ export default function ProcessIssuesList({ )); }; - const actionWrapper = - (action: Action) => async (error: BackupFatalError | undefined) => { - setIsLoading(true); - await action.func(error); - setIsLoading(false); - }; - const issuesIsEmpty = () => { switch (selectedTab) { case 'GENERAL': return generalIssues.length === 0; case 'SYNC': return processIssues.length === 0; - case 'BACKUPS': - return backupFatalErrors.length === 0; default: return true; } @@ -112,23 +88,10 @@ export default function ProcessIssuesList({ return (