Update extension metadata in registry, merging with existing entry. Merges the provided metadata with the existing entry, preserving any fields not specified in the new metadata. The installed_at timestamp is always preserved from the original entry. Use this method
(self, extension_id: str, metadata: dict)
| 509 | self._save() |
| 510 | |
| 511 | def update(self, extension_id: str, metadata: dict): |
| 512 | """Update extension metadata in registry, merging with existing entry. |
| 513 | |
| 514 | Merges the provided metadata with the existing entry, preserving any |
| 515 | fields not specified in the new metadata. The installed_at timestamp |
| 516 | is always preserved from the original entry. |
| 517 | |
| 518 | Use this method instead of add() when updating existing extension |
| 519 | metadata (e.g., enabling/disabling) to preserve the original |
| 520 | installation timestamp and other existing fields. |
| 521 | |
| 522 | Args: |
| 523 | extension_id: Extension ID |
| 524 | metadata: Extension metadata fields to update (merged with existing) |
| 525 | |
| 526 | Raises: |
| 527 | KeyError: If extension is not installed |
| 528 | """ |
| 529 | extensions = self.data.get("extensions") |
| 530 | if not isinstance(extensions, dict) or extension_id not in extensions: |
| 531 | raise KeyError(f"Extension '{extension_id}' is not installed") |
| 532 | # Merge new metadata with existing, preserving original installed_at |
| 533 | existing = extensions[extension_id] |
| 534 | # Handle corrupted registry entries (e.g., string/list instead of dict) |
| 535 | if not isinstance(existing, dict): |
| 536 | existing = {} |
| 537 | # Merge: existing fields preserved, new fields override (deep copy to prevent caller mutation) |
| 538 | merged = {**existing, **copy.deepcopy(metadata)} |
| 539 | # Always preserve original installed_at based on key existence, not truthiness, |
| 540 | # to handle cases where the field exists but may be falsy (legacy/corruption) |
| 541 | if "installed_at" in existing: |
| 542 | merged["installed_at"] = existing["installed_at"] |
| 543 | else: |
| 544 | # If not present in existing, explicitly remove from merged if caller provided it |
| 545 | merged.pop("installed_at", None) |
| 546 | extensions[extension_id] = merged |
| 547 | self._save() |
| 548 | |
| 549 | def restore(self, extension_id: str, metadata: dict): |
| 550 | """Restore extension metadata to registry without modifying timestamps. |