Setting the file. One moment. Multilingual Journal Removal · Rp Target Wix · wix/skills · Skills Docs41.10
Multilingual Restore
scripts/multilingual-journal-removal.js
scripts/multilingual-journal-removal.js
JavaScript·65 lines·3 KB
const
target
=
require
(
'../lib/multilingual-target.js'
);
9const { loadAdapter } = require('./multilingual-execute.js');
10
11async function request(projectDir, evidenceRef) {
12 if (typeof evidenceRef !== 'string' || !evidenceRef.trim()) throw new Error('evidenceRef is required');
13 const scopeDigest = core.digest({ collection: 'ReplatformTranslationRecovery', evidenceRef });
14 const value = {
15 schemaVersion: 1,
16 status: 'requested',
17 actionId: core.actionId('LANG_RECOVERY_JOURNAL_REMOVE', scopeDigest.slice(0, 24)),
18 scopeDigest,
19 evidenceRef,
20 requestedAt: new Date().toISOString(),
21 };
22 await core.writeJsonAtomic(path.join(projectDir, report.JOURNAL_REMOVAL), value);
23 return value;
24}
25
26async function remove(projectDir, { adapterModule, proofFile }) {
27 const file = path.join(projectDir, report.JOURNAL_REMOVAL);
28 const state = JSON.parse(await fs.readFile(file, 'utf8'));
29 if (state.status !== 'requested') throw new Error('journal removal is not requested');
30 const decisions = core.readNdjson(path.join(projectDir, report.DECISIONS));
31 const authorized = decisions.some((row) => row.kind === 'authorize-journal-removal'
32 && row.actionId === state.actionId && row.scopeDigest === state.scopeDigest);
33 if (!authorized) throw new Error('journal removal lacks a current owner authorization decision');
34 const proof = JSON.parse(await fs.readFile(proofFile, 'utf8'));
35 target.requireRouteProof(proof, target.ROUTES.collectionDelete);
36 target.requireRouteProof(proof, target.ROUTES.collectionRead);
37 const adapter = await loadAdapter(adapterModule, projectDir);
38 await adapter.deleteRecoveryCollection('ReplatformTranslationRecovery');
39 const read = await adapter.inspectRecoveryCollection();
40 if (read?.status !== 'absent') throw new Error('recovery collection absence read-back failed');
41 const removed = { ...state, status: 'removed', removedAt: new Date().toISOString(), absenceVerified: true };
42 await core.writeJsonAtomic(file, removed);
43 return removed;
44}
45
46async function main() {
47 const projectDir = process.argv[2] && path.resolve(process.argv[2]);
48 const command = process.argv[3];
49 if (!projectDir || !['request', 'remove'].includes(command)) throw new Error('Usage: multilingual-journal-removal.js <projectDir> request|remove [options]');
50 if (command === 'request') {
51 const evidenceIndex = process.argv.indexOf('--evidence-ref');
52 if (evidenceIndex < 0) throw new Error('request requires --evidence-ref <reference>');
53 const result = await request(projectDir, process.argv[evidenceIndex + 1]);
54 process.stdout.write(`${JSON.stringify({ status: result.status, actionId: result.actionId })}\n`);
55 return;
56 }
57 const adapterIndex = process.argv.indexOf('--adapter');
58 const proofIndex = process.argv.indexOf('--proof');
59 if (adapterIndex < 0 || proofIndex < 0) throw new Error('remove requires --adapter <module.js> --proof <contract-evidence.json>');
60 const result = await remove(projectDir, { adapterModule: process.argv[adapterIndex + 1], proofFile: path.resolve(process.argv[proofIndex + 1]) });
61 process.stdout.write(`${JSON.stringify({ status: result.status, absenceVerified: result.absenceVerified })}\n`);
62}
63
64if (require.main === module) main().catch((error) => { console.error(error.message); process.exitCode = 1; });
65module.exports = { remove, request };