very basic synthesizedFolder

This commit is contained in:
fyears 2024-03-30 03:30:18 +08:00
parent c37bf6aedd
commit 791c0e8df6
4 changed files with 67 additions and 6 deletions

View File

@ -204,6 +204,7 @@ export interface Entity {
sizeRaw: number;
hash?: string;
etag?: string;
synthesizedFolder?: boolean;
}
export interface UploadedType {

View File

@ -239,7 +239,8 @@ export class RemoteClient {
deleteFromRemote = async (
fileOrFolderPath: string,
cipher: Cipher,
remoteEncryptedKey: string = ""
remoteEncryptedKey: string = "",
synthesizedFolder: boolean = false
) => {
if (this.serviceType === "s3") {
return await s3.deleteFromRemote(
@ -247,7 +248,8 @@ export class RemoteClient {
this.s3Config!,
fileOrFolderPath,
cipher,
remoteEncryptedKey
remoteEncryptedKey,
synthesizedFolder
);
} else if (this.serviceType === "webdav") {
return await webdav.deleteFromRemote(

View File

@ -250,6 +250,7 @@ const fromS3ObjectToEntity = (
mtimeCli: mtimeCli,
sizeRaw: x.Size!,
etag: x.ETag,
synthesizedFolder: false,
};
return r;
};
@ -599,7 +600,10 @@ export const listAllFromRemote = async (
s3Client: S3Client,
s3Config: S3Config
) => {
return await listFromRemoteRaw(s3Client, s3Config, s3Config.remotePrefix);
const res = (
await listFromRemoteRaw(s3Client, s3Config, s3Config.remotePrefix)
).filter((x) => x.keyRaw !== "" && x.keyRaw !== "/");
return res;
};
/**
@ -715,11 +719,15 @@ export const deleteFromRemote = async (
s3Config: S3Config,
fileOrFolderPath: string,
cipher: Cipher,
remoteEncryptedKey: string = ""
remoteEncryptedKey: string = "",
synthesizedFolder: boolean = false
) => {
if (fileOrFolderPath === "/") {
return;
}
if (synthesizedFolder) {
return;
}
let remoteFileName = fileOrFolderPath;
if (!cipher.isPasswordEmpty()) {
remoteFileName = remoteEncryptedKey;

View File

@ -18,6 +18,7 @@ import {
isVaildText,
atWhichLevel,
mkdirpInVault,
getFolderLevels,
} from "./misc";
import {
DEFAULT_FILE_NAME_FOR_METADATAONREMOTE,
@ -326,7 +327,10 @@ export const ensembleMixedEnties = async (
): Promise<SyncPlanType> => {
const finalMappings: SyncPlanType = {};
const synthFolders: Record<string, Entity> = {};
// remote has to be first
// we also have to synthesize folders here
for (const remote of remoteEntityList) {
const remoteCopied = ensureMTimeOfRemoteEntityValid(
await decryptRemoteEntityInplace(
@ -352,6 +356,42 @@ export const ensembleMixedEnties = async (
key: key,
remote: remoteCopied,
};
for (const f of getFolderLevels(key, true)) {
if (finalMappings.hasOwnProperty(f)) {
delete synthFolders[f];
continue;
}
if (
!synthFolders.hasOwnProperty(f) ||
remoteCopied.mtimeSvr! >= synthFolders[f].mtimeSvr!
) {
synthFolders[f] = {
key: f,
keyRaw: `<synth: ${f}>`,
keyEnc: `<enc synth: ${f}>`,
size: 0,
sizeRaw: 0,
sizeEnc: 0,
mtimeSvr: remoteCopied.mtimeSvr,
mtimeSvrFmt: remoteCopied.mtimeSvrFmt,
mtimeCli: remoteCopied.mtimeCli,
mtimeCliFmt: remoteCopied.mtimeCliFmt,
synthesizedFolder: true,
};
}
}
}
console.debug(`synthFolders:`);
console.debug(synthFolders);
// special: add synth folders
for (const key of Object.keys(synthFolders)) {
finalMappings[key] = {
key: key,
remote: synthFolders[key],
};
}
if (Object.keys(finalMappings).length === 0 || localEntityList.length === 0) {
@ -1074,7 +1114,12 @@ const dispatchOperationToActualV3 = async (
);
} else if (r.decision === "local_is_deleted_thus_also_delete_remote") {
// local is deleted, we need to delete remote now
await client.deleteFromRemote(r.key, cipher, r.remote!.keyEnc);
await client.deleteFromRemote(
r.key,
cipher,
r.remote!.keyEnc,
r.remote!.synthesizedFolder
);
await clearPrevSyncRecordByVaultAndProfile(
db,
vaultRandomID,
@ -1128,7 +1173,12 @@ const dispatchOperationToActualV3 = async (
r.decision === "folder_to_be_deleted_on_both" ||
r.decision === "folder_to_be_deleted_on_remote"
) {
await client.deleteFromRemote(r.key, cipher, r.remote!.keyEnc);
await client.deleteFromRemote(
r.key,
cipher,
r.remote!.keyEnc,
r.remote!.synthesizedFolder
);
}
await clearPrevSyncRecordByVaultAndProfile(
db,