backupdrill 2.0.0 → 2.1.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.
@@ -11,7 +11,7 @@
11
11
  import { spawn } from "node:child_process";
12
12
  import { Client } from "pg";
13
13
  import { resolvePgRestoreBin } from "./pgbin.js";
14
- import { pgConnectOptions } from "./supabase-ca.js";
14
+ import { pgConnectOptions, dumpUrlFor } from "./supabase-ca.js";
15
15
  /** 主机名规范化:剥掉合法的 DNS 根点(db.x.supabase.co. ≡ db.x.supabase.co)。
16
16
  * 身份比较不规范化 = 一个尾点就能绕过同源阻断(supabase-ca 对同类早有钉子)。 */
17
17
  export function normalizeHost(hostname) {
@@ -254,7 +254,10 @@ export function assertNoHostOverride(connString) {
254
254
  }
255
255
  export async function restoreDatabaseArtifact(opts) {
256
256
  const bin = resolvePgRestoreBin();
257
- const { url, env } = credentialSafeDbArgs(opts.connString);
257
+ // TLS 全链路 verify-full(创始人承诺项):pg_restore 与 pg_dump 同一改写——
258
+ // Supabase 主机强制 verify-full + 打包根 CA(libpq 的 require 不验证书,
259
+ // 中间人可拿到连接与数据);沙箱/外部主机原样透传。先改写 SSL 再拆密码。
260
+ const { url, env } = credentialSafeDbArgs(dumpUrlFor(opts.connString));
258
261
  const common = ["--no-owner", "--no-privileges", "--dbname", url, opts.dumpPath];
259
262
  const first = await spawnPgRestore(bin, ["--section=pre-data", "--section=data", ...common], env);
260
263
  const preData = finalizePass(first.code, first.stderr, classifyBlocks(first.stderr, SCHEMA_EXISTS_ERROR));
package/dist/restore.d.ts CHANGED
@@ -74,6 +74,12 @@ export declare function runRestore(config: BackupConfig, opts: {
74
74
  dryRun?: boolean;
75
75
  /** 源身份不可考(v1 快照 + 无配置)时的显式风险认知——没有它一律拒绝写入 */
76
76
  acknowledgeUnverifiedSource?: boolean;
77
+ /**
78
+ * 跳过 Storage 阶段(既不回传也不本地下载)。用于把恢复拆成可独立重跑的两段
79
+ * (hosted 检查点重试):DB 阶段传此=true 只恢复库;Storage 阶段单独用
80
+ * targetSupabaseUrl 跑。不影响 CLI 默认行为。
81
+ */
82
+ skipStorage?: boolean;
77
83
  snapshot?: string;
78
84
  storageDir?: string;
79
85
  }): Promise<RestoreResult>;
package/dist/restore.js CHANGED
@@ -486,7 +486,10 @@ export async function runRestore(config, opts) {
486
486
  log.warn("No database target (--database + BACKUPDRILL_TARGET_DATABASE_URL); skipping database restore.");
487
487
  }
488
488
  // 2a. Storage → 目标项目回传(P0-D:给了目标 Storage 凭据时)
489
- if (manifest.storage && storageTarget) {
489
+ if (opts.skipStorage) {
490
+ // DB-only 阶段(hosted 检查点重试):既不回传也不本地下载,Storage 单独一段跑
491
+ }
492
+ else if (manifest.storage && storageTarget) {
490
493
  const summary = await restoreStorage({ s3, bucket: config.storage.bucket, base }, storageTarget, manifest);
491
494
  result.storageSummary = summary;
492
495
  result.storageFilesWritten = summary.filesUploaded;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backupdrill",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Open-source CLI to back up a Supabase project — Postgres database and Storage files — to your own S3/R2/B2 bucket, with a checksummed manifest.",
5
5
  "type": "module",
6
6
  "bin": {