mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-01 20:33:50 +00:00
Two gaps. Format was decided inline in the import command by whether the text started with a brace, and --source only ever reached the CSV reader -- so a JSON or archive export could not be forced at all. If the sniff was wrong there was no way to say "this came from 1Password". And 1Password's own export button produces a .1pux, which nothing here could open. A source now names a product rather than a file format. Bitwarden exports JSON and CSV; 1Password exports .1pux and CSV. Saying --source onepassword says where the file came from, and the container is still decided by looking at the bytes. One router owns that decision instead of the command, and when nothing can read a file it prints every source that can be named rather than the bare "pass --source" it used to. 1Password's .1pux is a ZIP holding a single JSON document. Pulling in a zip library for that would have been this package's only dependency beyond commander, so the central directory is read here: node's zlib already does the decompression, and the container is a few dozen lines of offsets. Deliberately not a general ZIP implementation -- no encryption, no ZIP64, only the two compression methods an export uses. The .1pux reader keeps vaults as folders, TOTP secrets, custom sections, password history and the whole of a card. 1Password item ids are 26-character base32 rather than UUIDs, so they are hashed into a v5-shaped UUID: the same export imported twice produces the same ids, which is what makes a re-import report its items as already present instead of duplicating the vault. Trashed items are left behind and reported, since restoring deleted entries into a fresh vault would be a surprise. A category we do not model -- a passport, a server, a licence -- becomes a note carrying its fields, so an import never quietly loses one. Six more CSV products join the existing five: NordPass, Dashlane, Proton Pass, RoboForm, Apple Passwords and Firefox. Adding Apple broke 1Password: their columns are nearly identical and only 1Password's `type` separates them, so Apple now requires its absence and 1Password is asked first. There is a test for that pair, because the failure mode is silent -- every 1Password CSV had started importing as Apple. LastPass and KeePass needed nothing: LastPass only ever exports CSV, which was already read, and the same is true of KeePass's CSV. Verified end to end: the real 4,395-item Bitwarden export still reads, a .1pux round-trips through the CLI, an unidentifiable CSV prints the source list and then imports once told, and an unknown source name is refused by name. The zip reader is tested against archives the system zip produced rather than ones we wrote. 195 tests pass. The 1Password mapping is built from the documented 1PUX schema and driven by fixtures, not from a real 1Password export. Run it with --dry-run first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| src | ||
| package.json | ||
| tsconfig.json | ||