(args: string[])
| 692 | // ─── Entry point ──────────────────────────────────────────────────────────── |
| 693 | |
| 694 | export default async function dbPatch(args: string[]): Promise<void> { |
| 695 | const parsed = parseArgs(args); |
| 696 | |
| 697 | if (parsed.help === "true") { |
| 698 | console.log(`Usage: pnpm action db-patch --table <t> --column <c> --where "<clause>" [edit flags] |
| 699 | |
| 700 | Surgical search-and-replace on a text column. Avoids re-sending the full |
| 701 | column value — ideal for large strings (documents, slides, dashboards, JSON). |
| 702 | |
| 703 | Required: |
| 704 | --table <name> Target table (identifier; no quoting) |
| 705 | --column <name> Target text column (identifier; no quoting) |
| 706 | --where "<clause>" SQL WHERE clause that matches exactly one row |
| 707 | |
| 708 | Edit mode (pick one): |
| 709 | --find <text> Text to find (single edit; default replace = "") |
| 710 | --replace <text> Replacement text (used with --find) |
| 711 | --edits <json> Batch: JSON array of {find, replace} objects |
| 712 | --json-ops <json> Structural JSON edits on a JSON column — array of ops: |
| 713 | { op: "set", path, value } → set/replace at path |
| 714 | { op: "remove", path } → delete at path |
| 715 | { op: "insert", path, value } → insert into array |
| 716 | { op: "move", from, path } → move node |
| 717 | { op: "move-before", from, path } → move, stable indexing |
| 718 | Paths use JSON Pointer ("/panels/3/title"). |
| 719 | Much safer than string patches for JSON columns |
| 720 | (dashboards, forms, slide decks). |
| 721 | |
| 722 | Options: |
| 723 | --all Replace every occurrence of each 'find' (default: first only) |
| 724 | --format json Output as JSON |
| 725 | --help Show this help |
| 726 | |
| 727 | Examples: |
| 728 | # Fix a typo in one document |
| 729 | pnpm action db-patch --table documents --column content \\ |
| 730 | --where "id='abc'" --find "teh" --replace "the" |
| 731 | |
| 732 | # Batch edits on a deck's JSON blob |
| 733 | pnpm action db-patch --table decks --column data --where "id='d1'" \\ |
| 734 | --edits '[{"find":"\\"Q3\\"","replace":"\\"Q4\\""},{"find":"$1M","replace":"$1.2M"}]' |
| 735 | |
| 736 | When to use db-patch vs other tools: |
| 737 | Large text field, small edit → db-patch (this) |
| 738 | Short field or multi-column set → db-exec UPDATE |
| 739 | Domain action exists (edit-document, ...) → use that action (syncs live |
| 740 | to open collaborative editors) |
| 741 | `); |
| 742 | return; |
| 743 | } |
| 744 | |
| 745 | const table = parsed.table; |
| 746 | const column = parsed.column; |
| 747 | const where = parsed.where; |
| 748 | |
| 749 | if (!table) fail("--table is required"); |
| 750 | if (!column) fail("--column is required"); |
| 751 | if (!where) fail("--where is required"); |
no test coverage detected