diff --git a/src/cli.mjs b/src/cli.mjs index 34802b00..fd4cb6b7 100644 --- a/src/cli.mjs +++ b/src/cli.mjs @@ -8,8 +8,8 @@ import chalk from "chalk"; import yargs from "yargs"; import databaseCommand from "./commands/database/database.mjs"; -import localCommand from "./commands/local.mjs"; import initCommand from "./commands/init.mjs"; +import localCommand from "./commands/local.mjs"; import loginCommand from "./commands/login.mjs"; import queryCommand from "./commands/query.mjs"; import schemaCommand from "./commands/schema/schema.mjs"; diff --git a/src/commands/database/list.mjs b/src/commands/database/list.mjs index ecef0f46..ecd04cef 100644 --- a/src/commands/database/list.mjs +++ b/src/commands/database/list.mjs @@ -6,7 +6,7 @@ import { faunaToCommandError } from "../../lib/fauna.mjs"; import { FaunaAccountClient } from "../../lib/fauna-account-client.mjs"; import { colorize, Format } from "../../lib/formatting/colorize.mjs"; -async function listDatabasesWithAccountAPI(argv) { +export async function listDatabasesWithAccountAPI(argv) { const { pageSize, database } = argv; const accountClient = new FaunaAccountClient(); const response = await accountClient.listDatabases({ @@ -14,7 +14,12 @@ async function listDatabasesWithAccountAPI(argv) { path: database, }); - return response.results.map(({ path, name }) => ({ path, name })); + // eslint-disable-next-line camelcase + return response.results.map(({ path, name, region_group }) => ({ + path, + name, + regionGroup: region_group, // eslint-disable-line camelcase + })); } async function listDatabasesWithSecret(argv) { diff --git a/src/commands/init.mjs b/src/commands/init.mjs index c37014cf..f1a81f81 100644 --- a/src/commands/init.mjs +++ b/src/commands/init.mjs @@ -15,8 +15,6 @@ import { getSecret } from "../lib/fauna-client.mjs"; import { reformatFSL } from "../lib/schema.mjs"; import { listDatabasesWithAccountAPI } from "./database/list.mjs"; -// TODO: handle error/exit case cleanly - async function doInit(argv) { const logger = container.resolve("logger"); const getters = [getDatabaseRunnable, getProjectRunnable, getKeyRunnable]; @@ -65,11 +63,11 @@ async function getDatabaseRunnable(argv /*, priorChoices*/) { buildCredentials({ ...argv, user: "default", database: "us-std" }); const dbs = (await listDatabasesWithAccountAPI(argv)) - .map((db) => `${db.region_group}/${db.name}`) + .map((db) => `${db.regionGroup}/${db.name}`) .map((dbName) => ({ value: dbName })); runnable.choices.createNewDb = await inquirer.select({ - message: "Select a database to create a project for", + message: "Select a database to create an FSL directory for", choices: [ ...dbs, { @@ -81,6 +79,7 @@ async function getDatabaseRunnable(argv /*, priorChoices*/) { if (runnable.choices.createNewDb !== "new") { runnable.choices.dbName = runnable.choices.createNewDb.split("/")[1]; + runnable.choices.regionGroup = runnable.choices.createNewDb.split("/")[0]; return runnable; } @@ -249,26 +248,29 @@ async function getProjectRunnable(argv, priorChoices) { if (!shouldCreateProjectDirectory) return runnable; runnable.choices.dirName = await inquirer.input({ - message: `FSL files are stored in a project directory and are specific to the database "${priorChoices.dbName}". What would you like to name this project directory? In the next step, you will choose where to put the directory.`, + message: `FSL files are stored in a directory and are specific to the database "${priorChoices.dbName}". What would you like to name this directory? In the next step, you will choose where to put the directory.`, default: priorChoices.dbName, }); runnable.choices.dirPath = await fileSelector({ - message: "Where would you like the project directory to be created?", + message: "Where would you like the FSL directory to be created?", type: "directory", }); - runnable.runner = async ({ - choices: { createNewDb, demoData, dirPath, dirName, dbName, regionGroup }, - }) => { + runnable.runner = async ({ choices }) => { + const { createNewDb, demoData, dirPath, dirName, dbName, regionGroup } = + choices; const fs = container.resolve("fs"); const fsp = container.resolve("fsp"); const path = await import("path"); - logger.stdout( - `Creating project directory at ${path.join(dirPath, dirName)}`, - ); + logger.stdout(`Creating FSL directory at ${path.join(dirPath, dirName)}`); - if (!createNewDb) { + buildCredentials({ + ...argv, + user: "default", + database: `${regionGroup}/${dbName}`, + }); + if (createNewDb !== "new") { // existing db? fetch the schema // TODO: this has huge overlap with schema pull - should refactor so it's only in one place fs.mkdirSync(path.join(dirPath, dirName), { recursive: true }); @@ -281,6 +283,13 @@ async function getProjectRunnable(argv, priorChoices) { secret, }); + const { version } = await makeFaunaRequest({ + argv, + path: "/schema/1/staged/status", + method: "GET", + secret, + }); + // sort for consistent order (it's nice for tests) const filenames = filesResponse.files .map((file) => file.filename) @@ -290,10 +299,12 @@ async function getProjectRunnable(argv, priorChoices) { const getAllSchemaFileContents = container.resolve( "getAllSchemaFileContents", ); - const contents = await getAllSchemaFileContents(filenames, { - ...argv, - secret, - }); + const contents = await getAllSchemaFileContents( + filenames, + "active", + version, + argv, + ); // don't start writing files until we've successfully fetched all the remote schema files const promises = []; @@ -321,11 +332,6 @@ async function getProjectRunnable(argv, priorChoices) { staged: "false", }); - buildCredentials({ - ...argv, - user: "default", - database: `${regionGroup}/${dbName}`, - }); await makeFaunaRequest({ argv, path: "/schema/1/update", @@ -347,9 +353,7 @@ async function getProjectRunnable(argv, priorChoices) { ), ]); } - logger.stdout( - `Created project directory at ${path.join(dirPath, dirName)}`, - ); + logger.stdout(`Created FSL directory at ${path.join(dirPath, dirName)}`); }; return runnable;