Files

28 lines
2.0 KiB
JavaScript

/** Read versioned content from S3-backed media API or an external authoring cache. */
import {readFile,mkdir,writeFile} from 'node:fs/promises';
import {createHash} from 'node:crypto';
import {fileURLToPath} from 'node:url';
import path from 'node:path';
export const repositoryRoot=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
export const managedMedia=JSON.parse(await readFile(path.join(repositoryRoot,'apps/waterfall-wiki/src/content/managed-media.json'),'utf8'));
export async function readRepositoryMedia(name){
const asset=managedMedia[name];if(!asset)throw Error('Unregistered media: '+name);
let bytes;
if(process.env.MEDIA_SOURCE_ROOT)bytes=await readFile(path.join(process.env.MEDIA_SOURCE_ROOT,name));
else{
const base=process.env.MEDIA_BASE_URL||process.env.WIKI_BASE||'http://8.211.154.134:18131';
const headers=process.env.PROMPT_TOKEN?{Authorization:'Bearer '+process.env.PROMPT_TOKEN}:{};
const response=await fetch(new URL('/api/media/'+asset.id,base),{headers,redirect:'error',signal:AbortSignal.timeout(60000)});
if(!response.ok)throw Error(`Media ${name}: HTTP ${response.status}; supply MEDIA_SOURCE_ROOT or authenticated MEDIA_BASE_URL`);
bytes=Buffer.from(await response.arrayBuffer());
}
if(bytes.length!==asset.bytes||createHash('sha256').update(bytes).digest('hex')!==asset.sha256)throw Error('Media checksum mismatch: '+name);
return bytes;
}
if(process.argv[1]&&path.resolve(process.argv[1])===fileURLToPath(import.meta.url)){
const destination=process.argv[2];if(!destination)throw Error('Usage: node scripts/managed-media.mjs /absolute/external-cache');
const target=path.resolve(destination);if(target===repositoryRoot||target.startsWith(repositoryRoot+path.sep))throw Error('Cache must be outside repository');
for(const name of Object.keys(managedMedia)){const bytes=await readRepositoryMedia(name);const file=path.join(target,name);await mkdir(path.dirname(file),{recursive:true});await writeFile(file,bytes);}
console.log(`Restored ${Object.keys(managedMedia).length} verified media paths to external cache`);
}