AFTE RELEASE feat(customization): typed customization registry via AppTypes.Customizations#6133
AFTE RELEASE feat(customization): typed customization registry via AppTypes.Customizations#6133sedghi wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
✅ Deploy Preview for ohif-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThe customization service now supports declaration-merged customization registries, typed lookup and update payloads, and string fallbacks for unknown keys. URL phase inputs use the typed entry map, and the annotation mode adopts the updated setter call form. ChangesTyped customizations
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Viewers
|
||||||||||||||||||||||||||||
| Project |
Viewers
|
| Branch Review |
ohifTypeOHIFCustomization
|
| Run status |
|
| Run duration | 01m 55s |
| Commit |
|
| Committer | Alireza |
| View all properties for this run ↗︎ | |
| Test results | |
|---|---|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
0
|
|
|
28
|
| View all changes introduced in this branch ↗︎ | |
…stomizations Seeds a declaration-merged AppTypes.Customizations registry so extensions can declare the value type of each customization id they own, and adds typed overloads to getCustomization, getValue, hasCustomization and setCustomizations. Registered ids get autocomplete and precise types; unregistered and dynamic ids keep the existing loose Customization fallback, so nothing breaks. setCustomizations payloads (including immutability-helper command specs and the custom $filter) are checked against the registry through the new CustomizationEntries type, which CustomizationPhaseInput now reuses for phased app-config blocks. Also drops a redundant string 'mode' scope argument in two modes that was mistyped against the CustomizationScope enum (Mode is the default). CUSTOMIZATION_TYPING_PLAN.md documents the design and the follow-up phases for populating the registry across extensions.
21ed32e to
68773e2
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@platform/core/src/services/CustomizationService/customizationUrlTypes.ts`:
- Around line 12-15: Update the CustomizationPhaseInput type alias to accept
arrays containing either string extension references or CustomizationEntries,
while continuing to accept a standalone CustomizationEntries value. Use the
supported shape Array<string | CustomizationEntries> | CustomizationEntries and
leave setCustomizations behavior unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ca0adf0e-4124-49d7-9d2d-3e9de70271d2
📒 Files selected for processing (6)
CUSTOMIZATION_TYPING_PLAN.mdmodes/usAnnotation/src/index.tsplatform/core/src/services/CustomizationService/CustomizationService.tsplatform/core/src/services/CustomizationService/customizationUrlTypes.tsplatform/core/src/services/CustomizationService/types.tsplatform/core/src/types/AppTypes.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- platform/core/src/types/AppTypes.ts
- platform/core/src/services/CustomizationService/types.ts
- modes/usAnnotation/src/index.ts
- platform/core/src/services/CustomizationService/CustomizationService.ts
| * - an array that mixes string references (extension module ids resolved via | ||
| * the ExtensionManager) and inline object maps. | ||
| */ | ||
| export type CustomizationPhaseInput = string[] | Record<string, any>; | ||
| export type CustomizationPhaseInput = string[] | CustomizationEntries; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the target file and nearby declarations
ast-grep outline platform/core/src/services/CustomizationService/customizationUrlTypes.ts --view expanded || true
echo
echo "---- file ----"
cat -n platform/core/src/services/CustomizationService/customizationUrlTypes.ts | sed -n '1,120p'
echo
echo "---- usages ----"
rg -n "CustomizationPhaseInput|CustomizationEntries|setCustomizations|customizationUrlTypes" platform/core/src/services -SRepository: OHIF/Viewers
Length of output: 12915
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect consumer code paths that build or consume customization phase inputs
rg -n "setCustomizations\(|CustomizationPhaseInput|CustomizationEntries|customization.*phase|mixed arrays|ExtensionManager" platform/core/src -SRepository: OHIF/Viewers
Length of output: 14270
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the related service implementation if present
fd -a "CustomizationService" platform/core/src/servicesRepository: OHIF/Viewers
Length of output: 820
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the current commit context for the file if available
git status --short
git rev-parse --short HEADRepository: OHIF/Viewers
Length of output: 160
🏁 Script executed:
#!/bin/bash
set -euo pipefail
cat -n platform/core/src/services/CustomizationService/customizationUrlTypes.ts | sed -n '1,120p'Repository: OHIF/Viewers
Length of output: 3094
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the implementation and nearby tests for array handling
sed -n '600,740p' platform/core/src/services/CustomizationService/CustomizationService.ts
echo
echo "---- array-related tests ----"
rg -n "string\\[\\]|Array|mixed|reference|customizationModule|setCustomizations\\(" platform/core/src/services/CustomizationService/CustomizationService.*test* platform/core/src/services/CustomizationService/CustomizationService.ts -SRepository: OHIF/Viewers
Length of output: 25504
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect how URL customization payloads are normalized before reaching setCustomizations
sed -n '900,1010p' platform/core/src/services/CustomizationService/CustomizationService.ts
echo
echo "---- related payload helpers ----"
sed -n '1,220p' platform/core/src/services/CustomizationService/getUrlCustomizationModulePayload.ts
echo
echo "---- phase input definitions ----"
sed -n '1,220p' platform/core/src/services/CustomizationService/types.tsRepository: OHIF/Viewers
Length of output: 8762
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
text = Path('platform/core/src/services/CustomizationService/CustomizationService.ts').read_text()
for needle in [
'public setCustomizations(',
'Array.isArray(customizations)',
'typeof customizations',
'this._extensionManager',
'resolveCustomization',
]:
idx = text.find(needle)
print(f"\n### {needle} @ {idx}")
if idx != -1:
start = max(0, idx - 500)
end = min(len(text), idx + 1500)
print(text[start:end])
PYRepository: OHIF/Viewers
Length of output: 6332
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Quick structural scan for where phase inputs are consumed
ast-grep run --pattern 'setCustomizations($$$)' --lang typescript platform/core/src/services/CustomizationService/CustomizationService.tsRepository: OHIF/Viewers
Length of output: 150
Widen the phase-input type to match the supported array shape. setCustomizations already processes array items one by one, so phase blocks can include both string references and inline customization maps. CustomizationPhaseInput currently narrows that to string[], which rejects a documented valid form; change it to Array<string | CustomizationEntries> | CustomizationEntries.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@platform/core/src/services/CustomizationService/customizationUrlTypes.ts`
around lines 12 - 15, Update the CustomizationPhaseInput type alias to accept
arrays containing either string extension references or CustomizationEntries,
while continuing to accept a standalone CustomizationEntries value. Use the
supported shape Array<string | CustomizationEntries> | CustomizationEntries and
leave setCustomizations behavior unchanged.
Context
The CustomizationService exposes ~90 customization ids, but
getCustomization(id)returns the looseCustomizationunion for all of them. There is no discoverability of which ids exist or what shape each expects, and consumers compensate with ~20as unknown as X/as anycasts across the repo.setCustomizationspayloads (including$set/$pushcommand specs used by modes and app config) are not checked at all.Changes
This PR adds the typing infrastructure (no per-key population yet, and no runtime changes):
AppTypes.Customizationsregistry — an empty, declaration-merged global interface inplatform/core/src/types/AppTypes.ts, following the exact pattern already used byAppTypes.ServicesandPresentationIds. Each extension (in-tree or third-party) declares the ids it owns:Typed overloads on
getCustomization,getValue, andhasCustomization: registered ids get autocomplete and their declared return type; any other string (dynamic keys, undeclared third-party keys) falls back to the existingCustomization | undefinedsignature, so nothing breaks.Checked
setCustomizationspayloads via the newCustomizationEntriestype: registered ids accept their declared value directly or as an immutability-helper spec ({ $set: ... },{ $push: [...] }, the custom$filter, ...).CustomizationPhaseInputreuses it, so phase-taggedappConfig.customizationServiceblocks written in TypeScript are checked the same way.Two small call-site fixes:
usAnnotationandbasic-test-modepassed the raw string'mode'where theCustomizationScopeenum is expected (Mode is already the default scope, so the argument is dropped; runtime behavior identical).CUSTOMIZATION_TYPING_PLAN.mddocuments the design, the conventions for declaring keys, and the follow-up phases (populating the registry per extension, then optionally generating the docs table and a JSON Schema for JSONC customization files from the registry).Testing
tscdiffed against a pre-change baseline: three pre-existing false positives fixed (valid customization objects rejected by the oldRecord<string, Customization>input type), zero new errors.$pushof wrong element type rejected,$filteraccepted, unknown keys and string module refs still compiling) under both the repo compiler settings and--strict.Summary by CodeRabbit
New Features
Documentation