Skip to content

v0.3.0

Choose a tag to compare

@tolgamorf tolgamorf released this 23 Sep 08:12
· 20 commits to main since this release

What's New

fix: keep quoted values, inline comments and op errors intact; export parser API

Values and comments now survive a push and pull:

  • A quoted value keeps its quotes in the template (KEY="op://…"). op
    inject substitutes inside them, so "a # b" or " padded " comes back
    quoted and reads the same on the next push instead of losing its tail.
  • Quoted values follow dotenv's rule: the value ends at the first matching
    quote followed only by whitespace or a comment, so "{"x":1}" is
    {"x":1} rather than {.
  • Inline comments on variable lines are kept in the template, so they no
    longer vanish from the .env on pull. A reference followed by one is always
    quoted: unquoted, op inject eats the space before the # and val# c
    reads back as the value. op:// in an inline comment is masked before op
    inject, found by the parser's own rules so a # inside a quoted value is
    never mistaken for one.

Checked against real 1Password: every shape above reads the same before and
after a pull, and op run gives the same values.

Bug fixes:

  • A failed op item list / op vault list now stops the command
    (OP_COMMAND_FAILED) instead of reading as "not found", which created a
    duplicate item. A failed op vault create is reported instead of shown as
    "Created vault": exec never throws, so the old try/catch caught nothing.
  • The temp JSON template, which holds every value in plain text, is written
    0600 instead of world-readable.
  • The update check gives up after 1.5 s instead of holding the CLI open on a
    dead network.
  • Unknown flags are errors, so --dryrun no longer pushes for real.
    --output=path is accepted, and -o without a path is an error.

Speed-ups:

  • One op whoami tells a missing op (spawn ENOENT) from a signed-out one,
    replacing the separate op --version spawn, which is slow under WSL.
  • Minimum spinner time drops from 500 ms to 200 ms.
  • --verbose no longer echoes op's item JSON, which carries every value.

Library API: parseEnvText (synchronous parseEnvFile for text in hand),
parseValue, ParsedValue, maskSecretRefsInComments, unmaskSecretRefs,
MaskedTemplate and Quote are exported from the package entry, with no
import side effects, so tools that read the same .env and template files
can share one implementation.

Removed: TemplateOptions.variables, errors.itemExists/parseError with the
ITEM_EXISTS/PARSE_ERROR codes, and unused helpers (execOrThrow,
detectPackageManagerSync, getUpdateCommand, clearUpdateCache, four logger
methods).

fix: keep empty values as literal KEY= in the template

A variable with an empty value got an op://vault/item/KEY reference that
could never resolve: 1Password keeps no empty field, so the item returned
no field ID for it and the template fell back to the label. The template
now writes such a line as a literal KEY=. op inject and op run pass a
line with no reference through unchanged, so op2env writes KEY= back and
"empty" survives the round trip. That matters where the file overrides
another (KEY= in .env.development.local is not the same as inheriting
.env's KEY).

Empty values are no longer pushed as fields either, since the template never
refers to them and they are not secrets. Each push still rebuilds the
template from the current .env and the field IDs op returns, so filling a
value in later turns the line into a reference, and clearing it turns it
back into KEY= and drops the field. Verified end to end against real
1Password, including an item whose values are all empty.

The parser read KEY= # note as the value "# note", because it trimmed
before splitting off the inline comment. It now splits first, so that line
is empty. KEY=#336699 keeps its #, as before.

The template header now says "Secret values are not stored here — only
references to them", which stays true with literal empty lines.

chore: update manifests for v0.2.11


Installation

Homebrew (macOS/Linux)

brew install tolgamorf/tap/env2op-cli

Package Managers (macOS/Linux/Windows)

# Using bun
bun add -g @tolgamorf/env2op-cli

# Using npm
npm install -g @tolgamorf/env2op-cli

# Using pnpm
pnpm add -g @tolgamorf/env2op-cli