backupdrill 1.0.0 → 2.0.0
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/README.md +34 -7
- package/dist/backup.js +47 -0
- package/dist/drill.d.ts +8 -5
- package/dist/drill.js +27 -96
- package/dist/index.js +100 -20
- package/dist/lib.d.ts +1 -1
- package/dist/manifest.d.ts +32 -1
- package/dist/manifest.js +157 -3
- package/dist/recovery-doc.d.ts +11 -0
- package/dist/recovery-doc.js +123 -0
- package/dist/restore-engine.d.ts +80 -0
- package/dist/restore-engine.js +267 -0
- package/dist/restore.d.ts +65 -2
- package/dist/restore.js +515 -23
- package/dist/storage-catalog.d.ts +19 -0
- package/dist/storage-catalog.js +50 -0
- package/dist/storage-restore.d.ts +79 -0
- package/dist/storage-restore.js +634 -0
- package/dist/storage.d.ts +16 -1
- package/dist/storage.js +33 -2
- package/package.json +1 -1
package/dist/storage.js
CHANGED
|
@@ -37,6 +37,30 @@ async function* listObjects(client, bucket) {
|
|
|
37
37
|
token = res.IsTruncated ? res.NextContinuationToken : undefined;
|
|
38
38
|
} while (token);
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* 从 GetObject 响应提取文件的可恢复元数据。Supabase 的 S3 handler 把这些头直接
|
|
42
|
+
* 从 storage.objects.metadata / user_metadata 取出(content-type、cache-control、
|
|
43
|
+
* x-amz-meta-*,源码实证 2026-07-24)——所以这份元数据与刚流过的字节**原子一致**,
|
|
44
|
+
* 不存在"拷完再查 DB"的并发漂移窗口,也不依赖 DB 上 storage schema 的读权限。
|
|
45
|
+
* 缺席的头不落字段(= 源端未设置/未提供),不猜测。
|
|
46
|
+
*/
|
|
47
|
+
export function fileMetadataFromS3(got) {
|
|
48
|
+
const meta = {};
|
|
49
|
+
if (got.ContentType)
|
|
50
|
+
meta.contentType = got.ContentType;
|
|
51
|
+
if (got.CacheControl)
|
|
52
|
+
meta.cacheControl = got.CacheControl;
|
|
53
|
+
if (got.ContentEncoding)
|
|
54
|
+
meta.contentEncoding = got.ContentEncoding;
|
|
55
|
+
// MissingMeta > 0 = 服务端明确声明有元数据条目没能放进 x-amz-meta 头(非法头名等)。
|
|
56
|
+
// 记一份自知残缺的 metadata 违反"未捕获就不写"原则 → 整个字段省略,如实缺席。
|
|
57
|
+
if (got.Metadata && Object.keys(got.Metadata).length && !(got.MissingMeta && got.MissingMeta > 0)) {
|
|
58
|
+
meta.metadata = got.Metadata;
|
|
59
|
+
}
|
|
60
|
+
if (got.LastModified)
|
|
61
|
+
meta.lastModified = got.LastModified.toISOString();
|
|
62
|
+
return meta;
|
|
63
|
+
}
|
|
40
64
|
/**
|
|
41
65
|
* 仅列举、不下载 —— 用于接入时的容量/egress 估算,几乎不产生 egress。
|
|
42
66
|
*/
|
|
@@ -95,10 +119,17 @@ export async function syncStorage(cfg, target) {
|
|
|
95
119
|
await upload.abort().catch(() => { });
|
|
96
120
|
throw error;
|
|
97
121
|
}
|
|
98
|
-
files.push({
|
|
122
|
+
files.push({
|
|
123
|
+
bucket,
|
|
124
|
+
key: obj.key,
|
|
125
|
+
bytes,
|
|
126
|
+
sha256: hash.digest("hex"),
|
|
127
|
+
...fileMetadataFromS3(got),
|
|
128
|
+
});
|
|
99
129
|
totalBytes += bytes;
|
|
100
130
|
}
|
|
101
131
|
log.step(` ${bucket}: ${files.filter((f) => f.bucket === bucket).length} files`);
|
|
102
132
|
}
|
|
103
|
-
|
|
133
|
+
// buckets 含空 bucket(files 推不出来)——manifest v2 的 bucket 属性采集要按它查
|
|
134
|
+
return { fileCount: files.length, totalBytes, files, buckets };
|
|
104
135
|
}
|
package/package.json
CHANGED