11#!/usr/bin/env node
2-
32import { cancel , confirm , group , intro , outro , select , spinner , text } from "@clack/prompts" ;
43import { cpSync , existsSync , mkdtempSync , readFileSync , rmSync , writeFileSync } from "fs" ;
54import { tmpdir } from "os" ;
@@ -215,8 +214,16 @@ function checkD1DatabaseExists(databaseName: string, cwd: string, accountId?: st
215214 return false ;
216215 }
217216
218- const result = runWranglerCommand ( [ "d1" , "info" , databaseName ] , cwd , accountId ) ;
219- return result . code === 0 ;
217+ const result = runWranglerCommand ( [ "d1" , "list" , "--json" ] , cwd , accountId ) ;
218+ if ( result . code === 0 ) {
219+ try {
220+ const databases = JSON . parse ( result . stdout ) ;
221+ return databases . some ( ( db : any ) => db . name === databaseName ) ;
222+ } catch {
223+ return false ;
224+ }
225+ }
226+ return false ;
220227}
221228
222229function checkHyperdriveExists ( hyperdriveId : string , cwd : string , accountId ? : string ) : boolean {
@@ -228,6 +235,68 @@ function checkHyperdriveExists(hyperdriveId: string, cwd: string, accountId?: st
228235 return result . code === 0 ;
229236}
230237
238+ // Functions to get IDs of existing resources
239+ function getExistingD1DatabaseId ( databaseName : string , cwd : string , accountId ?: string ) : string | null {
240+ try {
241+ console . log ( `[DEBUG] Attempting to get D1 ID for database: ${ databaseName } ` ) ;
242+ const result = runWranglerCommand ( [ "d1" , "list" , "--json" ] , cwd , accountId ) ;
243+ console . log ( `[DEBUG] D1 list command result - code: ${ result . code } ` ) ;
244+ console . log ( `[DEBUG] D1 list stderr: ${ result . stderr } ` ) ;
245+ console . log ( `[DEBUG] D1 list stdout: ${ result . stdout } ` ) ;
246+ if ( result . code === 0 ) {
247+ // Parse the JSON output to find the database by name
248+ const databases = JSON . parse ( result . stdout ) ;
249+ const database = databases . find ( ( db : any ) => db . name === databaseName ) ;
250+ const extractedId = database ?. uuid || null ;
251+ console . log ( `[DEBUG] Extracted D1 ID: ${ extractedId } ` ) ;
252+ return extractedId ;
253+ }
254+ console . log ( `[DEBUG] D1 list command failed with code: ${ result . code } ` ) ;
255+ return null ;
256+ } catch ( error ) {
257+ console . log ( `[DEBUG] D1 list command threw error: ${ error } ` ) ;
258+ return null ;
259+ }
260+ }
261+
262+ function getExistingKvNamespaceId ( namespaceName : string , cwd : string , accountId ?: string ) : string | null {
263+ try {
264+ const result = runWranglerCommand ( [ "kv" , "namespace" , "list" ] , cwd , accountId ) ;
265+ if ( result . code === 0 ) {
266+ // Parse the JSON output to find the namespace by name
267+ const namespaces = JSON . parse ( result . stdout ) ;
268+ const namespace = namespaces . find ( ( ns : any ) => ns . title === namespaceName ) ;
269+ return namespace ?. id || null ;
270+ }
271+ return null ;
272+ } catch {
273+ return null ;
274+ }
275+ }
276+
277+ function getExistingHyperdriveId ( hyperdriveName : string , cwd : string , accountId ?: string ) : string | null {
278+ try {
279+ const result = runWranglerCommand ( [ "hyperdrive" , "list" ] , cwd , accountId ) ;
280+ if ( result . code === 0 ) {
281+ // Parse the table format from `wrangler hyperdrive list` command
282+ const lines = result . stdout . split ( "\n" ) ;
283+ for ( const line of lines ) {
284+ // Look for a line that contains the hyperdrive name and extract the ID from the first column
285+ if ( line . includes ( hyperdriveName ) ) {
286+ // Extract ID from first column: │ id │ name │ ...
287+ const idMatch = / │ \s * ( [ 0 - 9 a - f ] { 32 } ) \s * │ / . exec ( line ) ;
288+ if ( idMatch ) {
289+ return idMatch [ 1 ] ;
290+ }
291+ }
292+ }
293+ }
294+ return null ;
295+ } catch {
296+ return null ;
297+ }
298+ }
299+
231300function parseAvailableAccounts ( stderr : string ) : Array < { name : string ; id : string } > {
232301 const accounts : Array < { name : string ; id : string } > = [ ] ;
233302 const lines = stderr . split ( "\n" ) ;
@@ -1527,13 +1596,24 @@ export const verification = {} as any;`;
15271596 res . stderr ?. includes ( "already exists" ) || res . stdout ?. includes ( "already exists" ) ;
15281597
15291598 if ( isDatabaseExists ) {
1530- // Database already exists, which is fine - just configure it in wrangler.toml
1531- if ( existsSync ( wranglerPath ) ) {
1532- let wrangler = readFileSync ( wranglerPath , "utf8" ) ;
1533- wrangler = updateD1Block ( wrangler , answers . d1Binding ! , answers . d1Name ) ;
1534- writeFileSync ( wranglerPath , wrangler ) ;
1599+ // Database already exists, which is fine - get its ID and configure it in wrangler.toml
1600+ const existingDatabaseId = getExistingD1DatabaseId ( answers . d1Name , cwd , answers . accountId ) ;
1601+ if ( existingDatabaseId && existsSync ( wranglerPath ) ) {
1602+ debugLog ( `Updating wrangler.toml with existing D1 database ID: ${ existingDatabaseId } ` ) ;
1603+ const currentWrangler = readFileSync ( wranglerPath , "utf-8" ) ;
1604+ const updatedWrangler = updateD1BlockWithId (
1605+ currentWrangler ,
1606+ answers . d1Binding || "DATABASE" ,
1607+ answers . d1Name ,
1608+ existingDatabaseId
1609+ ) ;
1610+ writeFileSync ( wranglerPath , updatedWrangler ) ;
15351611 }
1536- creating . stop ( pc . yellow ( `D1 database already exists (name: ${ answers . d1Name } ).` ) ) ;
1612+ creating . stop (
1613+ pc . yellow (
1614+ `D1 database already exists (name: ${ answers . d1Name } )${ existingDatabaseId ? " (id: " + existingDatabaseId + ")" : "" } .`
1615+ )
1616+ ) ;
15371617 } else if ( isInternalError ) {
15381618 creating . stop ( pc . red ( "D1 database creation failed due to Cloudflare API internal error." ) ) ;
15391619 console . log ( pc . gray ( "This is usually a temporary issue with Cloudflare's API." ) ) ;
@@ -1589,19 +1669,24 @@ export const verification = {} as any;`;
15891669 res . stdout ?. includes ( "A Hyperdrive config with the given name already exists" ) ;
15901670
15911671 if ( isHyperdriveExists ) {
1592- // Hyperdrive already exists, which is fine - just configure it in wrangler.toml
1593- if ( existsSync ( wranglerPath ) ) {
1594- let wrangler = readFileSync ( wranglerPath , "utf8" ) ;
1595- wrangler = appendOrReplaceHyperdriveBlock (
1596- wrangler ,
1672+ // Hyperdrive already exists, which is fine - get its ID and configure it in wrangler.toml
1673+ const existingHyperdriveId = getExistingHyperdriveId ( answers . hdName , cwd , answers . accountId ) ;
1674+ if ( existingHyperdriveId && existsSync ( wranglerPath ) ) {
1675+ debugLog ( `Updating wrangler.toml with existing Hyperdrive ID: ${ existingHyperdriveId } ` ) ;
1676+ const currentWrangler = readFileSync ( wranglerPath , "utf-8" ) ;
1677+ const updatedWrangler = updateHyperdriveBlockWithId (
1678+ currentWrangler ,
15971679 answers . hdBinding ,
1598- undefined ,
1599- answers . database as "hyperdrive-postgres" | "hyperdrive-mysql" ,
1680+ existingHyperdriveId ,
16001681 answers . hdConnectionString
16011682 ) ;
1602- writeFileSync ( wranglerPath , wrangler ) ;
1683+ writeFileSync ( wranglerPath , updatedWrangler ) ;
16031684 }
1604- creating . stop ( pc . yellow ( `Hyperdrive already exists (name: ${ answers . hdName } ).` ) ) ;
1685+ creating . stop (
1686+ pc . yellow (
1687+ `Hyperdrive already exists (name: ${ answers . hdName } )${ existingHyperdriveId ? " (id: " + existingHyperdriveId + ")" : "" } .`
1688+ )
1689+ ) ;
16051690 } else {
16061691 creating . stop ( pc . red ( "Failed to create Hyperdrive." ) ) ;
16071692 assertOk ( res , "Hyperdrive creation failed." ) ;
@@ -1641,13 +1726,27 @@ export const verification = {} as any;`;
16411726 res . stdout ?. includes ( "already exists" ) ;
16421727
16431728 if ( isKvExists ) {
1644- // KV namespace already exists, which is fine - just configure it in wrangler.toml
1645- if ( existsSync ( wranglerPath ) ) {
1646- let wrangler = readFileSync ( wranglerPath , "utf8" ) ;
1647- wrangler = appendOrReplaceKvNamespaceBlock ( wrangler , answers . kvBinding ) ;
1648- writeFileSync ( wranglerPath , wrangler ) ;
1729+ // KV namespace already exists, which is fine - get its ID and configure it in wrangler.toml
1730+ const existingNamespaceId = getExistingKvNamespaceId (
1731+ answers . kvNamespaceName ,
1732+ cwd ,
1733+ answers . accountId
1734+ ) ;
1735+ if ( existingNamespaceId && existsSync ( wranglerPath ) ) {
1736+ debugLog ( `Updating wrangler.toml with existing KV namespace ID: ${ existingNamespaceId } ` ) ;
1737+ const currentWrangler = readFileSync ( wranglerPath , "utf-8" ) ;
1738+ const updatedWrangler = updateKvBlockWithId (
1739+ currentWrangler ,
1740+ answers . kvBinding ,
1741+ existingNamespaceId
1742+ ) ;
1743+ writeFileSync ( wranglerPath , updatedWrangler ) ;
16491744 }
1650- creating . stop ( pc . yellow ( `KV namespace already exists (name: ${ answers . kvNamespaceName } ).` ) ) ;
1745+ creating . stop (
1746+ pc . yellow (
1747+ `KV namespace already exists (name: ${ answers . kvNamespaceName } )${ existingNamespaceId ? " (id: " + existingNamespaceId + ")" : "" } .`
1748+ )
1749+ ) ;
16511750 } else {
16521751 creating . stop ( pc . red ( "Failed to create KV namespace." ) ) ;
16531752 assertOk ( res , "KV namespace creation failed." ) ;
0 commit comments