From d2d88818db133d4101cabc01e8387b0987625bd2 Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Sun, 26 Jul 2026 07:24:13 -0700 Subject: [PATCH] generate turso:// URLs for Turso databases Databases identified as Turso (via the UUID type byte) now display turso:// URLs instead of libsql:// in db list, db show, and the shell banner. The built-in shell also accepts turso:// URLs, rewriting the scheme to libsql before handing it to libsql-shell-go, which only understands libsql/ws/http schemes. The shell library is quite legacy at this point, and we should be moving the CLI to the tursodb binary anyway, so for now we just hack the scheme rewrite here rather than teaching the library about turso://. Co-Authored-By: Claude Fable 5 --- internal/cmd/db_shell.go | 4 +++ internal/cmd/list_databases_test.go | 2 +- internal/cmd/utils.go | 3 +++ internal/cmd/utils_test.go | 39 +++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 internal/cmd/utils_test.go diff --git a/internal/cmd/db_shell.go b/internal/cmd/db_shell.go index 0d516a8b..64cd57ac 100644 --- a/internal/cmd/db_shell.go +++ b/internal/cmd/db_shell.go @@ -166,6 +166,10 @@ var shellCmd = &cobra.Command{ if err != nil { return err } + // the shell library only understands libsql/ws/http schemes + if u.Scheme == "turso" { + u.Scheme = "libsql" + } query := u.Query() authTokenSnake := query.Get("auth_token") authTokenCamel := query.Get("authToken") diff --git a/internal/cmd/list_databases_test.go b/internal/cmd/list_databases_test.go index 2126103c..99021755 100644 --- a/internal/cmd/list_databases_test.go +++ b/internal/cmd/list_databases_test.go @@ -29,7 +29,7 @@ func TestDbListModelViewIncludesTypeColumn(t *testing.T) { expected := [][]string{ {"NAME", "TYPE", "GROUP", "URL"}, {"sqlite-db", "SQLite", "-", "libsql://sqlite-db.example.com"}, - {"turso-db", "Turso", "default", "libsql://turso-db.example.com"}, + {"turso-db", "Turso", "default", "turso://turso-db.example.com"}, } if len(lines) != len(expected) { diff --git a/internal/cmd/utils.go b/internal/cmd/utils.go index 87e4fe38..d83c600c 100644 --- a/internal/cmd/utils.go +++ b/internal/cmd/utils.go @@ -81,6 +81,9 @@ func extractPrimary(instances []turso.Instance) (primary *turso.Instance, others } func getDatabaseUrl(db *turso.Database) string { + if isTursoDB(db.ID) { + return getUrl(db, nil, "turso") + } return getUrl(db, nil, "libsql") } diff --git a/internal/cmd/utils_test.go b/internal/cmd/utils_test.go new file mode 100644 index 00000000..0df97269 --- /dev/null +++ b/internal/cmd/utils_test.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "testing" + + "github.com/tursodatabase/turso-cli/internal/turso" +) + +func TestGetDatabaseUrl(t *testing.T) { + tests := []struct { + name string + db turso.Database + want string + }{ + { + name: "turso database", + db: turso.Database{ID: "019db7a2-9210-79e5-afed-0b1755901d50", Hostname: "turso-db.example.com"}, + want: "turso://turso-db.example.com", + }, + { + name: "sqlite database", + db: turso.Database{ID: "00000000-1100-0000-0000-000000000000", Hostname: "sqlite-db.example.com"}, + want: "libsql://sqlite-db.example.com", + }, + { + name: "no id", + db: turso.Database{Hostname: "db.example.com"}, + want: "libsql://db.example.com", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getDatabaseUrl(&tt.db); got != tt.want { + t.Fatalf("getDatabaseUrl() = %q, want %q", got, tt.want) + } + }) + } +}