{"version":3,"sources":["../../../src/storage/providers/r2.ts"],"sourcesContent":["import { hmac } from \"@noble/hashes/hmac\";\nimport { sha256 } from \"@noble/hashes/sha2\";\n\nimport {\n  StorageError,\n  type StorageProvider,\n  type StorageUploadResult,\n  type StorageFile,\n  type StorageListOptions,\n  type StorageProviderConfig,\n} from \"../index\";\n\n/**\n * Configuration for {@link R2Storage}.\n *\n * @category Storage\n */\nexport interface R2Config {\n  /** Cloudflare account ID. Used to derive the S3 endpoint when `endpoint` is not given. */\n  accountId?: string;\n  /**\n   * Full S3 endpoint URL. Overrides `accountId`.\n   *\n   * Defaults to `https://{accountId}.r2.cloudflarestorage.com`.\n   */\n  endpoint?: string;\n  /** R2 access key ID. */\n  accessKeyId: string;\n  /** R2 secret access key. */\n  secretAccessKey: string;\n  /** Bucket name. */\n  bucket: string;\n  /**\n   * Public URL prefix used when constructing the URL returned by {@link R2Storage.upload}.\n   *\n   * If unset, defaults to `https://{bucket}.{accountId}.r2.dev` (R2's default public hostname).\n   * Set this to a custom domain bound to the bucket if you have one.\n   */\n  publicUrl?: string;\n  /**\n   * S3 region. R2 expects `auto`; consumers can override for compatibility with other\n   * S3-compatible stores reachable through the same code path.\n   */\n  region?: string;\n}\n\ninterface SignedRequest {\n  url: string;\n  headers: Record<string, string>;\n}\n\nconst SERVICE = \"s3\";\nconst DEFAULT_REGION = \"auto\";\n\n/**\n * Cloudflare R2 storage provider.\n *\n * @remarks\n * Uses R2's S3-compatible API with SigV4 signed `fetch` requests, so the same\n * implementation runs in browsers, Node.js, and Workers without pulling in\n * `@aws-sdk/client-s3`. Treats blobs as opaque - encryption, access control,\n * and per-tenant prefixing are out of scope and live in higher layers.\n *\n * The SDK exposes R2 as the recommended default backend. Other providers\n * (Pinata, IPFS, Google Drive, Dropbox, CallbackStorage) remain available for\n * teams that need IPFS semantics or user-owned storage.\n *\n * @category Storage\n *\n * @example\n * ```typescript\n * import { R2Storage, StorageManager } from \"@opendatalabs/vana-sdk/node\";\n *\n * const storage = new StorageManager();\n * storage.register(\n *   \"r2\",\n *   new R2Storage({\n *     accountId: process.env.R2_ACCOUNT_ID!,\n *     accessKeyId: process.env.R2_ACCESS_KEY_ID!,\n *     secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,\n *     bucket: process.env.R2_BUCKET!,\n *     publicUrl: \"https://files.example.com\",\n *   }),\n *   true,\n * );\n *\n * const result = await storage.upload(myBlob, \"report.json\");\n * console.log(result.url);\n * ```\n */\nexport class R2Storage implements StorageProvider {\n  private readonly endpoint: string;\n  private readonly publicUrl: string;\n  private readonly region: string;\n  private readonly bucket: string;\n\n  constructor(private readonly config: R2Config) {\n    if (!config.accessKeyId) {\n      throw new StorageError(\n        \"R2 accessKeyId is required\",\n        \"MISSING_ACCESS_KEY\",\n        \"r2\",\n      );\n    }\n    if (!config.secretAccessKey) {\n      throw new StorageError(\n        \"R2 secretAccessKey is required\",\n        \"MISSING_SECRET_KEY\",\n        \"r2\",\n      );\n    }\n    if (!config.bucket) {\n      throw new StorageError(\"R2 bucket is required\", \"MISSING_BUCKET\", \"r2\");\n    }\n    if (!config.endpoint && !config.accountId) {\n      throw new StorageError(\n        \"R2 endpoint or accountId is required\",\n        \"MISSING_ENDPOINT\",\n        \"r2\",\n      );\n    }\n    if (!config.publicUrl && !config.accountId) {\n      throw new StorageError(\n        \"R2 publicUrl is required when accountId is not provided\",\n        \"MISSING_PUBLIC_URL\",\n        \"r2\",\n      );\n    }\n\n    this.bucket = config.bucket;\n    this.region = config.region ?? DEFAULT_REGION;\n    this.endpoint = (\n      config.endpoint ?? `https://${config.accountId}.r2.cloudflarestorage.com`\n    ).replace(/\\/$/, \"\");\n    this.publicUrl = (\n      config.publicUrl ?? `https://${config.bucket}.${config.accountId}.r2.dev`\n    ).replace(/\\/$/, \"\");\n  }\n\n  async upload(file: Blob, filename?: string): Promise<StorageUploadResult> {\n    const key = filename ?? `vana-${Date.now()}-${randomSuffix()}.dat`;\n    const body = new Uint8Array(await file.arrayBuffer());\n    const contentType =\n      file.type !== \"\" ? file.type : \"application/octet-stream\";\n\n    try {\n      const signed = await this.signRequest({\n        method: \"PUT\",\n        path: `/${this.bucket}/${encodePath(key)}`,\n        body,\n        extraHeaders: { \"content-type\": contentType },\n      });\n\n      const response = await fetch(signed.url, {\n        method: \"PUT\",\n        headers: signed.headers,\n        body,\n      });\n\n      if (!response.ok) {\n        throw new StorageError(\n          `R2 upload failed: ${response.status} ${response.statusText} - ${await safeText(response)}`,\n          \"UPLOAD_FAILED\",\n          \"r2\",\n        );\n      }\n\n      return {\n        url: `${this.publicUrl}/${encodePath(key)}`,\n        size: file.size,\n        contentType,\n      };\n    } catch (error) {\n      throw wrapError(error, \"UPLOAD_ERROR\", \"r2\");\n    }\n  }\n\n  async download(url: string): Promise<Blob> {\n    const key = this.extractKey(url);\n    if (!key) {\n      throw new StorageError(\n        `Could not extract object key from URL: ${url}`,\n        \"INVALID_URL\",\n        \"r2\",\n      );\n    }\n\n    try {\n      const signed = await this.signRequest({\n        method: \"GET\",\n        path: `/${this.bucket}/${encodePath(key)}`,\n      });\n\n      const response = await fetch(signed.url, {\n        method: \"GET\",\n        headers: signed.headers,\n      });\n\n      if (!response.ok) {\n        throw new StorageError(\n          `R2 download failed: ${response.status} ${response.statusText}`,\n          \"DOWNLOAD_FAILED\",\n          \"r2\",\n        );\n      }\n\n      return await response.blob();\n    } catch (error) {\n      throw wrapError(error, \"DOWNLOAD_ERROR\", \"r2\");\n    }\n  }\n\n  async list(options?: StorageListOptions): Promise<StorageFile[]> {\n    try {\n      const params = new URLSearchParams({ \"list-type\": \"2\" });\n      if (options?.namePattern) {\n        params.set(\"prefix\", options.namePattern);\n      }\n      if (options?.limit !== undefined) {\n        params.set(\"max-keys\", String(options.limit));\n      }\n      if (options?.offset !== undefined) {\n        params.set(\"continuation-token\", String(options.offset));\n      }\n\n      const signed = await this.signRequest({\n        method: \"GET\",\n        path: `/${this.bucket}`,\n        query: params,\n      });\n\n      const response = await fetch(signed.url, {\n        method: \"GET\",\n        headers: signed.headers,\n      });\n\n      if (!response.ok) {\n        throw new StorageError(\n          `R2 list failed: ${response.status} ${response.statusText}`,\n          \"LIST_FAILED\",\n          \"r2\",\n        );\n      }\n\n      const xml = await response.text();\n      return parseListObjects(xml).map((obj) => ({\n        id: obj.key,\n        name: obj.key,\n        url: `${this.publicUrl}/${encodePath(obj.key)}`,\n        size: obj.size,\n        contentType: \"application/octet-stream\",\n        createdAt: obj.lastModified,\n      }));\n    } catch (error) {\n      throw wrapError(error, \"LIST_ERROR\", \"r2\");\n    }\n  }\n\n  async delete(url: string): Promise<boolean> {\n    const key = this.extractKey(url);\n    if (!key) {\n      throw new StorageError(\n        `Could not extract object key from URL: ${url}`,\n        \"INVALID_URL\",\n        \"r2\",\n      );\n    }\n\n    try {\n      const signed = await this.signRequest({\n        method: \"DELETE\",\n        path: `/${this.bucket}/${encodePath(key)}`,\n      });\n\n      const response = await fetch(signed.url, {\n        method: \"DELETE\",\n        headers: signed.headers,\n      });\n\n      if (!response.ok && response.status !== 204) {\n        throw new StorageError(\n          `R2 delete failed: ${response.status} ${response.statusText}`,\n          \"DELETE_FAILED\",\n          \"r2\",\n        );\n      }\n\n      return true;\n    } catch (error) {\n      throw wrapError(error, \"DELETE_ERROR\", \"r2\");\n    }\n  }\n\n  getConfig(): StorageProviderConfig {\n    return {\n      name: \"Cloudflare R2\",\n      type: \"r2\",\n      requiresAuth: true,\n      features: {\n        upload: true,\n        download: true,\n        list: true,\n        delete: true,\n      },\n    };\n  }\n\n  /**\n   * Extract the object key from a URL. Accepts public URLs minted by `upload()`\n   * as well as raw keys for callers that already track them out-of-band.\n   *\n   * @internal\n   */\n  private extractKey(urlOrKey: string): string | null {\n    if (urlOrKey.startsWith(this.publicUrl + \"/\")) {\n      return decodeURIComponent(urlOrKey.slice(this.publicUrl.length + 1));\n    }\n    if (urlOrKey.startsWith(this.endpoint + \"/\")) {\n      const rest = urlOrKey.slice(this.endpoint.length + 1);\n      const slash = rest.indexOf(\"/\");\n      return slash === -1 ? null : decodeURIComponent(rest.slice(slash + 1));\n    }\n    if (!urlOrKey.includes(\"://\")) {\n      return urlOrKey;\n    }\n    return null;\n  }\n\n  private async signRequest(req: {\n    method: string;\n    path: string;\n    query?: URLSearchParams;\n    body?: Uint8Array;\n    extraHeaders?: Record<string, string>;\n  }): Promise<SignedRequest> {\n    // SigV4's host header must include the port for non-default ports\n    // (e.g. localhost:9000 for S3-compatible test endpoints). URL.host keeps\n    // the port; URL.hostname strips it.\n    const { host } = new URL(this.endpoint);\n    const now = new Date();\n    const amzDate = formatAmzDate(now);\n    const dateStamp = amzDate.slice(0, 8);\n\n    const payloadHash = req.body ? toHex(sha256(req.body)) : EMPTY_PAYLOAD_HASH;\n\n    const canonicalQuery = req.query ? canonicalizeQuery(req.query) : \"\";\n\n    const headers: Record<string, string> = {\n      host,\n      \"x-amz-content-sha256\": payloadHash,\n      \"x-amz-date\": amzDate,\n      ...(req.extraHeaders ?? {}),\n    };\n\n    const sortedHeaderNames = Object.keys(headers)\n      .map((h) => h.toLowerCase())\n      .sort();\n    const canonicalHeaders =\n      sortedHeaderNames\n        .map((h) => `${h}:${headers[h].trim().replace(/\\s+/g, \" \")}`)\n        .join(\"\\n\") + \"\\n\";\n    const signedHeaders = sortedHeaderNames.join(\";\");\n\n    const canonicalRequest = [\n      req.method,\n      req.path,\n      canonicalQuery,\n      canonicalHeaders,\n      signedHeaders,\n      payloadHash,\n    ].join(\"\\n\");\n\n    const credentialScope = `${dateStamp}/${this.region}/${SERVICE}/aws4_request`;\n    const stringToSign = [\n      \"AWS4-HMAC-SHA256\",\n      amzDate,\n      credentialScope,\n      toHex(sha256(new TextEncoder().encode(canonicalRequest))),\n    ].join(\"\\n\");\n\n    const signingKey = deriveSigningKey(\n      this.config.secretAccessKey,\n      dateStamp,\n      this.region,\n      SERVICE,\n    );\n    const signature = toHex(\n      hmac(sha256, signingKey, new TextEncoder().encode(stringToSign)),\n    );\n\n    headers.authorization = `AWS4-HMAC-SHA256 Credential=${this.config.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;\n\n    const url =\n      this.endpoint +\n      req.path +\n      (canonicalQuery !== \"\" ? `?${canonicalQuery}` : \"\");\n\n    return { url, headers };\n  }\n}\n\nconst EMPTY_PAYLOAD_HASH =\n  \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nfunction deriveSigningKey(\n  secret: string,\n  dateStamp: string,\n  region: string,\n  service: string,\n): Uint8Array {\n  const enc = new TextEncoder();\n  const kDate = hmac(\n    sha256,\n    enc.encode(`AWS4${secret}`),\n    enc.encode(dateStamp),\n  );\n  const kRegion = hmac(sha256, kDate, enc.encode(region));\n  const kService = hmac(sha256, kRegion, enc.encode(service));\n  return hmac(sha256, kService, enc.encode(\"aws4_request\"));\n}\n\nfunction formatAmzDate(date: Date): string {\n  // YYYYMMDDTHHMMSSZ\n  const iso = date.toISOString();\n  return iso.replace(/[-:]/g, \"\").replace(/\\.\\d+/, \"\");\n}\n\nfunction toHex(bytes: Uint8Array): string {\n  let s = \"\";\n  for (let i = 0; i < bytes.length; i++) {\n    s += bytes[i].toString(16).padStart(2, \"0\");\n  }\n  return s;\n}\n\n/**\n * RFC 3986-compliant percent-encoding. `encodeURIComponent` leaves `! ' ( ) *`\n * unescaped, but AWS SigV4 (and RFC 3986 reserved sub-delims) require them\n * encoded. Used for both path segments and query keys/values.\n */\nfunction rfc3986Encode(value: string): string {\n  return encodeURIComponent(value).replace(\n    /[!'()*]/g,\n    (c) => \"%\" + c.charCodeAt(0).toString(16).toUpperCase(),\n  );\n}\n\n/**\n * Encode each path segment per AWS canonical-URI rules. Slashes between segments\n * are preserved; everything else (including `+`, `=`, etc.) is percent-encoded.\n */\nfunction encodePath(key: string): string {\n  return key.split(\"/\").map(rfc3986Encode).join(\"/\");\n}\n\nfunction canonicalizeQuery(params: URLSearchParams): string {\n  const entries: [string, string][] = [];\n  for (const [k, v] of params.entries()) {\n    entries.push([k, v]);\n  }\n  entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n  return entries\n    .map(([k, v]) => `${rfc3986Encode(k)}=${rfc3986Encode(v)}`)\n    .join(\"&\");\n}\n\ninterface ListObject {\n  key: string;\n  size: number;\n  lastModified: Date;\n}\n\nfunction parseListObjects(xml: string): ListObject[] {\n  const out: ListObject[] = [];\n  const contentsRe = /<Contents>([\\s\\S]*?)<\\/Contents>/g;\n  let match: RegExpExecArray | null;\n  while ((match = contentsRe.exec(xml)) !== null) {\n    const block = match[1];\n    const key = matchTag(block, \"Key\");\n    const size = matchTag(block, \"Size\");\n    const lastModified = matchTag(block, \"LastModified\");\n    if (key === null) {\n      continue;\n    }\n    out.push({\n      key: decodeXmlEntities(key),\n      size: size !== null ? parseInt(size, 10) || 0 : 0,\n      lastModified:\n        lastModified !== null ? new Date(lastModified) : new Date(0),\n    });\n  }\n  return out;\n}\n\nfunction matchTag(block: string, tag: string): string | null {\n  const re = new RegExp(`<${tag}>([\\\\s\\\\S]*?)<\\\\/${tag}>`);\n  const m = re.exec(block);\n  return m === null ? null : m[1];\n}\n\nfunction decodeXmlEntities(s: string): string {\n  return s\n    .replace(/&amp;/g, \"&\")\n    .replace(/&lt;/g, \"<\")\n    .replace(/&gt;/g, \">\")\n    .replace(/&quot;/g, '\"')\n    .replace(/&apos;/g, \"'\");\n}\n\nfunction randomSuffix(): string {\n  return Math.random().toString(36).slice(2, 10);\n}\n\nasync function safeText(response: Response): Promise<string> {\n  try {\n    return await response.text();\n  } catch {\n    return \"\";\n  }\n}\n\nfunction wrapError(error: unknown, code: string, provider: string): Error {\n  if (error instanceof StorageError) {\n    return error;\n  }\n  return new StorageError(\n    `R2 error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n    code,\n    provider,\n  );\n}\n"],"mappings":"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","names":[]}