-
Notifications
You must be signed in to change notification settings - Fork 910
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Firebase CLI Supports Firestore Provisioning API (#5616)
b/267473272 - Add support for Firestore Provisioning API. This feature is experimental and may not yet be enabled on all projects. It introduces 6 new commands to the Firebase CLI
- Loading branch information
Showing
18 changed files
with
593 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,8 @@ | ||
- Adds new commands for provisioning and managing Firestore databases: (#5616) | ||
- firestore:databases:list | ||
- firestore:databases:create | ||
- firestore:databases:get | ||
- firestore:databases:update | ||
- firestore:databases:delete | ||
- firestore:locations | ||
- Relaxed repo URI validation in ext:dev:publish (#5698). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { Command } from "../command"; | ||
import * as clc from "colorette"; | ||
import * as fsi from "../firestore/api"; | ||
import * as types from "../firestore/api-types"; | ||
import { logger } from "../logger"; | ||
import { requirePermissions } from "../requirePermissions"; | ||
import { Emulators } from "../emulator/types"; | ||
import { warnEmulatorNotSupported } from "../emulator/commandUtils"; | ||
import { FirestoreOptions } from "../firestore/options"; | ||
|
||
export const command = new Command("firestore:databases:create <database>") | ||
.description("Create a database in your Firebase project.") | ||
.option( | ||
"--location <locationId>", | ||
"Region to create database, for example 'nam5'. Run 'firebase firestore:locations' to get a list of eligible locations. (required)" | ||
) | ||
.option( | ||
"--delete-protection <deleteProtectionState>", | ||
"Whether or not to prevent deletion of database, for example 'ENABLED' or 'DISABLED'. Default is 'DISABLED'" | ||
) | ||
.before(requirePermissions, ["datastore.databases.create"]) | ||
.before(warnEmulatorNotSupported, Emulators.FIRESTORE) | ||
.action(async (database: string, options: FirestoreOptions) => { | ||
const api = new fsi.FirestoreApi(); | ||
if (!options.location) { | ||
logger.error( | ||
"Missing required flag --location. See firebase firestore:databases:create --help for more info." | ||
); | ||
return; | ||
} | ||
// Type is always Firestore Native since Firebase does not support Datastore Mode | ||
const type: types.DatabaseType = types.DatabaseType.FIRESTORE_NATIVE; | ||
if ( | ||
options.deleteProtection && | ||
options.deleteProtection !== types.DatabaseDeleteProtectionStateOption.ENABLED && | ||
options.deleteProtection !== types.DatabaseDeleteProtectionStateOption.DISABLED | ||
) { | ||
logger.error( | ||
"Invalid value for flag --delete-protection. See firebase firestore:databases:create --help for more info." | ||
); | ||
return; | ||
} | ||
const deleteProtectionState: types.DatabaseDeleteProtectionState = | ||
options.deleteProtection === types.DatabaseDeleteProtectionStateOption.ENABLED | ||
? types.DatabaseDeleteProtectionState.ENABLED | ||
: types.DatabaseDeleteProtectionState.DISABLED; | ||
|
||
const databaseResp: types.DatabaseResp = await api.createDatabase( | ||
options.project, | ||
database, | ||
options.location, | ||
type, | ||
deleteProtectionState | ||
); | ||
|
||
if (options.json) { | ||
logger.info(JSON.stringify(databaseResp, undefined, 2)); | ||
} else { | ||
logger.info(clc.bold(`Successfully created ${api.prettyDatabaseString(databaseResp)}`)); | ||
logger.info( | ||
"Please be sure to configure Firebase rules in your Firebase config file for\n" + | ||
"the new database. By default, created databases will have closed rules that\n" + | ||
"block any incoming third-party traffic." | ||
); | ||
} | ||
|
||
return databaseResp; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { Command } from "../command"; | ||
import * as clc from "colorette"; | ||
import * as fsi from "../firestore/api"; | ||
import * as types from "../firestore/api-types"; | ||
import { promptOnce } from "../prompt"; | ||
import { logger } from "../logger"; | ||
import { requirePermissions } from "../requirePermissions"; | ||
import { Emulators } from "../emulator/types"; | ||
import { warnEmulatorNotSupported } from "../emulator/commandUtils"; | ||
import { FirestoreOptions } from "../firestore/options"; | ||
import { FirebaseError } from "../error"; | ||
|
||
export const command = new Command("firestore:databases:delete <database>") | ||
.description( | ||
"Delete a database in your Cloud Firestore project. Database delete protection state must be disabled. To do so, use the update command: firebase firestore:databases:update <database> --delete-protection DISABLED" | ||
) | ||
.option("--force", "Attempt to delete database without prompting for confirmation.") | ||
.before(requirePermissions, ["datastore.databases.delete"]) | ||
.before(warnEmulatorNotSupported, Emulators.FIRESTORE) | ||
.action(async (database: string, options: FirestoreOptions) => { | ||
const api = new fsi.FirestoreApi(); | ||
|
||
if (!options.force) { | ||
const confirmMessage = `You are about to delete projects/${options.project}/databases/${database}. Do you wish to continue?`; | ||
const consent = await promptOnce({ | ||
type: "confirm", | ||
message: confirmMessage, | ||
default: false, | ||
}); | ||
if (!consent) { | ||
throw new FirebaseError("Delete database canceled."); | ||
} | ||
} | ||
|
||
const databaseResp: types.DatabaseResp = await api.deleteDatabase(options.project, database); | ||
|
||
if (options.json) { | ||
logger.info(JSON.stringify(databaseResp, undefined, 2)); | ||
} else { | ||
logger.info(clc.bold(`Successfully deleted ${api.prettyDatabaseString(databaseResp)}`)); | ||
} | ||
|
||
return databaseResp; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Command } from "../command"; | ||
import * as fsi from "../firestore/api"; | ||
import * as types from "../firestore/api-types"; | ||
import { logger } from "../logger"; | ||
import { requirePermissions } from "../requirePermissions"; | ||
import { Emulators } from "../emulator/types"; | ||
import { warnEmulatorNotSupported } from "../emulator/commandUtils"; | ||
import { FirestoreOptions } from "../firestore/options"; | ||
|
||
export const command = new Command("firestore:databases:get [database]") | ||
.description("Get database in your Cloud Firestore project.") | ||
.before(requirePermissions, ["datastore.databases.get"]) | ||
.before(warnEmulatorNotSupported, Emulators.FIRESTORE) | ||
.action(async (database: string, options: FirestoreOptions) => { | ||
const api = new fsi.FirestoreApi(); | ||
|
||
const databaseId = database || "(default)"; | ||
const databaseResp: types.DatabaseResp = await api.getDatabase(options.project, databaseId); | ||
|
||
if (options.json) { | ||
logger.info(JSON.stringify(databaseResp, undefined, 2)); | ||
} else { | ||
api.prettyPrintDatabase(databaseResp); | ||
} | ||
|
||
return databaseResp; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Command } from "../command"; | ||
import * as fsi from "../firestore/api"; | ||
import * as types from "../firestore/api-types"; | ||
import { logger } from "../logger"; | ||
import { requirePermissions } from "../requirePermissions"; | ||
import { Emulators } from "../emulator/types"; | ||
import { warnEmulatorNotSupported } from "../emulator/commandUtils"; | ||
import { FirestoreOptions } from "../firestore/options"; | ||
|
||
export const command = new Command("firestore:databases:list") | ||
.description("List databases in your Cloud Firestore project.") | ||
.before(requirePermissions, ["datastore.databases.list"]) | ||
.before(warnEmulatorNotSupported, Emulators.FIRESTORE) | ||
.action(async (options: FirestoreOptions) => { | ||
const api = new fsi.FirestoreApi(); | ||
|
||
const databases: types.DatabaseResp[] = await api.listDatabases(options.project); | ||
|
||
if (options.json) { | ||
logger.info(JSON.stringify(databases, undefined, 2)); | ||
} else { | ||
api.prettyPrintDatabases(databases); | ||
} | ||
|
||
return databases; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { Command } from "../command"; | ||
import * as clc from "colorette"; | ||
import * as fsi from "../firestore/api"; | ||
import * as types from "../firestore/api-types"; | ||
import { logger } from "../logger"; | ||
import { requirePermissions } from "../requirePermissions"; | ||
import { Emulators } from "../emulator/types"; | ||
import { warnEmulatorNotSupported } from "../emulator/commandUtils"; | ||
import { FirestoreOptions } from "../firestore/options"; | ||
|
||
export const command = new Command("firestore:databases:update <database>") | ||
.description( | ||
"Update a database in your Firebase project. Must specify at least one property to update." | ||
) | ||
.option("--json", "Prints raw json response of the create API call if specified") | ||
.option( | ||
"--delete-protection <deleteProtectionState>", | ||
"Whether or not to prevent deletion of database, for example 'ENABLED' or 'DISABLED'. Default is 'DISABLED'" | ||
) | ||
.before(requirePermissions, ["datastore.databases.update"]) | ||
.before(warnEmulatorNotSupported, Emulators.FIRESTORE) | ||
.action(async (database: string, options: FirestoreOptions) => { | ||
const api = new fsi.FirestoreApi(); | ||
|
||
if (!options.type && !options.deleteProtection) { | ||
logger.error( | ||
"Missing properties to update. See firebase firestore:databases:update --help for more info." | ||
); | ||
return; | ||
} | ||
const type: types.DatabaseType = types.DatabaseType.FIRESTORE_NATIVE; | ||
if ( | ||
options.deleteProtection && | ||
options.deleteProtection !== types.DatabaseDeleteProtectionStateOption.ENABLED && | ||
options.deleteProtection !== types.DatabaseDeleteProtectionStateOption.DISABLED | ||
) { | ||
logger.error( | ||
"Invalid value for flag --delete-protection. See firebase firestore:databases:update --help for more info." | ||
); | ||
return; | ||
} | ||
const deleteProtectionState: types.DatabaseDeleteProtectionState = | ||
options.deleteProtection === types.DatabaseDeleteProtectionStateOption.ENABLED | ||
? types.DatabaseDeleteProtectionState.ENABLED | ||
: types.DatabaseDeleteProtectionState.DISABLED; | ||
|
||
const databaseResp: types.DatabaseResp = await api.updateDatabase( | ||
options.project, | ||
database, | ||
type, | ||
deleteProtectionState | ||
); | ||
|
||
if (options.json) { | ||
logger.info(JSON.stringify(databaseResp, undefined, 2)); | ||
} else { | ||
logger.info(clc.bold(`Successfully updated ${api.prettyDatabaseString(databaseResp)}`)); | ||
} | ||
|
||
return databaseResp; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Command } from "../command"; | ||
import * as fsi from "../firestore/api"; | ||
import * as types from "../firestore/api-types"; | ||
import { logger } from "../logger"; | ||
import { requirePermissions } from "../requirePermissions"; | ||
import { Emulators } from "../emulator/types"; | ||
import { warnEmulatorNotSupported } from "../emulator/commandUtils"; | ||
import { FirestoreOptions } from "../firestore/options"; | ||
|
||
export const command = new Command("firestore:locations") | ||
.description("List possible locations for your Cloud Firestore project.") | ||
.before(requirePermissions, ["datastore.locations.list"]) | ||
.before(warnEmulatorNotSupported, Emulators.FIRESTORE) | ||
.action(async (options: FirestoreOptions) => { | ||
const api = new fsi.FirestoreApi(); | ||
|
||
const locations: types.Location[] = await api.locations(options.project); | ||
|
||
if (options.json) { | ||
logger.info(JSON.stringify(locations, undefined, 2)); | ||
} else { | ||
api.prettyPrintLocations(locations); | ||
} | ||
|
||
return locations; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.