@floomhq/floom 1.0.52 → 1.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sync.js +55 -1
- package/package.json +1 -1
package/dist/sync.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { constants } from "node:fs";
|
|
2
|
-
import { lstat, mkdir, open } from "node:fs/promises";
|
|
2
|
+
import { lstat, mkdir, open, rm, rmdir } from "node:fs/promises";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import ora from "ora";
|
|
@@ -224,6 +224,40 @@ async function overwriteTrackedFile(root, target, body, expectedHash) {
|
|
|
224
224
|
await parent.close();
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
+
async function deleteSyncedFile(root, target, expectedHash) {
|
|
228
|
+
const state = await localState(target);
|
|
229
|
+
if (state.kind === "missing")
|
|
230
|
+
return;
|
|
231
|
+
if (state.kind === "conflict")
|
|
232
|
+
throw conflictError(state.reason, "EEXIST");
|
|
233
|
+
if (state.hash !== expectedHash)
|
|
234
|
+
throw conflictError("local file changed since the last Floom sync", "EEXIST");
|
|
235
|
+
await rm(target);
|
|
236
|
+
await pruneEmptyParents(root, dirname(target));
|
|
237
|
+
}
|
|
238
|
+
async function pruneEmptyParents(root, startDir) {
|
|
239
|
+
const resolvedRoot = resolve(root);
|
|
240
|
+
let current = resolve(startDir);
|
|
241
|
+
for (;;) {
|
|
242
|
+
const relativeCurrent = relative(resolvedRoot, current);
|
|
243
|
+
if (!relativeCurrent || relativeCurrent === ".." || relativeCurrent.startsWith(`..${sep}`) || isAbsolute(relativeCurrent))
|
|
244
|
+
return;
|
|
245
|
+
try {
|
|
246
|
+
await rmdir(current);
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
const code = err.code;
|
|
250
|
+
if (code === "ENOENT") {
|
|
251
|
+
current = dirname(current);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (code === "ENOTEMPTY" || code === "EEXIST" || code === "ENOTDIR")
|
|
255
|
+
return;
|
|
256
|
+
throw err;
|
|
257
|
+
}
|
|
258
|
+
current = dirname(current);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
227
261
|
async function ensureSafeParentDirectory(root, target) {
|
|
228
262
|
const resolvedRoot = resolve(root);
|
|
229
263
|
const resolvedParent = resolve(dirname(target));
|
|
@@ -446,6 +480,26 @@ export async function sync(opts = {}) {
|
|
|
446
480
|
noteConflict(target, "local file changed since the last Floom sync");
|
|
447
481
|
continue;
|
|
448
482
|
}
|
|
483
|
+
try {
|
|
484
|
+
await deleteSyncedFile(root, target, entry.hash);
|
|
485
|
+
}
|
|
486
|
+
catch (err) {
|
|
487
|
+
const code = err.code;
|
|
488
|
+
if (code === "ENOENT") {
|
|
489
|
+
unmarkSynced(manifest, key);
|
|
490
|
+
manifestChanged = true;
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
if (code === "ELOOP") {
|
|
494
|
+
noteManifestConflict(key, "path contains a symbolic link");
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
if (code === "ENOTDIR" || code === "EISDIR" || code === "EEXIST") {
|
|
498
|
+
noteManifestConflict(key, err instanceof Error ? err.message : "local file changed since the last Floom sync");
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
throw err;
|
|
502
|
+
}
|
|
449
503
|
unmarkSynced(manifest, key);
|
|
450
504
|
manifestChanged = true;
|
|
451
505
|
}
|