@@ -16,6 +16,7 @@ const TIMEOUT_MILLIS = 30000;
16
16
const MAXIMUM_PROMPT_LIST = 100 ;
17
17
const PROJECT_LIST_PAGE_SIZE = 1000 ;
18
18
const CREATE_PROJECT_API_REQUEST_TIMEOUT_MILLIS = 15000 ;
19
+ const CHECK_PROJECT_ID_API_REQUEST_TIMEOUT_MILLIS = 15000 ;
19
20
20
21
export enum ProjectParentResourceType {
21
22
ORGANIZATION = "organization" ,
@@ -39,14 +40,26 @@ export async function promptProjectCreation(
39
40
message :
40
41
"Please specify a unique project id " +
41
42
`(${ clc . yellow ( "warning" ) } : cannot be modified afterward) [6-30 characters]:\n` ,
42
- validate : ( projectId : string ) => {
43
+ validate : async ( projectId : string ) => {
43
44
if ( projectId . length < 6 ) {
44
45
return "Project ID must be at least 6 characters long" ;
45
46
} else if ( projectId . length > 30 ) {
46
47
return "Project ID cannot be longer than 30 characters" ;
47
- } else {
48
- return true ;
49
48
}
49
+
50
+ try {
51
+ // Best effort. We should still allow project creation even if this fails.
52
+ const { isAvailable, suggestedProjectId } = await checkAndRecommendProjectId ( projectId ) ;
53
+ if ( ! isAvailable && suggestedProjectId ) {
54
+ return `Project ID is taken or unavailable. Try ${ clc . bold ( suggestedProjectId ) } .` ;
55
+ }
56
+ } catch ( error : any ) {
57
+ logger . debug (
58
+ `Couldn't check if project ID ${ projectId } is available. Original error: ${ error } ` ,
59
+ ) ;
60
+ }
61
+
62
+ return true ;
50
63
} ,
51
64
} ) ) ;
52
65
@@ -75,6 +88,12 @@ const firebaseAPIClient = new Client({
75
88
apiVersion : "v1beta1" ,
76
89
} ) ;
77
90
91
+ const firebaseV1APIClient = new Client ( {
92
+ urlPrefix : api . firebaseApiOrigin ( ) ,
93
+ auth : true ,
94
+ apiVersion : "v1" ,
95
+ } ) ;
96
+
78
97
const resourceManagerClient = new Client ( {
79
98
urlPrefix : api . resourceManagerOrigin ( ) ,
80
99
apiVersion : "v1" ,
@@ -432,6 +451,35 @@ export async function listFirebaseProjects(pageSize?: number): Promise<FirebaseP
432
451
return projects ;
433
452
}
434
453
454
+ export async function checkAndRecommendProjectId (
455
+ projectId : String ,
456
+ ) : Promise < { isAvailable : boolean ; suggestedProjectId ?: string } > {
457
+ try {
458
+ const res = await firebaseV1APIClient . request <
459
+ any ,
460
+ { projectIdStatus : string ; suggestedProjectId ?: string }
461
+ > ( {
462
+ method : "POST" ,
463
+ path : "/projects:checkProjectId" ,
464
+ body : {
465
+ proposedId : projectId ,
466
+ } ,
467
+ timeout : CHECK_PROJECT_ID_API_REQUEST_TIMEOUT_MILLIS ,
468
+ } ) ;
469
+
470
+ const { projectIdStatus, suggestedProjectId } = res . body ;
471
+ return {
472
+ isAvailable : projectIdStatus === "PROJECT_ID_AVAILABLE" ,
473
+ suggestedProjectId,
474
+ } ;
475
+ } catch ( err : any ) {
476
+ throw new FirebaseError (
477
+ "Failed to check if project ID is available. See firebase-debug.log for more info." ,
478
+ { exit : 2 , original : err } ,
479
+ ) ;
480
+ }
481
+ }
482
+
435
483
/**
436
484
* Gets the Firebase project information identified by the specified project ID
437
485
*/
0 commit comments