1import fs from 'fs/promises' 3import type { Knex } from 'knex' 14const META_FILE = '_meta.json' 16export const restoreIpfsContent = async ({label, db}: {label: string, db: Knex}) => { 19 const summary = {restored: 0, failed: 0} 21 let meta: IpfsBackupMeta | null = null 23 const metaRaw = await fs.readFile(path.join(dirPath, META_FILE), 'utf8') 24 meta = JSON.parse(metaRaw) 26 betLog('ipfsRestoreNoMeta', {label, dirPath}) 29 const mfsRoot = meta?.mfsRoot 31 await client.files.mkdir(mfsRoot, {parents: true}).catch(() => {}) 34 const files = await fs.readdir(dirPath) 35 const contentFiles = files.filter(f => f !== META_FILE && !f.startsWith('.')) 37 for (const fileName of contentFiles) { 38 const lastDot = fileName.lastIndexOf('.') 39 const ext = lastDot >= 0 ? fileName.slice(lastDot + 1) : 'bin' 40 const fileCid = lastDot >= 0 ? fileName.slice(0, lastDot) : fileName 41 const filePath = path.join(dirPath, fileName) 44 const buffer = await fs.readFile(filePath) 48 const mfsPath = `${mfsRoot}/${newCid}.${ext}` 49 await client.files.cp(`/ipfs/${newCid}`, mfsPath).catch(() => {}) 55 betLog('ipfsRestoreFile', {fileName, newCid}) 57 betLog('ipfsRestoreFail', {fileName, errMsg: (err as Error).message}) 62 if (mfsRoot && meta?.kvKey) { 64 const stat = await client.files.stat(mfsRoot) 65 const newRootCid = stat.cid.toString() 68 await db('generic_kvs') 69 .insert({key: meta.kvKey, value: newRootCid}) 71 .merge({value: newRootCid, updated_at: db.fn.now()}) 73 betLog('ipfsRestoreRoot', {mfsRoot, newRootCid}) 75 betLog('ipfsRestoreRootFail', {mfsRoot, errMsg: (err as Error).message})