Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework eval and shell to fully implement eval #443

Merged
merged 9 commits into from
Dec 2, 2024
Merged

Conversation

ecooper
Copy link

@ecooper ecooper commented Nov 26, 2024

Problem

The current implementation of eval was not fully ported over, and recent CLI changes have started to add some drift in how we interact with Fauna.

Solution

This is a "big" PR that's really pretty simple:

  • Renames the command to query but enables an eval alias for the old-timers
  • Moves all query helpers out of the query command and into fauna.mjs and faunadb.mjs. Each module implements the following:
    • stringExpressionToQuery: Transform a string into a query
    • getClient: to return a client
    • runQuery: execute a query
    • runQueryFromString: helper to run a query directly from a string input
    • formatError: support error formatting in a single place
    • formatQueryResponse: support driver response formatting in a single place
  • Use fauna-client for a single entry point to make queries:
    • runQueryFromString: wraps the version specific implementations
    • formatError: wraps the version specific implementations
    • formatQueryResponse: wraps the version specific implementations
  • The following flags have been added:
    • extra: returns the full API response instead of just the data. This flag is surfaced in the shell via .toggleExtra
    • quiet: mutes stderr
    • apiVersion: version has been renamed to not conflict with cli version
  • The following flags have been removed:
    • format: When using the driver, format isn't specifically helpful. The undocumented decorated format doesn't add enough value to manage separately. If we want colorized JSON output (or something else altogether), plenty of options exist.

Result

  fauna query "Collection.all()" --database us-std/example --role admin                                   run the query and write to stdout
  fauna query -i /path/to/queries.fql --database us-std/example --role admin                              run the query from a file
  echo "1 + 1" | fauna query - --database us-std/example --role admin                                     run the query from stdin
  fauna query -i /path/to/queries.fql -o /tmp/result.json --database us-std/example --role admin          run the query and write to a file
  fauna query -i /path/to/queries.fql -o /tmp/result.json --extra --database us-std/example --role admin  run the query and write full API response to a file
➜  fauna-shell (v3-eval-to-query)                                                                                                                                  

Testing

See query tests.

Next/Out of scope

  • Apply proper stderr/stdout patterns in other commands
  • Update shell tests
  • Explore other output formats/styling for query when --json is not specified

@ecooper ecooper requested a review from a team November 26, 2024 21:52
const output = formatQueryResponse(results, argv);

if (argv.output) {
container.resolve("fs").writeFileSync(argv.output, output);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to output the result even when we write to file? sort of like tee.

Copy link
Author

@ecooper ecooper Nov 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see -i and -o as helpers for pipe/redirection so my instinct would to redirect output to the file. But if it makes sense to enough people to do both, that's fine too.

type: "string",
description: "the query to run; use - to read from stdin",
})
.nargs('query', 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this'll probably cause issues with queries that have spaces in them. is the behavior better if we don't specify a number and let yargs infer? or do we want to enforce string quoting?

see queries like:

fauna query let x = 5 --no-color

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah. Good call out. Let me putz around with it and see.

This usage came from the yargs parser tests, but those were also operating on single tokens/values.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, trying to write FQL in zsh without quotes is super dangerous...so I might not do anything about this until we get more feedback from folks.

@ecooper ecooper requested a review from a team November 27, 2024 22:56
@ecooper ecooper marked this pull request as ready for review November 27, 2024 22:59
Comment on lines +119 to +123
['$0 query "Collection.all()" --database us-std/example --role admin', "run the query and write to stdout "],
["$0 query -i /path/to/queries.fql --database us-std/example --role admin", "run the query from a file"],
['echo "1 + 1" | $0 query - --database us-std/example --role admin', "run the query from stdin"],
['$0 query -i /path/to/queries.fql -o /tmp/result.json --database us-std/example --role admin', "run the query and write to a file"],
['$0 query -i /path/to/queries.fql -o /tmp/result.json --extra --database us-std/example --role admin', "run the query and write full API response to a file"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--role will default to admin when minting a key for the specified database path. Maybe examples should show you don't have to provide role arg.

Also reminds me to go test out custom user roles...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure?

./src/user-entrypoint.mjs query -d us-std/A --url https://db.fauna-dev.com "Database.all()"          
fauna query [fql]

<...snip>

Failed to make request to Fauna account API [404]: undefined - Role 'undefined' doesn't exist.

const credentials = container.resolve("credentials");

await credentials.databaseKeys.onInvalidCreds();
const refreshedSecret = await credentials.databaseKeys.getOrRefreshKey();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we already awaited the refresh via onInvalidCreds, safe to just access ".key" here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clean this up in a follow-up.

Comment on lines +44 to +50
const validateQueryParams = ({ query, client, url, secret }) => {
if (!query) {
throw new Error("A query is required.");
} else if (!client && (!url || !secret)) {
throw new Error("A client or url and secret are required.");
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saw some validation of args above somewhere as well. I have some arg validation in Credentials class too.

Thoughts on validating all args and their combinations in one place in middleware before we get to handlers?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory, this check doesn't need to be here at all. The fauna client will barf if we're missing things. This error isn't adding a lot of value as-is.

@ecooper ecooper merged commit cbdc8cd into v3 Dec 2, 2024
4 checks passed
@ecooper ecooper deleted the v3-eval-to-query branch December 2, 2024 18:18
@cleve-fauna cleve-fauna mentioned this pull request Dec 5, 2024
This was referenced Dec 6, 2024
@cleve-fauna cleve-fauna mentioned this pull request Dec 13, 2024
@wildemat wildemat mentioned this pull request Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants