very basic synthesizedFolder
This commit is contained in:
parent
c37bf6aedd
commit
791c0e8df6
@ -204,6 +204,7 @@ export interface Entity {
|
||||
sizeRaw: number;
|
||||
hash?: string;
|
||||
etag?: string;
|
||||
synthesizedFolder?: boolean;
|
||||
}
|
||||
|
||||
export interface UploadedType {
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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;
|
||||
|
||||
54
src/sync.ts
54
src/sync.ts
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user