summaryrefslogtreecommitdiff
path: root/scripts/generate_ts_schema.py
blob: 1997c55eef9d162b8d3af12ff549d6e7c497cd71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env python3
"""
Generate TypeScript schema from Python shared_config.py

This script reads the canonical schema from shared_config.py and generates
the corresponding TypeScript files, ensuring single source of truth.
"""

import sys
from pathlib import Path

# Add project root to path to import shared_config
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from shared_config import CONFIG_SCHEMA_DEF, ConfigFieldType


def generate_typescript_schema():
    """Generate generatedConfigSchema.ts from Python schema"""
    
    # Generate enum
    enum_lines = [
        "// src/config/generatedConfigSchema.ts",
        "// Configuration field type enum - matches Python",
        "export enum ConfigFieldType {",
        "  BOOLEAN = \"boolean\",",
        "  INTEGER = \"integer\",", 
        "  FLOAT = \"float\",",
        "  STRING = \"string\"",
        "}",
        "",
        "// Configuration field definition",
        "export interface ConfigField {",
        "  name: string;",
        "  fieldType: ConfigFieldType;",
        "  default: boolean | number | string;",
        "  description: string;",
        "}",
        "",
        "// Configuration schema - auto-generated from Python",
        "export const CONFIG_SCHEMA: Record<string, ConfigField> = {"
    ]
    
    # Generate schema entries
    schema_entries = []
    interface_fields = []
    defaults_fields = []
    field_types = []
    
    for field_name, field_def in CONFIG_SCHEMA_DEF.items():
        # Schema entry
        default_value = field_def["default"]
        if isinstance(default_value, str):
            default_str = f'"{default_value}"'
        elif isinstance(default_value, bool):
            default_str = "true" if default_value else "false"
        else:
            default_str = str(default_value)
            
        schema_entries.append(f'  {field_name}: {{')
        schema_entries.append(f'    name: "{field_def["name"]}",')
        schema_entries.append(f'    fieldType: ConfigFieldType.{field_def["fieldType"].upper()},')
        schema_entries.append(f'    default: {default_str},')
        schema_entries.append(f'    description: "{field_def["description"]}"')
        schema_entries.append('  },')
        
        # Interface field
        if field_def["fieldType"] == ConfigFieldType.BOOLEAN:
            ts_type = "boolean"
        elif field_def["fieldType"] == ConfigFieldType.INTEGER:
            ts_type = "number"
        elif field_def["fieldType"] == ConfigFieldType.FLOAT:
            ts_type = "number"
        elif field_def["fieldType"] == ConfigFieldType.STRING:
            ts_type = "string"
        else:
            ts_type = "any"
            
        interface_fields.append(f'  {field_name}: {ts_type};')
        defaults_fields.append(f'    {field_name}: {default_str},')
        field_types.append(f'    {field_name}: ConfigFieldType.{field_def["fieldType"].upper()},')
    
    # Complete the file
    all_lines = enum_lines + schema_entries + [
        "};",
        "",
        "// Type-safe configuration data structure", 
        "export interface ConfigurationData {",
    ] + interface_fields + [
        "}",
        "",
        "// Helper functions",
        "export function getFieldNames(): string[] {",
        "  return Object.keys(CONFIG_SCHEMA);",
        "}",
        "",
        "export function getDefaults(): ConfigurationData {",
        "  return {",
    ] + defaults_fields + [
        "  };",
        "}",
        "",
        "export function getFieldTypes(): Record<string, ConfigFieldType> {",
        "  return {",
    ] + field_types + [
        "  };",
        "}",
        "",
        ""
    ]
    
    return "\n".join(all_lines)


def main():
    """Main function to generate TypeScript schema and Python boilerplate"""
    try:
        # Generate the TypeScript content
        ts_content = generate_typescript_schema()
        
        # Write to the target file
        target_file = project_root / "src" / "config" / "generatedConfigSchema.ts"
        target_file.write_text(ts_content)
        
        print(f"āœ… Generated {target_file} from shared_config.py")
        print(f"   Fields: {len(CONFIG_SCHEMA_DEF)}")
        
        # Also generate Python boilerplate
        print("\nšŸ”„ Generating Python boilerplate...")
        from pathlib import Path
        import subprocess
        
        boilerplate_script = project_root / "scripts" / "generate_python_boilerplate.py"
        result = subprocess.run([sys.executable, str(boilerplate_script)], 
                              capture_output=True, text=True)
        
        if result.returncode == 0:
            print(result.stdout)
        else:
            print(f"āš ļø  Python boilerplate generation had issues:\n{result.stderr}")
        
    except Exception as e:
        print(f"āŒ Error generating schema: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()