package handlers import ( "encoding/json" "fmt" "go.starlark.net/starlark" ) // jsonToStarlark converts an arbitrary Go value (typically from JSON unmarshal) // to a Starlark value for passing into extension scripts. func jsonToStarlark(v any) starlark.Value { switch val := v.(type) { case nil: return starlark.None case bool: return starlark.Bool(val) case float64: if val == float64(int64(val)) { return starlark.MakeInt64(int64(val)) } return starlark.Float(val) case string: return starlark.String(val) case []any: elems := make([]starlark.Value, len(val)) for i, e := range val { elems[i] = jsonToStarlark(e) } return starlark.NewList(elems) case map[string]any: d := starlark.NewDict(len(val)) for k, v := range val { _ = d.SetKey(starlark.String(k), jsonToStarlark(v)) } return d default: return starlark.String(fmt.Sprintf("%v", val)) } } // starlarkValueToGo converts a Starlark value back to a Go value suitable // for JSON serialization. func starlarkValueToGo(v starlark.Value) any { switch val := v.(type) { case starlark.NoneType: return nil case starlark.Bool: return bool(val) case starlark.Int: i, _ := val.Int64() return i case starlark.Float: return float64(val) case starlark.String: return string(val) case *starlark.List: out := make([]any, val.Len()) for i := 0; i < val.Len(); i++ { out[i] = starlarkValueToGo(val.Index(i)) } return out case *starlark.Dict: out := make(map[string]any) for _, item := range val.Items() { k, _ := item[0].(starlark.String) out[string(k)] = starlarkValueToGo(item[1]) } return out default: return v.String() } } // ParseSchemaVersion extracts the schema_version from a package manifest. func ParseSchemaVersion(manifest any) int { switch m := manifest.(type) { case map[string]any: if v, ok := m["schema_version"].(float64); ok { return int(v) } case json.RawMessage: var s struct { SchemaVersion int `json:"schema_version"` } if err := json.Unmarshal(m, &s); err == nil { return s.SchemaVersion } } return 0 } // RunSchemaMigrations runs extension schema migrations between versions. // Stub — full implementation will be added when extension DB schemas are stabilized. func RunSchemaMigrations(ctx any, sandbox any, stores any, db any, isPostgres bool, packageID string, manifest any, fromVersion, toVersion int) error { // TODO: implement extension schema migrations return nil }