11import os from "node:os" ;
22import path from "node:path" ;
3- import { cancel , confirm , isCancel , log , spinner , text } from "@clack/prompts" ;
3+ import {
4+ cancel ,
5+ confirm ,
6+ isCancel ,
7+ log ,
8+ select ,
9+ spinner ,
10+ text ,
11+ } from "@clack/prompts" ;
412import { $ } from "execa" ;
513import fs from "fs-extra" ;
614import pc from "picocolors" ;
715
8- interface TursoConfig {
16+ type TursoConfig = {
917 dbUrl : string ;
1018 authToken : string ;
11- }
19+ } ;
20+
21+ type TursoGroup = {
22+ name : string ;
23+ locations : string ;
24+ version : string ;
25+ status : string ;
26+ } ;
1227
1328async function isTursoInstalled ( ) {
1429 try {
15- await $ `turso --version` ;
16- return true ;
17- } catch {
30+ const result = await $ `turso --version` ;
31+ return result . exitCode === 0 ;
32+ } catch ( error ) {
1833 return false ;
1934 }
2035}
@@ -67,9 +82,66 @@ async function installTursoCLI(isMac: boolean) {
6782 }
6883}
6984
70- async function createTursoDatabase ( dbName : string ) : Promise < TursoConfig > {
85+ async function getTursoGroups ( ) : Promise < TursoGroup [ ] > {
86+ try {
87+ const { stdout } = await $ `turso group list` ;
88+ const lines = stdout . trim ( ) . split ( "\n" ) ;
89+
90+ if ( lines . length <= 1 ) {
91+ return [ ] ;
92+ }
93+
94+ const groups = lines . slice ( 1 ) . map ( ( line ) => {
95+ const [ name , locations , version , status ] = line . trim ( ) . split ( / \s { 2 , } / ) ;
96+ return { name, locations, version, status } ;
97+ } ) ;
98+
99+ return groups ;
100+ } catch ( error ) {
101+ console . error ( "Error fetching Turso groups:" , error ) ;
102+ return [ ] ;
103+ }
104+ }
105+
106+ async function selectTursoGroup ( ) : Promise < string | null > {
107+ const groups = await getTursoGroups ( ) ;
108+
109+ if ( groups . length === 0 ) {
110+ return null ;
111+ }
112+
113+ if ( groups . length === 1 ) {
114+ return groups [ 0 ] . name ;
115+ }
116+
117+ const groupOptions = groups . map ( ( group ) => ( {
118+ value : group . name ,
119+ label : `${ group . name } (${ group . locations } )` ,
120+ } ) ) ;
121+
122+ const selectedGroup = await select ( {
123+ message : "Select a Turso database group:" ,
124+ options : groupOptions ,
125+ } ) ;
126+
127+ if ( isCancel ( selectedGroup ) ) {
128+ cancel ( pc . red ( "Operation cancelled" ) ) ;
129+ process . exit ( 0 ) ;
130+ }
131+
132+ return selectedGroup as string ;
133+ }
134+
135+ async function createTursoDatabase (
136+ dbName : string ,
137+ groupName : string | null ,
138+ ) : Promise < TursoConfig > {
71139 try {
72- await $ `turso db create ${ dbName } ` ;
140+ if ( groupName ) {
141+ await $ `turso db create ${ dbName } --group ${ groupName } ` ;
142+ } else {
143+ await $ `turso db create ${ dbName } ` ;
144+ }
73145 } catch ( error ) {
74146 if ( error instanceof Error && error . message . includes ( "already exists" ) ) {
75147 throw new Error ( "DATABASE_EXISTS" ) ;
@@ -159,6 +231,8 @@ export async function setupTurso(
159231 await loginToTurso ( ) ;
160232 }
161233
234+ const selectedGroup = await selectTursoGroup ( ) ;
235+
162236 let success = false ;
163237 let dbName = "" ;
164238 let suggestedName = path . basename ( projectDir ) ;
@@ -180,8 +254,10 @@ export async function setupTurso(
180254 const s = spinner ( ) ;
181255
182256 try {
183- s . start ( `Creating Turso database "${ dbName } "...` ) ;
184- const config = await createTursoDatabase ( dbName ) ;
257+ s . start (
258+ `Creating Turso database "${ dbName } "${ selectedGroup ? ` in group "${ selectedGroup } "` : "" } ...` ,
259+ ) ;
260+ const config = await createTursoDatabase ( dbName , selectedGroup ) ;
185261 await writeEnvFile ( projectDir , config ) ;
186262 s . stop ( "Turso database configured successfully!" ) ;
187263 success = true ;
0 commit comments