Skip to content

Commit

Permalink
Clean up output formatting and support colorizing FQL results (#496)
Browse files Browse the repository at this point in the history
* Update output to support fql
* Move to sync and support fql directly via tm grammar

---------

Co-authored-by: Paul Paterson <[email protected]>
  • Loading branch information
ecooper and ptpaterson authored Dec 10, 2024
1 parent 5951ab7 commit 8047c4d
Show file tree
Hide file tree
Showing 27 changed files with 1,130 additions and 598 deletions.
562 changes: 537 additions & 25 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,24 @@
"bugs": "https://github.com/fauna/fauna-shell/issues",
"dependencies": {
"@inquirer/prompts": "^7.0.0",
"@shikijs/cli": "^1.24.0",
"awilix": "^12.0.2",
"chalk": "^5.3.0",
"eslint": "^9.12.0",
"esprima": "^4.0.1",
"fauna": "^2.3.0",
"faunadb": "^4.5.4",
"inquirer": "^12.0.0",
"json-colorizer": "^3.0.1",
"luxon": "^3.5.0",
"open": "10.1.0",
"shiki": "^1.15.2",
"update-notifier": "^7.3.1",
"yaml": "^2.6.1",
"yargs": "^17.7.2"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.11.1",
"@eslint/js": "^9.16.0",
"@fauna/typescript": "^0.0.12",
"@inquirer/testing": "^2.1.7",
"@types/chai": "^5.0.0",
Expand Down
8 changes: 6 additions & 2 deletions src/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import chalk from "chalk";
import yargs from "yargs";

import databaseCommand from "./commands/database/database.mjs";
import keyCommand from "./commands/key/key.mjs";
import loginCommand from "./commands/login.mjs";
import queryCommand from "./commands/query.mjs";
import schemaCommand from "./commands/schema/schema.mjs";
Expand Down Expand Up @@ -132,6 +131,12 @@ function buildYargs(argvInput) {
process.emitWarning("this is a warning emitted on the node process");
},
builder: {},
})
.command("argv", false, {
handler: async (argv) => {
container.resolve("logger").stdout(argv);
},
builder: {},
});
}

Expand All @@ -144,7 +149,6 @@ function buildYargs(argvInput) {
.command(queryCommand)
.command(shellCommand)
.command(loginCommand)
.command(keyCommand)
.command(schemaCommand)
.command(databaseCommand)
.demandCommand()
Expand Down
6 changes: 4 additions & 2 deletions src/commands/database/create.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { container } from "../../cli.mjs";
import { validateDatabaseOrSecret } from "../../lib/command-helpers.mjs";
import { throwForError } from "../../lib/fauna.mjs";
import { getSecret, retryInvalidCredsOnce } from "../../lib/fauna-client.mjs";
import { formatObjectForShell } from "../../lib/misc.mjs";
import { colorize, JSON_FORMAT } from "../../lib/formatting/colorize.mjs";

async function runCreateQuery(secret, argv) {
const { fql } = container.resolve("fauna");
Expand Down Expand Up @@ -37,7 +37,9 @@ async function createDatabase(argv) {

const { color, json } = argv;
if (json) {
logger.stdout(formatObjectForShell({ name: argv.name }, { color }));
logger.stdout(
colorize({ name: argv.name }, { color, format: JSON_FORMAT }),
);
} else {
logger.stdout(argv.name);
}
Expand Down
19 changes: 10 additions & 9 deletions src/commands/database/list.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { container } from "../../cli.mjs";
import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs";
import { throwForError } from "../../lib/fauna.mjs";
import { FaunaAccountClient } from "../../lib/fauna-account-client.mjs";
import { formatObjectForShell } from "../../lib/misc.mjs";
import { colorize, JSON_FORMAT } from "../../lib/formatting/colorize.mjs";

// Narrow the output fields based on the provided flags.
const getOutputFields = (argv) => {
Expand All @@ -29,23 +29,24 @@ function pickOutputFields(databases, argv) {
}

async function listDatabasesWithAccountAPI(argv) {
const { pageSize, database, json, color } = argv;
const { pageSize, database, color } = argv;
const accountClient = new FaunaAccountClient();
const response = await accountClient.listDatabases({
pageSize,
path: database,
});
const output = pickOutputFields(response.results, argv);

if (json) {
container.resolve("logger").stdout(JSON.stringify(output));
} else {
container.resolve("logger").stdout(formatObjectForShell(output, { color }));
}
container.resolve("logger").stdout(
colorize(output, {
format: JSON_FORMAT,
color: color,
}),
);
}

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

Expand All @@ -59,7 +60,7 @@ async function listDatabasesWithSecret(argv) {
});
container
.resolve("logger")
.stdout(formatQueryResponse(result, { json, color }));
.stdout(formatQueryResponse(result, { format: JSON_FORMAT, color }));
} catch (e) {
if (e instanceof FaunaError) {
throwForError(e);
Expand Down
91 changes: 0 additions & 91 deletions src/commands/key/create.mjs

This file was deleted.

18 changes: 0 additions & 18 deletions src/commands/key/key.mjs

This file was deleted.

3 changes: 1 addition & 2 deletions src/commands/login.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ async function doLogin(argv) {
const dashboardOAuthURL =
await FaunaAccountClient.startOAuthRequest(authCodeParams);
open(dashboardOAuthURL);
logger.stdout(`To login, open your browser to:\n ${dashboardOAuthURL}`);
logger.stdout(`To login, open your browser to:\n${dashboardOAuthURL}`);
});
oAuth.server.on("auth_code_received", async () => {
try {
const tokenParams = oAuth.getTokenParams();
const accessToken = await FaunaAccountClient.getToken(tokenParams);
await credentials.login(accessToken);
logger.stdout(`Login Success!\n`);
} catch (err) {
logger.stderr(err);
}
Expand Down
14 changes: 11 additions & 3 deletions src/commands/query.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { container } from "../cli.mjs";
import {
CommandError,
isUnknownError,
resolveFormat,
validateDatabaseOrSecret,
ValidationError,
yargsWithCommonConfigurableQueryOptions,
Expand All @@ -13,6 +14,7 @@ import {
formatQueryResponse,
getSecret,
} from "../lib/fauna-client.mjs";
import { isTTY } from "../lib/misc.mjs";

function validate(argv) {
const { existsSync, accessSync, constants } = container.resolve("fs");
Expand Down Expand Up @@ -73,23 +75,29 @@ async function queryCommand(argv) {
// get the query handler and run the query
try {
const secret = await getSecret();
const { url, timeout, typecheck, raw, json, apiVersion, color } = argv;
const { url, timeout, typecheck, apiVersion, color, raw } = argv;

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

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

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

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

Expand Down
26 changes: 20 additions & 6 deletions src/commands/shell.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//@ts-check

import console from "node:console";
import repl from "node:repl";

import * as esprima from "esprima";

import { container } from "../cli.mjs";
import {
resolveFormat,
validateDatabaseOrSecret,
yargsWithCommonConfigurableQueryOptions,
} from "../lib/command-helpers.mjs";
Expand Down Expand Up @@ -46,7 +48,6 @@ async function shellCommand(argv) {
}
});

// eslint-disable-next-line no-console
shell.on("error", console.error);

if (argv.apiVersion === "4") {
Expand All @@ -62,7 +63,6 @@ async function shellCommand(argv) {
cmd: "clear",
help: "Clear the REPL",
action: () => {
// eslint-disable-next-line no-console
console.clear();
shell.prompt();
},
Expand Down Expand Up @@ -122,8 +122,15 @@ async function buildCustomEval(argv) {
if (cmd.trim() === "") return cb();

// These are options used for querying and formatting the response
const { apiVersion, color, json } = argv;
const { raw } = ctx;
const { apiVersion, color, raw: argvRaw } = argv;
const raw = ctx.raw === undefined ? argvRaw : ctx.raw;

if (ctx.raw === undefined) {
ctx.raw = argvRaw;
}

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

if (apiVersion === "4") {
try {
Expand All @@ -144,14 +151,21 @@ async function buildCustomEval(argv) {
url,
timeout,
typecheck,
format: outputFormat,
});
} catch (err) {
logger.stderr(formatError(err, { apiVersion, raw, color }));
return cb(null);
}

// If raw is on, return the full response. Otherwise, return just the data.
logger.stdout(formatQueryResponse(res, { apiVersion, raw, color, json }));
const output = formatQueryResponse(res, {
apiVersion,
raw,
color,
format: outputFormat,
});

logger.stdout(output);

return cb(null);
} catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions src/config/setup-container.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as awilix from "awilix";
import { Lifetime } from "awilix";
import fauna from "fauna";
import faunadb from "faunadb";
import { colorize } from "json-colorizer";
import open from "open";
import updateNotifier from "update-notifier";

Expand All @@ -22,6 +21,7 @@ import * as faunaV10 from "../lib/fauna.mjs";
import { formatError, runQueryFromString } from "../lib/fauna-client.mjs";
import * as faunaV4 from "../lib/faunadb.mjs";
import fetchWrapper from "../lib/fetch-wrapper.mjs";
import { codeToAnsi } from "../lib/formatting/codeToAnsi.mjs";
import buildLogger from "../lib/logger.mjs";
import {
deleteUnusedSchemaFiles,
Expand Down Expand Up @@ -65,7 +65,7 @@ export const injectables = {
updateNotifier: awilix.asValue(updateNotifier),
fauna: awilix.asValue(fauna),
faunadb: awilix.asValue(faunadb),
colorize: awilix.asValue(colorize),
codeToAnsi: awilix.asValue(codeToAnsi),

// generic lib (homemade utilities)
parseYargs: awilix.asValue(parseYargs),
Expand Down
Loading

0 comments on commit 8047c4d

Please sign in to comment.