refactor: centralize shared utilities across backend and frontend

Backend:
- Move SHA256 normalization logic from path_utils._normalize_header_sha256
  into core/type_utils.normalize_sha256, adding support for 0x-prefixed
  hashes and unifying the normalization path used by
  extract_safetensors_header_sha256.
- Add tests for the 0x prefix normalization cases.

Frontend:
- Introduce copyTextWithFeedback in web/resolver/utils/html_utils.js
  as a shared clipboard helper with configurable feedback text, CSS class,
  and duration, replacing repeated inline clipboard copy logic in
  globals.js, model_info_methods.js, and the notification utility.
- Centralize showNotification on ResolverManagerDialog and remove the
  duplicate implementation from missingBrowserMethods.
- Replace local const localStorage = safeStorage aliases in
  model_info_methods.js, missing_browser_methods.js, and
  options_methods.js with direct safeStorage usage.
This commit is contained in:
Dariusz L
2026-07-17 18:06:22 +02:00
parent 28d24214aa
commit be12494953
9 changed files with 109 additions and 103 deletions
+4 -25
View File
@@ -292,29 +292,6 @@ SAFETENSORS_METADATA_TEXT_MAX_CHARS = 20000
SAFETENSORS_METADATA_THUMBNAIL_MAX_CHARS = 512 * 1024
def _normalize_header_sha256(value: Any) -> str:
if not isinstance(value, str):
return ""
candidate = value.strip()
lower_candidate = candidate.lower()
if lower_candidate.startswith("sha256:") or lower_candidate.startswith("sha256="):
if ":" in candidate:
candidate = candidate.split(":", 1)[-1]
else:
candidate = candidate.split("=", 1)[-1]
candidate = candidate.strip()
lower_candidate = candidate.lower()
if lower_candidate.startswith("0x"):
candidate = candidate[2:].strip()
if len(candidate) != 64:
return ""
if any(char not in _SHA256_HEX_CHARS for char in candidate):
return ""
return candidate.lower()
def read_safetensors_header(
file_path: str,
@@ -368,6 +345,8 @@ def extract_safetensors_header_sha256(
max_header_size: int = SAFETENSORS_HEADER_MAX_BYTES,
) -> Optional[str]:
"""Return an embedded SHA256 from a safetensors metadata header when present."""
from .type_utils import normalize_sha256
header_json = read_safetensors_header(file_path, max_header_size=max_header_size)
if not isinstance(header_json, dict):
return None
@@ -382,7 +361,7 @@ def extract_safetensors_header_sha256(
"sha256",
"SHA256",
):
sha256 = _normalize_header_sha256(metadata.get(key))
sha256 = normalize_sha256(metadata.get(key))
if sha256:
return sha256
@@ -396,7 +375,7 @@ def extract_safetensors_header_sha256(
continue
if any(part in key_lower for part in _NON_SHA256_HASH_KEY_PARTS):
continue
sha256 = _normalize_header_sha256(value)
sha256 = normalize_sha256(value)
if sha256:
return sha256