#!/usr/bin/env -S npx --yes tsx // ============================================================================= // delete.ts — Delete a key's value from the vault // // Part of: .opencode/skills/templating-vault/scripts/ // // Removes a key's value file. Respects write-once and owner restrictions. // Optionally deletes recursively under a prefix. // // USAGE: // delete.ts --key [--owner ] [--recursive] // [--config ] [--store-dir ] // // OUTPUT (stdout): JSON result // ============================================================================= import * as fs from 'node:fs'; import * as path from 'node:path'; import { fileURLToPath } from 'node:url'; import { parseCommonFlags, getFlag, hasFlag, output, loadConfig, resolveStore, loadKeyMeta, deleteValue, hasValue, listAllKeys, keyToPath, } from './api.ts'; async function main(): Promise { const { config: cfgPath, storeDirs, rest } = parseCommonFlags(process.argv); const config = loadConfig(cfgPath, storeDirs.length > 0 ? storeDirs : undefined); const key = getFlag(rest, '--key'); const owner = getFlag(rest, '--owner'); const recursive = hasFlag(rest, '--recursive'); if (!key) { output({ deleted: false, error: '--key is required' }); process.exit(1); } // Check access const resolved = resolveStore(config, key); if (resolved.mapping.access === 'readonly') { output({ deleted: false, error: `Store for prefix "${resolved.mapping.prefix}" is readonly` }); process.exit(1); } if (recursive) { // Delete all keys under prefix const keys = listAllKeys(config, key, true); let deletedCount = 0; const errors: string[] = []; // Also include the key itself if (hasValue(config, key)) { const meta = loadKeyMeta(config, key); if (meta.write_once) { errors.push(`${key}: write-once, cannot delete`); } else { deleteValue(config, key); deletedCount++; } } for (const k of keys) { const meta = loadKeyMeta(config, k); if (meta.write_once) { errors.push(`${k}: write-once, cannot delete`); continue; } if (deleteValue(config, k)) deletedCount++; } output({ deleted: true, count: deletedCount, errors: errors.length > 0 ? errors : undefined }); } else { // Delete single key if (!hasValue(config, key)) { output({ deleted: false, error: `Key "${key}" has no value` }); process.exit(1); } const meta = loadKeyMeta(config, key); if (meta.write_once) { output({ deleted: false, error: `Key "${key}" is write-once, cannot delete` }); process.exit(1); } if (meta.owner && owner && meta.owner !== owner) { output({ deleted: false, error: `Key "${key}" is owned by "${meta.owner}", not "${owner}"` }); process.exit(1); } deleteValue(config, key); output({ deleted: true, key }); } } if (process.argv[1] === fileURLToPath(import.meta.url)) { main().catch((err: unknown) => { output({ deleted: false, error: String(err instanceof Error ? err.message : err) }); process.exit(1); }); }