Skip to content

v0.6.0 — OptionSet identity in read tools

Choose a tag to compare

@rededis rededis released this 17 Aug 06:58
· 46 commits to main since this release
3161f06

Changed

  • BREAKING — get_picklist_options no longer returns a bare [{ value, label }] array. It now returns { option_set: { name, is_global, metadata_id }, options: [{ value, label }] } (closes #61). The flat array made a Local OptionSet and a Global one indistinguishable: the response shape was identical either way, and matching values do not prove a binding. Callers that consumed the array directly need to read .options.
  • get_picklist_options now resolves Choice, Status, State and MultiSelect columns, not just Choice. statecode / statuscode previously failed with "Picklist attribute not found"; the not-found message now names the whole choice family.

Added

  • get_entity_schema attaches an option_set summary — { name, is_global, metadata_id, option_count } — to every choice-style column, so a schema dump answers "what can this column contain, and is the list shared?" without a call per column. The option values themselves are deliberately excluded; read them per column with get_picklist_options.

Failure behavior

Reading OptionSet data turns get_entity_schema from one metadata request into five, so the two tools handle a failing request differently — in both cases so that an unknown answer is never presented as a definite one:

  • get_entity_schema degrades. The base attribute list is the tool's contract and does not depend on OptionSets, so a failing lookup no longer costs the caller the column list. The partial coverage is reported in a second content block (the JSON stays in the first), because a silently missing option_set would read as "this column has no options". A failure of the base request itself still fails the call.
  • get_picklist_options fails hard. There, an empty result means "not a choice column", so swallowing an error would turn a transient failure into a confident Choice attribute not found on a column that does exist. For the same reason a matched column whose OptionSet did not come back is an error rather than a default of is_global: false.

Notes

Verified live against a real org: a column bound to a global set reports is_global: true with the global set's own metadata_id, while a locally-defined column reports is_global: false with an auto-generated name.

Two Web API details found during that verification, both encoded in src/tools/optionset-utils.ts:

  • OptionSet is only reachable through a type cast, and the cast must name a concrete type. Casting to the abstract base — /Attributes/Microsoft.Dynamics.CRM.EnumAttributeMetadata — is rejected with HTTP 500 0x8006088a: Unexpected attribute type, despite the docs listing it as a GET-able entity type. Each concrete choice type is therefore requested separately.
  • The sibling GlobalOptionSet navigation property is not a usable binding signal: for a locally-defined column it resolves to that column's own local set rather than returning null, so it cannot tell the two cases apart. IsGlobal on the expanded OptionSet is the reliable indicator.