Files
boxofficefantasy/scripts/generate_js_constants.py
Anthony Correa baddca8d50 Refactor draft app with improved state management and components
* Rename WebSocket message types for better organization
* Improve state handling with dedicated methods like broadcast_state
* Restructure frontend components and remove unused code
2025-08-24 12:06:41 -05:00

103 lines
3.3 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
import importlib
import inspect
import os
import sys
from enum import Enum, IntEnum, StrEnum
# Adjust these for your project
PY_MODULE = "draft.constants" # where your enums live
OUTPUT_PATH = "frontend/src/apps/draft/constants.js"
# Optionally allow running from any cwd
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(PROJECT_ROOT, ".."))
if PROJECT_ROOT not in sys.path:
sys.path.insert(0, PROJECT_ROOT)
def js_quote(s: str) -> str:
return s.replace("\\", "\\\\").replace('"', '\\"')
def titleize(name: str) -> str:
# e.g., "DETERMINE_ORDER" -> "Determine Order"
return name.replace("_", " ").title()
def emit_header():
return "// AUTO-GENERATED. Do not edit by hand.\n" \
"// Run: python scripts/generate_js_constants.py\n\n"
def emit_str_enum(name: str, enum_cls) -> str:
"""
Emit a JS object for StrEnum:
export const DraftMessage = { KEY: "value", ... };
"""
lines = [f"export const {name} = {{"] # ESM export
for member in enum_cls:
lines.append(f' {member.name}: "{js_quote(member.value)}",')
lines.append("};\n")
return "\n".join(lines)
def emit_int_enum(name: str, enum_cls) -> str:
"""
Emit a JS object + labels + ordered list for IntEnum:
export const DraftPhase = { KEY: number, ... };
export const DraftPhaseLabel = { [number]: "Pretty", ... };
export const DraftPhasesOrdered = [numbers...];
"""
lines = [f"export const {name} = {{"] # ESM export
items = list(enum_cls)
# object map
for member in items:
lines.append(f" {member.name}: {int(member.value)},")
lines.append("};\n")
# label map (use .pretty_name if you added it; else derive from name or __str__)
lines.append(f"export const {name}Label = {{")
for member in items:
if hasattr(member, "pretty_name"):
label = getattr(member, "pretty_name")
else:
# fall back: __str__ if you overload it, else Title Case of name
label = str(member)
if label == f"{enum_cls.__name__}.{member.name}":
label = titleize(member.name)
lines.append(f' [{name}.{member.name}]: "{js_quote(label)}",')
lines.append("};\n")
# ordered list
ordered = sorted(items, key=lambda m: int(m.value))
ordered_vals = ", ".join(f"{name}.{m.name}" for m in ordered)
lines.append(f"export const {name}sOrdered = [{ordered_vals}];\n")
return "\n".join(lines)
def main():
mod = importlib.import_module(PY_MODULE)
out = [emit_header()]
# Pick which enums to export. You can filter here if you dont want all.
for name, obj in inspect.getmembers(mod):
ignore_classes = [Enum, IntEnum, StrEnum]
if inspect.isclass(obj) and issubclass(obj, Enum) and not obj in ignore_classes:
# Skip helper classes that arent actual Enums
if name.startswith("_"):
continue
if issubclass(obj, IntEnum):
out.append(emit_int_enum(name, obj))
else:
out.append(emit_str_enum(name, obj))
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
f.write("\n".join(out))
print(f"✅ Wrote {OUTPUT_PATH}")
if __name__ == "__main__":
main()