Skip to main content
Version: 0.16

Updating objects

The update command applies a JMAP patch to one object (or a singleton). The patch shape mirrors JMAP's Foo/set update argument: only the changed fields are sent.

Synopsis

stalwart-cli update <object> [<id>] ( --field key=value... | --json '<json>' | --file <path> | --stdin )
  • <object>: object type name (with or without x: prefix). The slash form is rejected here (it is a create feature).
  • <id>: required for normal objects; optional for singletons (defaults to singleton). Passing any non-singleton id for a singleton is rejected.
  • The four input forms are mutually exclusive.

Field paths and JSON pointers

For --field keys, two forms are supported:

  • Top-level property name: --field name=foo sets the entire property.
  • JSON pointer path: --field 'aliases/2/name=foo' patches a sub-element. The first segment is matched against the schema (case-insensitive, rewritten to canonical case). Deeper segments (map keys, list indices, nested object properties) are passed through verbatim.

This makes targeted edits cheap. For example, adding one entry to a set:

stalwart-cli update domain b --field 'aliases/extra.example.com=true'

And removing one entry from a set or map:

stalwart-cli update domain b --field 'aliases/extra.example.com=null'

The JSON pointer model is the same one JMAP uses internally:

  • Sets are encoded as a map of value -> true. Set the value to true to add, to null to remove.
  • Object lists are encoded as a map of stringified positional indices to objects. Use a new index to add, set the index to null to remove.
  • Maps are plain JSON objects: set a key's value to update, set it to null to delete.

Quoted keys

When a JSON-pointer path contains characters that would otherwise be misparsed (for example a literal = in a CIDR or header name), quote the entire key:

stalwart-cli update systemsettings --field '"proxyTrustedNetworks/127.0.0.1"=true'

Without quotes, the parser splits on the first =, which would land inside the path. With quotes, everything between the matching quote characters is the key, and the first = after the closing quote separates key from value.

Updating singletons

Singletons accept (or default to) the literal id singleton:

stalwart-cli update systemsettings --field allowRelaying=true
stalwart-cli update systemsettings singleton --field allowRelaying=true

Both are equivalent. Passing any other id for a singleton is rejected with a clear error.

Input sources

Identical to create:

SourceWhen to use
--field key=valueQuick targeted edits from the shell
--json '<json>'A small structured patch composed inline
--file <path>A patch generated by another tool or template
--stdinA patch piped from another command

For the JSON forms, the document is the patch object sent to JMAP, not the full object. Setting a sub-key with the JSON forms uses the JSON-pointer convention (the keys may contain /):

stalwart-cli update domain b --json '{"description": "Renamed", "aliases/extra.example.com": true}'

Repeating the same key with --field is an error. Mixing input sources is also an error (only one may be supplied).

Examples

Change a description:

stalwart-cli update domain b --field description='Primary domain'

Toggle a singleton flag:

stalwart-cli update systemsettings --field allowRelaying=false

Replace a structured field:

stalwart-cli update domain b \
--field 'certificateManagement={"@type":"Automatic","acmeProviderId":"a"}'

Add a new alias to an object list (next available index):

stalwart-cli update account/user b --field 'aliases/3={"name":"hello","domainId":"b"}'

Add an item to a set (using set-of-id semantics):

stalwart-cli update account/user b --field 'memberGroupIds/g1=true'

Remove the same item:

stalwart-cli update account/user b --field 'memberGroupIds/g1=null'

Apply a patch generated by another tool:

generate-domain-patch.sh | stalwart-cli update domain b --stdin

Variant changes

For multi-variant objects, changing the variant requires patching the entire sub-object atomically (JMAP cannot mix @type/... JSON pointer keys with sibling property changes when the type itself changes). Send the new variant's full body in one go:

stalwart-cli update domain b \
--field 'certificateManagement={"@type":"Automatic","acmeProviderId":"a"}'

The CLI does not validate variant changes (the server does). For complex variant transitions, prefer a JSON file built by a configuration tool.

Output

A success line is printed:

Updated Domain b

If the server returns server-set fields after the update (rare; mostly for fields that are recomputed), they are rendered below in the same form-driven view as get.

See also