// Test-only synthetic transport bytes. Never use this module for a real // activation manifest, upload evidence, prune receipt or source backup. import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { isMediaFile, readSourceManifest, sha256 } from './tang-detective-source-validation.mjs' const originalSourceDirectory = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../native/tang-detective') export function writeFixture(directory, relative, bytes) { const filename = path.join(directory, relative) fs.mkdirSync(path.dirname(filename), { recursive: true }) fs.writeFileSync(filename, bytes) } export function createSyntheticSource(temporary) { const sourceDirectory = path.join(temporary, 'source') const original = readSourceManifest() const replacements = new Map([...original.files.values()].filter(file => isMediaFile(file.path)) .map(file => [file.sha256, Buffer.from(`Test-only media fixture for ${file.sha256}\n`)])) const hashReplacements = new Map([...replacements].map(([originalHash, bytes]) => [originalHash, sha256(bytes)])) const files = [] for (const file of original.files.values()) { let bytes if (isMediaFile(file.path)) bytes = replacements.get(file.sha256) else { const source = fs.readFileSync(path.join(originalSourceDirectory, file.path)) if (source.length !== file.bytes || sha256(source) !== file.sha256) throw new Error(`Original non-media source drift: ${file.path}`) bytes = Buffer.from(source.toString('utf8').replace(/[a-f0-9]{64}/g, value => hashReplacements.get(value) || value)) } writeFixture(sourceDirectory, file.path, bytes) files.push({ path: file.path, bytes: bytes.length, sha256: sha256(bytes) }) } const sourceManifest = { version: 1, files } const sourceBytes = Buffer.from(`${JSON.stringify(sourceManifest, null, 2)}\n`) const sourceManifestPath = path.join(temporary, 'synthetic-source-manifest.json') fs.writeFileSync(sourceManifestPath, sourceBytes) return { sourceDirectory, sourceManifest, sourceManifestPath, sourceBytes, sourceMedia: files.filter(file => isMediaFile(file.path)), hashReplacements } } export function fakeVerifiedManifest({ sourceBytes, sourceMedia }) { const baseUrl = 'https://tang-assets.example.test' return { schemaVersion: 1, uploadRunId: 'test-only-offline-run', sourceManifestSha256: sha256(sourceBytes), destination: { bucket: 'test-bucket', region: 'test-region', baseUrl }, entries: sourceMedia.map(file => { const kind = file.path.endsWith('.jpg') ? 'image' : 'audio' const objectKey = `tang-detective/season-01/media-v1/${file.sha256}${path.extname(file.path)}` return { sourcePath: file.path, kind, contentType: kind === 'image' ? 'image/jpeg' : 'audio/mpeg', bytes: file.bytes, sha256: file.sha256, objectKey, url: `${baseUrl}/${objectKey}`, uploaded: true, publicReadVerified: true, remoteVerifiedSha256: file.sha256, ...(kind === 'audio' ? { rangeVerified: true } : {}) } }), } } export function fakePruneReceipt(mediaManifest) { const backup = { sha256: sha256('Test-only archive receipt; no real archive or upload'), bytes: 123, format: 'tar.gz' } return { schemaVersion: 1, status: 'completed', sourceManifestSha256: mediaManifest.sourceManifestSha256, mediaManifestSha256: sha256(`${JSON.stringify(mediaManifest, null, 2)}\n`), uploadRunId: mediaManifest.uploadRunId, backup, entries: mediaManifest.entries.map(({ sourcePath, sha256: digest, bytes, url, objectKey }) => ({ sourcePath, sha256: digest, bytes, url, objectKey, backupSha256: backup.sha256, })) } }