34 lines
2.1 KiB
JavaScript
34 lines
2.1 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import crypto from 'node:crypto'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { inventory, hash } from './upload.mjs'
|
|
|
|
const project = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..')
|
|
const stage = process.argv[2]
|
|
if (!stage || !path.isAbsolute(stage) || fs.existsSync(stage)) throw new Error('NEW_ABSOLUTE_STAGING_DIRECTORY_REQUIRED')
|
|
const source = inventory(project)
|
|
const unique = [...new Map(source.entries.map(entry => [entry.objectKey, entry])).values()]
|
|
const shared = source.entries.find(entry => entry.sourcePath === 'assets/share/guixiang-story-share-preview-v1.jpg')
|
|
if (!shared) throw new Error('FIRST_VERIFIED_SAMPLE_NOT_FOUND')
|
|
const sampleUrl = 'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/images/20260908/202609081718480ee488780.jpg'
|
|
const runId = crypto.randomUUID()
|
|
const counters = { image: 0, audio: 0 }
|
|
fs.mkdirSync(stage, { recursive: false })
|
|
const entries = unique.map(entry => {
|
|
const sample = entry.sha256 === shared.sha256
|
|
const stagedName = sample ? null : `tang-20260908-1714-${entry.kind}-${String(++counters[entry.kind]).padStart(3, '0')}${path.extname(entry.sourcePath)}`
|
|
const stagedPath = stagedName ? path.join(stage, stagedName) : null
|
|
if (stagedPath) {
|
|
const original = path.join(source.sourceDirectory, entry.sourcePath)
|
|
fs.copyFileSync(original, stagedPath, fs.constants.COPYFILE_EXCL)
|
|
if (hash(fs.readFileSync(stagedPath)) !== entry.sha256) throw new Error('STAGING_BYTES_DIFFER')
|
|
}
|
|
return { ...entry, stagedName, stagedPath, observedUrl: sample ? sampleUrl : null }
|
|
})
|
|
const result = { schemaVersion: 1, uploadRunId: runId, sourceManifestSha256: source.sourceManifestSha256,
|
|
sourceDirectory: source.sourceDirectory, stagingDirectory: stage, createdAt: new Date().toISOString(), entries }
|
|
const output = path.join(project, 'build/tang-detective-admin-upload-plan.json')
|
|
fs.writeFileSync(output, JSON.stringify(result, null, 2) + '\n', { flag: 'wx' })
|
|
console.log(JSON.stringify({ uploadRunId: runId, entries: entries.length, staged: counters, stage, output, originalsChanged: false }, null, 2))
|