← back to Tk 10965 Zero Price Analysis
cli-args.mjs
30 lines
export const USAGE = `Usage: node apply-fix.mjs <mode> [options]
--help Show usage without initialization
--plan | --enumerate Validate frozen manifest and print plan; no adapter or journal
--canary | --all Execute frozen canary membership or complete manifest OFFLINE
--rollback Restore only confirmed journal successes OFFLINE
Required: --manifest FILE --expected-sha256 HASH --expected-store-id SHOP_GID
Execution: --offline-state FILE --journal FILE
Existing journal: --journal-sha256 HASH (external checkpoint required)
Live execution is disabled. Legacy scans, numeric canaries and restore maps are refused.`;
export function parseArgs(args) {
const [mode, ...rest] = args;
if (!['--help','--plan','--enumerate','--canary','--all','--rollback'].includes(mode)) throw new Error('A recognized mode is required.');
if (mode === '--help') { if (rest.length) throw new Error('Unexpected arguments.'); return {mode}; }
const cli = {mode};
const options = new Set(['--manifest','--expected-sha256','--expected-store-id','--offline-state','--journal','--journal-sha256']);
for (let i=0;i<rest.length;i+=2) {
const [k,v] = rest.slice(i,i+2);
if (!options.has(k) || Object.hasOwn(cli,k) || !v?.trim() || v.startsWith('-')) throw new Error('Invalid, duplicate or missing option: ' + k);
cli[k] = v;
}
for (const k of ['--manifest','--expected-sha256','--expected-store-id']) if (!cli[k]) throw new Error('Required: ' + k);
for (const k of ['--expected-sha256','--journal-sha256']) if (cli[k] && !/^[a-f0-9]{64}$/.test(cli[k])) throw new Error('Invalid SHA256: '+k);
if (!/^gid:\/\/shopify\/Shop\/[1-9][0-9]*$/.test(cli['--expected-store-id'])) throw new Error('Invalid expected store ID.');
const plan = ['--plan','--enumerate'].includes(mode);
if (plan && ['--offline-state','--journal','--journal-sha256'].some(k=>cli[k])) throw new Error('Plan cannot initialize adapter or journal.');
if (!plan && (!cli['--offline-state'] || !cli['--journal'])) throw new Error('Live execution disabled; offline-state and journal required.');
if (mode==='--rollback' && !cli['--journal-sha256']) throw new Error('Rollback requires pinned journal SHA256.');
return cli;
}