{"path":"lib/filebase.js","size":3472,"locked":false,"binary":false,"truncated":false,"content":"import { readdir, readFile } from 'node:fs/promises';\nimport { join, relative, sep } from 'node:path';\nimport { ObjectManager } from '@filebase/sdk';\n\n/**\n * Recursively walks a directory and returns entries shaped for\n * @filebase/sdk's ObjectManager.upload() directory-upload form:\n *   [{ path: '/relative/virtual/path', content: Buffer }, ...]\n *\n * VERIFIED against Filebase's own docs (docs.filebase.com/ipfs-pinning/pinning-files,\n * filebase.github.io/filebase-sdk/ObjectManager.html) — passing an array of\n * { path, content } objects to upload() packs them into a directory/CAR upload.\n * We walk the filesystem ourselves (rather than pulling in their `recursive-fs`\n * example dependency) so the virtual path is a clean, predictable relative path\n * with no local folder-name prefix baked in.\n */\nasync function walkDirectory(rootDir, currentDir = rootDir, files = []) {\n  const entries = await readdir(currentDir, { withFileTypes: true });\n  for (const entry of entries) {\n    const fullPath = join(currentDir, entry.name);\n    if (entry.isDirectory()) {\n      await walkDirectory(rootDir, fullPath, files);\n    } else {\n      const virtualPath = '/' + relative(rootDir, fullPath).split(sep).join('/');\n      const content = await readFile(fullPath);\n      files.push({ path: virtualPath, content });\n    }\n  }\n  return files;\n}\n\n/**\n * Uploads a build directory to Filebase and returns the resulting CID.\n *\n * This is an ALTERNATE pinning provider to Storacha (lib/storacha.js) — same\n * role, different service. Use it by setting \"provider\": \"filebase\" in\n * anchr.json. It exists specifically as a fallback for when Storacha's\n * upload endpoint is unreachable; it is not a \"use both at once\" abstraction\n * (that's explicitly deferred multi-provider scope, see docs/ROADMAP.md).\n *\n * NOT independently confirmed: the exact field name for the CID on the\n * object ObjectManager.upload() resolves to. Docs describe the return type\n * as an \"objectHeadResult\" but don't show its full field list in the\n * snippets available. Log the raw result and confirm `cid` is correct\n * before trusting this in a real deploy — same \"verify before building on\n * top of it\" caution as the SNS module.\n *\n * Requires env vars:\n *   ANCHR_FILEBASE_KEY    — S3 access key (Filebase Console → Access Keys)\n *   ANCHR_FILEBASE_SECRET — S3 secret key\n *   ANCHR_FILEBASE_BUCKET — name of an IPFS-enabled bucket in your Filebase account\n */\nexport async function uploadToFilebase(buildDir) {\n  const key = process.env.ANCHR_FILEBASE_KEY;\n  const secret = process.env.ANCHR_FILEBASE_SECRET;\n  const bucket = process.env.ANCHR_FILEBASE_BUCKET;\n\n  if (!key || !secret || !bucket) {\n    throw new Error(\n      'Missing ANCHR_FILEBASE_KEY / ANCHR_FILEBASE_SECRET / ANCHR_FILEBASE_BUCKET env vars. See README.md.'\n    );\n  }\n\n  const objectManager = new ObjectManager(key, secret, { bucket });\n\n  const files = await walkDirectory(buildDir);\n  if (files.length === 0) {\n    throw new Error(`No files found in build directory: ${buildDir}`);\n  }\n\n  const uploaded = await objectManager.upload('anchr-deploy', files);\n\n  // See caution above — confirm this field name against a real response.\n  const cid = uploaded?.cid;\n  if (!cid) {\n    throw new Error(\n      `Upload completed but no CID was found on the result. Raw result: ${JSON.stringify(uploaded)}`\n    );\n  }\n\n  return {\n    cid: cid.toString(),\n    gatewayUrl: `https://ipfs.filebase.io/ipfs/${cid}`\n  };\n}\n"}