const fetch = require('node-fetch');
const { WebCache, VersionResolveError } = require('./WebCache');
const { verifyWebCacheIntegrity } = require('./WebCacheIntegrity');
/**
* RemoteWebCache - Fetches a WhatsApp Web version index from a remote server
* @param {object} options - options
* @param {string} options.remotePath - Endpoint that should be used to fetch the version index. Use {version} as a placeholder for the version number.
* @param {boolean} options.strict - If true, will throw an error if the requested version can't be fetched. Defaults to true.
* @param {Record<string, {sha256: string, sizeBytes: number}>} options.integrity - Optional immutable artifact manifest.
*/
class RemoteWebCache extends WebCache {
constructor(options = {}) {
super();
if (!options.remotePath)
throw new Error(
'webVersionCache.remotePath is required when using the remote cache',
);
this.remotePath = options.remotePath;
this.strict = options.strict !== false;
this.integrity = options.integrity;
}
async resolve(version) {
const remotePath = this.remotePath.replace('{version}', version);
try {
const cachedRes = await fetch(remotePath);
if (cachedRes.ok) {
const content = await cachedRes.text();
return verifyWebCacheIntegrity(
content,
version,
this.integrity,
);
}
} catch (err) {
// An integrity manifest is a pin, not a best-effort cache hint.
// Never turn a mismatched remote artifact into a live-Web fallback
// when strict mode is disabled.
if (err instanceof VersionResolveError) throw err;
console.error(`Error fetching version ${version} from remote`, err);
}
if (this.strict)
throw new VersionResolveError(
`Couldn't load version ${version} from the archive`,
);
return null;
}
async persist() {
// Nothing to do here
}
}
module.exports = RemoteWebCache;