Skip to content

Commit

Permalink
Add prototype of a format factory for account API crud commands
Browse files Browse the repository at this point in the history
  • Loading branch information
ecooper committed Jan 16, 2025
1 parent 0ce3015 commit 616946e
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 152 deletions.
6 changes: 0 additions & 6 deletions src/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,6 @@ function buildYargs(argvInput) {
description: "Profile from the CLI config file to use.",
group: "Config:",
},
json: {
type: "boolean",
description: "Output the results as JSON.",
default: false,
group: "Output:",
},
quiet: {
type: "boolean",
description:
Expand Down
40 changes: 28 additions & 12 deletions src/commands/database/create.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,25 @@ import { container } from "../../config/container.mjs";
import { CommandError } from "../../lib/errors.mjs";
import { faunaToCommandError } from "../../lib/fauna.mjs";
import { getSecret, retryInvalidCredsOnce } from "../../lib/fauna-client.mjs";
import { colorize, Format } from "../../lib/formatting/colorize.mjs";
import { createFormatter } from "../../lib/formatting/formatter.mjs";
import { validateDatabaseOrSecret } from "../../lib/middleware.mjs";
import { FORMATTABLE_OPTIONS } from "../../lib/options.mjs";

const formatter = createFormatter({
header: "fauna database create",
columns: [
"global_id",
"name",
"coll",
"ts",
"protected",
"typechecked",
"priority",
],
short: {
formatter: ({ global_id, name }) => `${name} (${global_id})`, // eslint-disable-line camelcase
},
});

async function runCreateQuery(secret, argv) {
const { fql } = container.resolve("fauna");
Expand All @@ -29,20 +46,18 @@ async function createDatabase(argv) {
const logger = container.resolve("logger");

try {
await retryInvalidCredsOnce(secret, async (secret) =>
const { data } = await retryInvalidCredsOnce(secret, async (secret) =>
runCreateQuery(secret, argv),
);
const dataWithAllFields = {
protected: undefined,
typechecked: undefined,
priority: undefined,
...data,
};

logger.stderr(`Database successfully created.`);

const { color, json } = argv;
if (json) {
logger.stdout(
colorize({ name: argv.name }, { color, format: Format.JSON }),
);
} else {
logger.stdout(argv.name);
}
const { color, format } = argv;
logger.stdout(formatter({ data: dataWithAllFields, color, format }));
} catch (e) {
faunaToCommandError({
err: e,
Expand Down Expand Up @@ -76,6 +91,7 @@ async function createDatabase(argv) {

function buildCreateCommand(yargs) {
return yargs
.options(FORMATTABLE_OPTIONS)
.options({
name: {
type: "string",
Expand Down
42 changes: 24 additions & 18 deletions src/commands/database/list.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,30 @@ import chalk from "chalk";

import { container } from "../../config/container.mjs";
import { faunaToCommandError } from "../../lib/fauna.mjs";
import { colorize, Format } from "../../lib/formatting/colorize.mjs";
import { createFormatter } from "../../lib/formatting/formatter.mjs";
import { FORMATTABLE_OPTIONS } from "../../lib/options.mjs";

const formatter = createFormatter({
header: "fauna database list",
columns: ["name", "path"],
short: {
formatter: ({ path, name }) => `${path ?? name}`,
},
});

async function listDatabasesWithAccountAPI(argv) {
const { pageSize, database } = argv;
const { maxSize, database } = argv;
const { listDatabases } = container.resolve("accountAPI");
const response = await listDatabases({
pageSize,
pageSize: maxSize,
path: database,
});

return response.results.map(({ path, name }) => ({ path, name }));
}

async function listDatabasesWithSecret(argv) {
const { url, secret, pageSize } = argv;
const { url, secret, maxSize, color } = argv;
const { runQueryFromString } = container.resolve("faunaClientV10");

try {
Expand All @@ -26,11 +35,11 @@ async function listDatabasesWithSecret(argv) {
secret,
// This gives us back an array of database names. If we want to
// provide the after token at some point this query will need to be updated.
expression: `Database.all().paginate(${pageSize}).data { name }`,
expression: `Database.all().paginate(${maxSize}).data { name }`,
});
return res.data;
} catch (e) {
return faunaToCommandError({ err: e, color: argv.color });
return faunaToCommandError({ err: e, color });
}
}

Expand All @@ -54,22 +63,19 @@ async function doListDatabases(argv) {
);
}

if (argv.json) {
logger.stdout(colorize(res, { format: Format.JSON, color: argv.color }));
} else {
res.forEach(({ path, name }) => {
logger.stdout(path ?? name);
});
}
const { format, color } = argv;
logger.stdout(formatter({ data: res, format, color }));
}

function buildListCommand(yargs) {
return yargs
.options(FORMATTABLE_OPTIONS)
.options({
"page-size": {
"max-size": {
alias: "max",
type: "number",
description: "Maximum number of databases to return.",
default: 1000,
default: 10,
},
})
.example([
Expand All @@ -83,12 +89,12 @@ function buildListCommand(yargs) {
"List all child databases directly under a database scoped to a secret.",
],
[
"$0 database list --json",
"$0 database list -f json",
"List all top-level databases and output as JSON.",
],
[
"$0 database list --page-size 10",
"List the first 10 top-level databases.",
"$0 database list --max-size 100",
"List the first 100 top-level databases.",
],
]);
}
Expand Down
14 changes: 7 additions & 7 deletions src/commands/local.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { pushSchema } from "../commands/schema/push.mjs";
import { container } from "../config/container.mjs";
import { ensureContainerRunning } from "../lib/docker-containers.mjs";
import { CommandError, ValidationError } from "../lib/errors.mjs";
import { colorize, Format } from "../lib/formatting/colorize.mjs";
import { colorize, Language } from "../lib/formatting/colorize.mjs";

/**
* Starts the local Fauna container
Expand Down Expand Up @@ -40,7 +40,7 @@ async function createDatabaseSchema(argv) {
colorize(
`[CreateDatabaseSchema] Creating schema for database '${argv.database}' from directory '${argv.directory}'...`,
{
format: Format.LOG,
language: Language.LOG,
color: argv.color,
},
),
Expand All @@ -52,7 +52,7 @@ async function createDatabaseSchema(argv) {
colorize(
`[CreateDatabaseSchema] Schema for database '${argv.database}' created from directory '${argv.directory}'.`,
{
format: Format.LOG,
language: Language.LOG,
color: argv.color,
},
),
Expand All @@ -66,7 +66,7 @@ async function createDatabase(argv) {
const color = argv.color;
logger.stderr(
colorize(`[CreateDatabase] Creating database '${argv.database}'...`, {
format: Format.LOG,
language: Language.LOG,
color,
}),
);
Expand Down Expand Up @@ -105,17 +105,17 @@ async function createDatabase(argv) {
});
logger.stderr(
colorize(`[CreateDatabase] Database '${argv.database}' created.`, {
format: Format.LOG,
language: Language.LOG,
color,
}),
);
logger.stderr(colorize(db.data, { format: Format.FQL, color }));
logger.stderr(colorize(db.data, { language: Language.FQL, color }));
} catch (e) {
if (e instanceof AbortError) {
throw new CommandError(
`${chalk.red(`[CreateDatabase] Database '${argv.database}' already exists but with differrent properties than requested:\n`)}
-----------------
${colorize(e.abort, { format: Format.FQL, color })}
${colorize(e.abort, { language: Language.FQL, color })}
-----------------
${chalk.red("Please use choose a different name using --name or align the --typechecked, --priority, and --protected with what is currently present.")}`,
);
Expand Down
10 changes: 4 additions & 6 deletions src/commands/query.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
DATABASE_PATH_OPTIONS,
QUERY_OPTIONS,
} from "../lib/options.mjs";
import { isTTY, resolveFormat } from "../lib/utils.mjs";
import { isTTY } from "../lib/utils.mjs";

function validate(argv) {
const { existsSync, accessSync, constants } = container.resolve("fs");
Expand Down Expand Up @@ -96,22 +96,20 @@ async function queryCommand(argv) {
performanceHints,
color,
include,
format,
} = argv;

// If we're writing to a file, don't colorize the output regardless of the user's preference
const useColor = argv.output || !isTTY() ? false : color;

// Using --json takes precedence over --format
const outputFormat = resolveFormat(argv);

const results = await container.resolve("runQueryFromString")(expression, {
apiVersion,
secret,
url,
timeout,
typecheck,
performanceHints,
format: outputFormat,
format,
color: useColor,
});

Expand All @@ -130,7 +128,7 @@ async function queryCommand(argv) {

const output = formatQueryResponse(results, {
apiVersion,
format: outputFormat,
format,
color: useColor,
});

Expand Down
12 changes: 4 additions & 8 deletions src/commands/shell.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
QUERY_INFO_CHOICES,
QUERY_OPTIONS,
} from "../lib/options.mjs";
import { resolveFormat } from "../lib/utils.mjs";

async function shellCommand(argv) {
const { query: v4Query } = container.resolve("faunadb");
Expand Down Expand Up @@ -159,13 +158,10 @@ async function buildCustomEval(argv) {
if (cmd.trim() === "") return cb();

// These are options used for querying and formatting the response
const { apiVersion, color } = argv;
const { apiVersion, color, format } = argv;
const include = getArgvOrCtx("include", argv, ctx);
const performanceHints = getArgvOrCtx("performanceHints", argv, ctx);

// Using --json output takes precedence over --format
const outputFormat = resolveFormat({ ...argv });

if (apiVersion === "4") {
try {
esprima.parseScript(cmd);
Expand All @@ -177,7 +173,7 @@ async function buildCustomEval(argv) {
let res;
try {
const secret = await getSecret();
const { color, timeout, typecheck, url } = argv;
const { color, timeout, typecheck, url, format } = argv;

res = await runQueryFromString(cmd, {
apiVersion,
Expand All @@ -186,7 +182,7 @@ async function buildCustomEval(argv) {
timeout,
typecheck,
performanceHints,
format: outputFormat,
format,
});

// If any query info should be displayed, print to stderr.
Expand All @@ -209,7 +205,7 @@ async function buildCustomEval(argv) {
const output = formatQueryResponse(res, {
apiVersion,
color,
format: outputFormat,
format,
});

logger.stdout(output);
Expand Down
4 changes: 2 additions & 2 deletions src/lib/docker-containers.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { container } from "../config/container.mjs";
import { CommandError, SUPPORT_MESSAGE } from "./errors.mjs";
import { colorize, Format } from "./formatting/colorize.mjs";
import { colorize, Language } from "./formatting/colorize.mjs";

const IMAGE_NAME = "fauna/faunadb:latest";
let color = false;
Expand Down Expand Up @@ -413,5 +413,5 @@ async function waitForHealthCheck({
*/
function stderr(log) {
const logger = container.resolve("logger");
logger.stderr(colorize(log, { format: Format.LOG, color }));
logger.stderr(colorize(log, { language: Language.LOG, color }));
}
12 changes: 6 additions & 6 deletions src/lib/fauna-client.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { container } from "../config/container.mjs";
import { isUnknownError } from "./errors.mjs";
import { faunaToCommandError } from "./fauna.mjs";
import { faunadbToCommandError } from "./faunadb.mjs";
import { colorize, Format } from "./formatting/colorize.mjs";
import { colorize, Language } from "./formatting/colorize.mjs";

/**
* Regex to match the FQL diagnostic line.
Expand Down Expand Up @@ -73,7 +73,7 @@ export const runQueryFromString = (expression, argv) => {
} else {
const { secret, url, timeout, format, performanceHints, ...rest } = argv;
let apiFormat = "decorated";
if (format === Format.JSON) {
if (format === Language.JSON) {
apiFormat = "simple";
}

Expand Down Expand Up @@ -177,7 +177,7 @@ export const formatQuerySummary = (summary) => {
if (!line.match(FQL_DIAGNOSTIC_REGEX)) {
return line;
}
return colorize(line, { format: Format.FQL });
return colorize(line, { language: Language.FQL });
});
return lines.join("\n");
} catch (err) {
Expand Down Expand Up @@ -228,7 +228,7 @@ export const formatQueryInfo = (response, { apiVersion, color, include }) => {
const metricsResponse = response;
const colorized = colorize(
{ metrics: metricsResponse.metrics },
{ color, format: Format.YAML },
{ color, language: Language.YAML },
);

return `${colorized}\n`;
Expand All @@ -242,14 +242,14 @@ export const formatQueryInfo = (response, { apiVersion, color, include }) => {
// strip the ansi when we're checking if the line is a diagnostic line.
const colorized = colorize(queryInfoToDisplay, {
color,
format: Format.YAML,
language: Language.YAML,
})
.split("\n")
.map((line) => {
if (!stripAnsi(line).match(FQL_DIAGNOSTIC_REGEX)) {
return line;
}
return colorize(line, { format: Format.FQL });
return colorize(line, { language: Language.FQL });
})
.join("\n");

Expand Down
Loading

0 comments on commit 616946e

Please sign in to comment.