Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "opencode-theme-editor",
"private": true,
"version": "1.2.1",
"version": "1.2.2",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
48 changes: 43 additions & 5 deletions public/import-export.sh
Original file line number Diff line number Diff line change
Expand Up @@ -547,15 +547,56 @@ def parse_color(value: str):
raise SystemExit(f'cannot encode unsupported color value: {value}')


def try_parse_color(value: str):
try:
return parse_color(value)
except SystemExit:
return None


def resolve_theme_token_color(value: str, defs: dict, token: str, visited_defs=None):
direct_color = try_parse_color(value)

if direct_color is not None:
return rgba_to_color(*direct_color)

if value not in defs:
raise SystemExit(f'token {token} must be a color literal, transparent, or a name from defs')

if visited_defs is None:
visited_defs = set()

if value in visited_defs:
raise SystemExit(f'token {token} has a circular defs reference at {value}')

next_value = defs[value]

if not isinstance(next_value, str):
raise SystemExit(f'defs.{value} must resolve to a string color value')

next_visited_defs = set(visited_defs)
next_visited_defs.add(value)

return resolve_theme_token_color(next_value, defs, token, next_visited_defs)


def normalize_theme_file(data: dict):
if not isinstance(data, dict):
raise SystemExit('theme JSON must be an object')

raw_theme = data.get('theme')
raw_defs = data.get('defs')

if not isinstance(raw_theme, dict):
raise SystemExit('theme JSON must contain a theme object')

if raw_defs is None:
defs = {}
elif isinstance(raw_defs, dict):
defs = raw_defs
else:
raise SystemExit('theme JSON defs must be an object when provided')

normalized_theme = {}

for token in TOKEN_NAMES:
Expand All @@ -580,12 +621,9 @@ def normalize_theme_file(data: dict):
if not isinstance(dark, str) or not isinstance(light, str):
raise SystemExit(f'theme token {token} must contain color strings')

dark_rgba = parse_color(dark)
light_rgba = parse_color(light)

normalized_theme[token] = {
'dark': rgba_to_color(*dark_rgba),
'light': rgba_to_color(*light_rgba),
'dark': resolve_theme_token_color(dark, defs, token),
'light': resolve_theme_token_color(light, defs, token),
}

return {
Expand Down
Loading