Skip to content

Generate typings for multi-select picklist, file and image columns via AttributeTypeName#333

Open
Cordedmink2 wants to merge 5 commits into
Power-Maverick:mainfrom
Cordedmink2:fix/multiselect-typings-generation
Open

Generate typings for multi-select picklist, file and image columns via AttributeTypeName#333
Cordedmink2 wants to merge 5 commits into
Power-Maverick:mainfrom
Cordedmink2:fix/multiselect-typings-generation

Conversation

@Cordedmink2

Copy link
Copy Markdown

Problem

Generating typings for an entity with multi-select picklist (Choices) columns produces their option-value enums but no getAttribute/getControl signatures — addresses #313 (closed by the stale bot; I'm the original reporter and this delivers the PR discussed there). Root cause: generation filters on the legacy AttributeType property, where multi-select, file and image columns all report Virtual, so they were dropped before the type maps were ever consulted. Microsoft's guidance is to use AttributeTypeName for anything newer than the original 2011 type set.

Changes

  • Typing generation is re-keyed on AttributeTypeName.Value with a whitelist map: multi-selects map to Attributes.MultiSelectOptionSetAttribute / Controls.MultiSelectOptionSetControl, booleans now get Controls.BooleanControl (previously generic StandardControl), and file/image columns are included with conservative fallback types (Attributes.Attribute / Controls.StandardControl) since @types/xrm has no dedicated interfaces for them. The docs list file/image as valid getAttributeType() values but don't document their getControlType(); these fallbacks are deliberately conservative, and I'll follow up with observed runtime values from a live form.
  • Form eligibility now comes from the IsValidForForm metadata property instead of being inferred from type names.
  • Deliberate behavior change — generated output shrinks: attributes that can never be retrieved via formContext.getAttribute() are no longer emitted. Dropped categories: primary ids / uniqueidentifier, entityname, managedproperty, calendarrules, plain virtual companion columns (e.g. *name shadows), and bigint (absent from the documented getAttributeType() values, and JS numbers can't safely hold all 64-bit values). Previously these were emitted with misleading types — e.g. accountid typed as StringAttribute when getAttribute("accountid") returns null at runtime. Projects referencing those signatures will see compile errors after regenerating; that's the output telling the truth now.
  • Option-value enums are derived from the same filtered attribute set as the signatures, so enum/signature output can no longer disagree (the inverse of the [Bug]: MultiSelectPicklistAttribute attributes fail to generate when generating typings. #313 symptom); statecode/statuscode enums resolve directly from those attributes rather than via their AttributeOf companion columns.
  • Fixed a latent race: enum-resolution promises were fired via .forEach(async ...) and never awaited before the file was emitted — they only landed in the output because the directory QuickPick stalls long enough. Resolution is now awaited (Promise.all) with a regression test.
  • Generation logic extracted to a vscode-free src/helpers/typingsBuilder.ts with mocha unit tests (npm run test:unit, 11 tests). The new script exists because the current pretest/test chain can't run: pretest calls a nonexistent compile-tests script, tsconfig.json excludes src/test/**, and runTest.ts imports the legacy vscode-test package. That harness is left untouched here; test:unit is additive and reuses the existing mocha devDependency.
  • All three project templates now require @types/xrm ^9.0.68 — the minimum version containing MultiSelectOptionSetAttribute/MultiSelectOptionSetControl (9.0.68) and BooleanControl (9.0.63). Without this, freshly generated typings don't compile in scaffolded projects. Note on the lockfile diff: the TypeScript template's package-lock.json shows ~4,800 changed lines because npm ≥7 can't write lockfileVersion: 1 — the regeneration upgrades it to v2 (readable by npm 6+). The real change is just the @types/xrm bump.

Known limitation

IsValidForForm means a column can be placed on a form — getAttribute/getControl still return null at runtime when the column isn't on the loaded form. Generated signatures stay non-null, matching @types/xrm@9.0.68's own base signatures and the tool's existing behavior.

Testing

  • npm run compile, npm run lint (no new warnings), and npm run test:unit (11 tests: type-map coverage, filter exclusions, sort determinism, input non-mutation, resolver scoping, race regression, emitted-signature assertions) all pass.
  • Sample generated output compiles under tsc --strict against exactly @types/xrm@9.0.68, and fails against 9.0.41 with the expected missing-member errors — confirming the template bump is required.
  • Metadata behavior verified against a live Dataverse environment: multi-select (29 columns), file (146) and image (65) columns all report legacy AttributeType = "Virtual"; statecode/statuscode report StateType/StatusType with IsValidForForm = true; primary ids report IsValidForForm = false.

Copilot AI review requested due to automatic review settings July 15, 2026 07:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Dataverse typings generator to key off AttributeTypeName.Value (instead of legacy AttributeType) so newer column types like multi-select picklists, file, and image columns are correctly included in generated getAttribute/getControl signatures. It also makes form-eligibility filtering use IsValidForForm, fixes an async enum-resolution race, and introduces a VS Code–independent builder with unit tests.

Changes:

  • Reworked typings generation via a new typingsBuilder helper that maps AttributeTypeName.Value to @types/xrm attribute/control types (including multi-select) and filters output using IsValidForForm.
  • Fixed enum generation ordering/race by awaiting enum-resolution work and aligned enum emission with the same filtered attribute set as signature generation.
  • Added a Node-friendly unit-test harness (tsconfig.tests.json, test:unit, mocha tests) and bumped template @types/xrm to ^9.0.68 to ensure scaffolded projects compile with the new signatures.

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tsconfig.tests.json Adds a dedicated TS config for compiling mocha unit tests to out-tests.
src/utils/Interfaces.ts Extends attribute metadata typing with IsValidForForm used by the generator filter.
src/test/unit/typingsBuilder.test.ts Adds unit coverage for filtering, mapping, enum resolution awaiting, and emitted output.
src/helpers/typingsHelper.ts Switches VS Code command path to call the new builder and write emitted typings output.
src/helpers/typingsBuilder.ts New core builder: filtering, type mapping keyed by AttributeTypeName.Value, enum generation, and emission.
resources/templates/Webpack/package.json Bumps @types/xrm to a version that includes multi-select and BooleanControl typings.
resources/templates/TypeScript/package.json Bumps @types/xrm to ^9.0.68.
resources/templates/JavaScript/package.json Bumps @types/xrm to ^9.0.68.
package.json Adds test:unit script to compile/run mocha unit tests.
.gitignore Ignores the unit-test build output directory out-tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Cordedmink2

Copy link
Copy Markdown
Author

@Power-Maverick This ok?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants