diff --git a/.circleci/config.yml b/.circleci/config.yml index 29e77de6..c4b5e5d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,9 @@ executors: core: resource_class: large docker: - - image: cimg/node:18.20 + - image: cimg/node:22.9.0 + environment: + TERM: xterm-256color commands: build_and_test: @@ -15,11 +17,14 @@ commands: - run: name: Install dependencies - command: yarn install + command: npm ci - run: name: Run Tests - command: yarn test + command: npm test + + - store_test_results: + path: test-results.xml - store_artifacts: path: coverage @@ -37,3 +42,10 @@ workflows: jobs: - fauna-shell-tests: context: faunadb-drivers + filters: + branches: + # only build the branch "main" + # and branches ending in "-old" + only: + - main + - /^.+-old$/ diff --git a/.env.example b/.env.example deleted file mode 100644 index aa065526..00000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -FAUNA_DOMAIN="db.fauna.com" -FAUNA_SCHEME="https" -FAUNA_PORT="433" -FAUNA_SECRET="" \ No newline at end of file diff --git a/.env.test b/.env.test deleted file mode 100644 index 2ddf7582..00000000 --- a/.env.test +++ /dev/null @@ -1,4 +0,0 @@ -FAUNA_DOMAIN="core" -FAUNA_SCHEME="http" -FAUNA_PORT="8443" -FAUNA_SECRET="secret" diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 8aedc17c..00000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -experiments -node_modules diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 6e1516e9..00000000 --- a/.eslintrc +++ /dev/null @@ -1,57 +0,0 @@ -{ - "extends": ["oclif", "plugin:prettier/recommended"], - "rules": { - "no-await-in-loop": "off", - "new-cap": "off", - "quote-props": "off", - "no-negated-condition": "off", - "no-warning-comments": "off", - "spaced-comment": "off", - "max-nested-callbacks": "off", - "no-else-return": "off", - "no-console": "off", - "no-multi-str": "off", - "no-prototype-builtins": "off", - "unicorn/escape-case": "off", - "node/no-extraneous-require": [ - "error", - { - "allowModules": [ - "@oclif/errors", - "expect", - "jest-mock", - "@jest/globals" - ] - } - ], - // we use typescript so dynamic imports are fine - "node/no-unsupported-features": "off", - "camelcase": "off" - }, - "ignorePatterns": ["dist/**/*", "coverage/**/*"], - "overrides": [ - { - "files": ["*.test.js", "*.spec.js", "*.test.ts"], - "rules": { - "no-unused-expressions": "off", - "node/no-missing-require": "off" - } - }, - { - "files": ["*.ts"], - "parser": "@typescript-eslint/parser", - "rules": { - "lines-between-class-members": "off", - "no-use-before-define": "off", - "no-undef-init": "off" - } - } - ], - "parser": "@babel/eslint-parser", - "parserOptions": { - "requireConfigFile": false - }, - "env": { - "mocha": true - } -} diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7011b20e..94d5eb96 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,3 @@ -Ticket(s): FE-### - ## Problem Explain the context and why you're making that change. What is the problem you're trying to solve? In some cases there is not a problem and this can be thought of being the motivation for your change. diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml new file mode 100644 index 00000000..ba758051 --- /dev/null +++ b/.github/workflows/build-binaries.yml @@ -0,0 +1,63 @@ +name: Build binaries +on: + push: + branches: [build] + +jobs: + build-binaries: + name: Build binaries + timeout-minutes: 5 + + strategy: + matrix: + runner: [macos-13, macos-latest, ubuntu-latest, windows-latest] + node: [22.x] + include: + - runner: macos-13 + os: mac + arch: x64 + - runner: macos-latest + os: mac + arch: arm + - runner: ubuntu-latest + os: linux + arch: x64 + - runner: windows-latest + os: windows + arch: x64 + # github-hosted (free) linux arm64 runner is planned by end of 2024 + # it's currently available on team/enterprise github plans: + # https://github.blog/news-insights/product-news/arm64-on-github-actions-powering-faster-more-efficient-build-systems/ + + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + - run: npm ci + - name: Build binary + run: npm run build + - uses: actions/upload-artifact@v4 + with: + # Name of the artifact to upload. + name: fauna-shell-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.node }} + + # A file, directory or wildcard pattern that describes what to upload + path: ${{ matrix.os == 'windows' && 'dist\fauna.exe' || 'dist/fauna' }} + + # Fail the action with an error message if no files are found at the path. + if-no-files-found: error + + # Duration after which artifact will expire in days. 0 means use the repository's default retention. + retention-days: 0 + + # The level of compression for Zlib to be applied to the artifact archive from 0 (none) to 9 (most). + compression-level: 6 + + # Deletes any artifact with a matching name before a new one is uploaded. + # Does not fail if the artifact does not exist. + overwrite: true + + # Don't upload hidden files in the provided path. + include-hidden-files: false diff --git a/.github/workflows/close-jira-ticket.yml b/.github/workflows/close-jira-ticket.yml deleted file mode 100644 index a472052e..00000000 --- a/.github/workflows/close-jira-ticket.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Set JIRA ticket to DONE - -on: - issues: - types: [closed, deleted] - -jobs: - set_done_for_closed_issued: - name: Set JIRA ticket to DONE - runs-on: ubuntu-latest - steps: - - name: Login - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - - name: Find comment with ticket number - uses: peter-evans/find-comment@v1 - id: comment - with: - issue-number: ${{ github.event.issue.number }} - body-includes: Internal ticket number is FE- - - - name: Get ticket number - id: ticket - uses: atlassian/gajira-find-issue-key@master - with: - string: ${{ steps.comment.outputs.comment-body }} - - - name: Close - uses: atlassian/gajira-transition@master - with: - issue: ${{ steps.ticket.outputs.issue }} - transition: "DONE" diff --git a/.github/workflows/create-jira-ticket-from-issue.yml b/.github/workflows/create-jira-ticket-from-issue.yml deleted file mode 100644 index 67fd205b..00000000 --- a/.github/workflows/create-jira-ticket-from-issue.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Create JIRA ticket for GH issue - -on: - issues: - types: [opened] - -jobs: - create_ticket_from_issue: - name: Create JIRA ticket - runs-on: ubuntu-latest - steps: - - name: Login - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - - name: Create - id: create - uses: atlassian/gajira-create@master - with: - project: FE - issuetype: Bug - summary: Issue ${{ github.event.issue.number }} ${{ github.event.issue.title }} - description: ${{ github.event.issue.html_url }} - fields: '{"labels": ["github", "issue", "dx-ops"], "components": [{ "name": "Fauna Shell" }]}' - - - name: Comment - uses: peter-evans/create-or-update-comment@v1 - with: - issue-number: ${{ github.event.issue.number }} - body: Internal ticket number is ${{ steps.create.outputs.issue }} - - - name: Complete - if: ${{ steps.create.outputs.issue }} - run: echo "Issue ${{ steps.create.outputs.issue }} was created" diff --git a/.github/workflows/create-jira-ticket-from-pull-request.yml b/.github/workflows/create-jira-ticket-from-pull-request.yml deleted file mode 100644 index a2e2fc1c..00000000 --- a/.github/workflows/create-jira-ticket-from-pull-request.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Create JIRA ticket for GH pull request - -on: - pull_request: - types: [opened] - -jobs: - create_ticket_from_pr: - name: Create JIRA ticket - runs-on: ubuntu-latest - if: ${{ github.actor != 'dependabot[bot]' }} - steps: - - name: Login - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - - name: Create - id: create - uses: atlassian/gajira-create@master - with: - project: FE - issuetype: Task - summary: Pull Request ${{ github.event.pull_request.number }} ${{ github.event.pull_request.title }} - description: ${{ github.event.pull_request.html_url }} - fields: '{"labels": ["github", "pr", "dx-ops"], "components": [{ "name": "Fauna Shell" }]}' - - - name: Complete - if: ${{ steps.create.outputs.issue }} - run: echo "Issue ${{ steps.create.outputs.issue }} was created" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..8f3d5d78 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,27 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: Lint and prettify + +on: + # temporarily "v3"; change to "main" after merge + push: + branches: ["v3"] + pull_request: + branches: ["v3"] + +jobs: + lint: + runs-on: ubuntu-latest + timeout-minutes: 2 + + steps: + - uses: actions/checkout@v4 + - name: Lint (nodeJS 22.x) + uses: actions/setup-node@v4 + with: + node-version: 22.x + cache: "npm" + - run: npm ci + - run: npm run format:check + - run: npm run lint diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..425d16df --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: Test + +on: + # temporarily "v3"; change to "main" after merge + push: + branches: ["v3"] + pull_request: + branches: ["v3"] + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 3 + + strategy: + matrix: + node-version: [20.x, 22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v4 + - name: Test (nodeJS ${{ matrix.node-version }}) + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + - run: npm ci + - run: npm run test:ci + env: + TERM: xterm-256color + # Set to the correct color level; 2 is 256 colors + # https://github.com/chalk/chalk?tab=readme-ov-file#supportscolor + FORCE_COLOR: 2 + - name: Publish Test Report + uses: mikepenz/action-junit-report@v4 + if: success() || failure() # always run even if the previous step fails + with: + report_paths: "**/test-results.xml" diff --git a/.gitignore b/.gitignore index 33d53969..05ae68e1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,16 @@ experiments *# .log coverage +test-results.xml +.history + +# test directory for persisted files +/test/test-homedir + +# default fauna config file names +fauna.config.yaml, +fauna.config.yml, +fauna.config.json, +.fauna.config.yaml, +.fauna.config.yml, +.fauna.config.json, diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 00000000..56b9d193 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npm run format && npm run lint diff --git a/.ignore b/.ignore new file mode 100644 index 00000000..722f19f0 --- /dev/null +++ b/.ignore @@ -0,0 +1 @@ +**/*.0x/** diff --git a/.mocharc.json b/.mocharc.json deleted file mode 100644 index ff56c8d7..00000000 --- a/.mocharc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require": [ - "test/helpers/init.js", - "ts-node/register" - ], - "watch-extensions": [ - "ts" - ], - "recursive": true, - "reporter": "spec", - "timeout": 5000 -} diff --git a/.nvmrc b/.nvmrc index 3c032078..2bd5a0a9 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18 +22 diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 0967ef42..00000000 --- a/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..237adddc --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,4 @@ +# @fauna/developer-experience are the default owners for everything in this repo. +# Later matches will take precedence over earlier matches. +# see https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners +* @fauna/developer-experience \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..dde1465e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,50 @@ +### Quick Start + +Install dependencies and verify you can execute the CLI: + +Sanity check your local setup: + +``` +# Install dependencies +npm install +# Run the local code +./src/user-entrypoint.mjs +# Make sure you can build the distributions: +npm run build +``` + +If you change code and want to see how it behaves from a customer-perspective: + +``` +./src/user-entrypoint.mjs [--option ...] +``` + +You can run the tests with: + +``` +npm run test +``` + +### Application versions + +This project has 3 runnable entrypoints (a raw ESM one, a built CJS one, and an SEA one). You can read more about them [here](./sea/README.md). + +### General style guidelines + +- Prefer to throw errors instead of exiting the process. Exit is harder to mock well in tests, and the global error-handler in `src/cli.mjs` should already do verbosity-aware error-handling. You can request a specific exit code by attaching an `exitCode` property to your error before throwing it. The error-handling has a series of tests in `yargs-test/general-cli.mjs`; if you find a case where throwing results in bad output to the user, replicate that case in a test suite. +- Prefer to re-throw an existing error after modifying its message over catching and throwing a newly-constructed error. The `exitCode` and `stack` properties on the existing error are worth keeping. + +#### Testing guidelines + +- Prefer to mock the "far" edges of the application - methods on `fs`, complex async libraries (e.g., `http#Server`), `fetch`. This results in the test code traversing all of the CLI's business logic, but not interacting with error-prone external resources like disk, network, port availability, etc. `sinon` records all calls to a mock, and allows asserting against them. Use this if, e.g., your business logic calls `fetch` multiple times. +- ~~Prefer to run local tests in watch mode with (e.g., with `yarn local-test`) while developing.~~ This is currently broken. +- Use debug logs to output the shape of objects (especially network responses) to determine how to structure mocks. For instance, to get a quick mock for a network request caused by `fauna schema status ...`, set the situation up and run `fauna schema status ... --verbosity 5`. You can then use the logged objects as mocks. + +#### Debugging strategies + +- Fetch is not particularly amenable to debugging, but if you need to see the raw requests being made, open a netcat server locally (`nc -l 8080`) and then change the code to call the netcat server, either by passing the flag `--url http://localhost:8080` or by editing the code. +- This project has debug logging with a somewhat configurable logging strategy. To use it, provide either: + - `--verbose-component foo`, which logs all debug info for the component `foo`. Because it's an array, you can specify it multiple times. To see the available components, look at the help or tab completion. + - `--verbosity level`, where `level` is a number from 0 (no debug logging) to 5 (all debug logging) for all components. +- To investigate why a sinon stub is failing in a way you don't expect, you can log out `stub.args`, which is an array of the arguments provided each time the stub was called. This can be particularly helpful for assertions where the error message is hard to read or involves objects that don't stringify correctly (like FormData). +- To trigger [SEA builds](./sea/README.md) on all supported OS/architecture combinations, make changes and push commits to the `build` branch in github. This will [trigger github actions](./.github/workflows/build-binaries.yml) that build the SEA binaries. diff --git a/README.md b/README.md index 3eccd26d..18c9babc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Fauna CLI +# Fauna CLI v4 (beta) -This tools gives you access to [Fauna](http://fauna.com/) directly from your CLI. +> [!IMPORTANT] +> v4 of the Fauna CLI is in beta. For the latest GA version, see the [Fauna CLI v3 +> docs](https://docs.fauna.com/fauna/current/build/cli/). -It also includes a [Shell](#shell) so you can issue queries to Fauna without -needing to install additional libraries. +The Fauna CLI lets you access [Fauna](http://fauna.com/) from your terminal. +You can use the CLI to: -You can install it via npm like this: +- Create and manage Fauna + [databases](https://docs.fauna.com/fauna/current/learn/data-model/databases/). +- Manage [database schema](https://docs.fauna.com/fauna/current/learn/schema/) + as `.fsl` files. +- Run [FQL queries](https://docs.fauna.com/fauna/current/learn/query/) from + files or in an interactive REPL. +- Run a local [Fauna container](https://docs.fauna.com/fauna/current/build/tools/docker/). -```sh -$ npm install -g fauna-shell -``` - -You can upgrade like this: - -``` -$ npm update -g fauna-shell -``` - - -* [Fauna CLI](#fauna-cli) -* [Usage](#usage) -* [Technical Requirements](#technical-requirements) -* [Shell](#shell) -* [Connecting to different endpoints](#connecting-to-different-endpoints) -* [Connecting to local endpoints](#connecting-to-local-endpoints) -* [Overriding Connection Parameters](#overriding-connection-parameters) -* [Executing queries from a file](#executing-queries-from-a-file) -* [List of Commands](#list-of-commands) -* [Development](#development) - - -# Usage - -The **Fauna CLI** allows you to do issue queries, modify database schema, and -create keys and databases. - -First lets configure our connection to a Fauna account. If you don't have an -account, you can create a free one [here](https://dashboard.fauna.com). - -To log in, run the following command: - -```sh -$ fauna cloud-login -``` +![fauna-cli](https://github.com/user-attachments/assets/d3e88ad9-68ae-4011-945a-23654f9fbd0a) -You will be prompted for your `email` and `password` from your -[Fauna](https://dashboard.fauna.com) account. +## Requirements -Now that we have an endpoint to connect to we can try to create a database to -start interacting with Fauna. +- [Node.js](https://nodejs.org/en/download/package-manager) v20.x or later. +- A Fauna account. You can sign up for a free account at https://dashboard.fauna.com/register. -This is how you can create a database called `my_app`: +## Quick start -```sh -$ fauna create-database my_app -creating database my_app - -created database my_app +To get started: -To start a shell with your new database, run: +1. Install the CLI: - fauna shell my_app + ```shell + npm install -g fauna-shell@">=4.0.0-beta" + ``` -Or, to create an application key for your database, run: - - fauna create-key my_app -``` +2. If you're using bash or zsh, enable auto-complete by appending the output of + `fauna completion` to your `.bashrc`, `.bash_profile`, `.zshrc,` or + `.zprofile`. For example: -Now, you can start a shell within that database. - -```sh -$ fauna shell my_app -my_app> Collection.create({ name: "Users" }) -{ - name: "Users", - coll: Collection, - ts: Time("2023-10-03T02:40:37.060Z"), - indexes: {}, - constraints: [] -} -my_app> -``` + ```shell + fauna completion >> ~/.zshrc + ``` -You can also list your databases: +3. Authenticate with Fauna: -```sh-session -$ fauna list-databases -listing databases -my_app -my_second_app -my_other_app -``` + ```shell + fauna login + ``` -You can delete a particular database: +4. Run CLI commands. Specify a `--database` path, including the [Region Group + identifier](https://docs.fauna.com/fauna/current/manage/region-groups/#id) and + hierarchy, to run the command in. For example: -```sh-session -$ fauna delete-database my_other_app -deleting database 'my_other_app' -database 'my_other_app' deleted -``` + ```shell + # Runs a query in the top-level 'example' database + # in the 'us' Region Group. Use the default admin role. + fauna query "Collection.all()" \ + --database us/example + ``` -And you can create, list, and delete keys. +## Installation -This is how you create a key for the database `my_app`: +During the beta, you can install v4 of the Fauna CLI globally using npm: ```sh -$ fauna create-key my_app -creating key for database 'my_app' with role 'admin' - -created key for database 'my_app' with role 'admin'. -secret: fnAFPULk2WAAQY9t4x0tduzuz85gC-suDbTnl7um # this will be different - -To access 'my_app' with this key, create a client using -the driver library for your language of choice using -the above secret. +npm install -g fauna-shell@">=4.0.0-beta" ``` -This is how to list keys: +## Documentation -```sh -$ fauna list-keys -listing keys -Key ID Database Role -203269476002562560 my_app admin -203269731203940864 my_app admin -203269732275585536 my_app admin -203269735610057216 test admin -``` +For usage instructions and a full [list of +commands](https://docs.fauna.com/fauna/current/build/cli/v4/commands/), see the +[Fauna docs](https://docs.fauna.com/fauna/current/build/cli/v4/). -And then delete the key with id: `200219702370238976`: +You can also access help directly in the CLI: ```sh -$ fauna delete-key 200219702370238976 -deleting key 200219702370238976 -key 200219702370238976 deleted -``` - -See [Commands](#commands) for a list of commands and help on their usage. - -# Requirements - -To use Fauna Shell, you must have Node.js v20.x or later. - -# Shell - -The Fauna Shell lets you issue queries directly to your Fauna database without -the need for installing additional libraries. - -Let's create a database and then we'll jump straight into the Shell to start -playing with Fauna's data model. - -```sh -$ fauna create-database my_app -``` - -Our next step is to start the shell for a specific database, in this case `my_app`: - -```sh -$ fauna shell my_app -Starting shell for database my_app -Connected to http://127.0.0.1:8443 -Type Ctrl+D or .exit to exit the shell -my_app> -``` - -Once you have the prompt ready, you can start issues queries against your Fauna -database. Note that the results shown here might vary from the ones you see -while running the examples. - -```ts -my_app> Collection.create({ name: "Post" }) -{ - name: "Post", - coll: Collection, - ts: Time("2023-08-15T16:06:01.120Z"), - indexes: {}, - constraints: [] -} -``` - -Let's create an index for our collection `Post`. - -```ts -my_app> Post.definition.update({ indexes: { byTitle: { terms: [{ field: ".title" }] } } }) -{ - name: "Post", - coll: Collection, - ts: Time("2023-08-15T16:07:10.800Z"), - indexes: { - byTitle: { - terms: [ - { - field: ".title" - } - ], - queryable: true, - status: "complete" - } - }, - constraints: [] -} -``` - -Let's insert a new `Post` document: - -```ts -my_app> Post.create({ title: "What I had for breakfast .." }) -{ - id: "373143369066480128", - coll: Post, - ts: Time("2023-08-15T16:14:57.440Z"), - title: "What I had for breakfast .." -} -``` - -We can also insert items in bulk by using iterator functions on arrays. - -```ts -my_app> [ - "My cat and other marvels", - "Pondering during a commute", - "Deep meanings in a latte" -].map(title => Post.create({ title: title })) -[ - { - id: "373143473418666496", - coll: Post, - ts: Time("2023-08-15T16:16:36.960Z"), - title: "My cat and other marvels" - }, - { - id: "373143473419715072", - coll: Post, - ts: Time("2023-08-15T16:16:36.960Z"), - title: "Pondering during a commute" - }, - { - id: "373143473420763648", - coll: Post, - ts: Time("2023-08-15T16:16:36.960Z"), - title: "Deep meanings in a latte" - } -] -``` - -Now let's try to fetch our post about _latte_. We need to access it by _id_ like this: - -```ts -my_app> Post.byId("373143473420763648") -{ - id: "373143473420763648", - coll: Post, - ts: Time("2023-08-15T16:16:36.960Z"), - title: "Deep meanings in a latte" -} -``` - -Now let's update our post about our cat, by adding some tags: - -```ts -my_app> Post.byId("373143473420763648")!.update({ tags: ["cute", "pet"] }) -{ - id: "373143473420763648", - coll: Post, - ts: Time("2023-08-15T16:17:41Z"), - title: "Deep meanings in a latte", - tags: [ - "cute", - "pet" - ] -} -``` - -And now let's try to change the content of that post: - -```ts -my_app> Post.byId("373143473418666496")!.replace({ title: "My dog and other marvels" }) -{ - id: "373143473418666496", - coll: Post, - ts: Time("2023-08-15T16:18:32.680Z"), - title: "My dog and other marvels" -} -``` - -Now let's try to delete our post about _latte_: - -```ts -my_app> Post.byId("373143473420763648")!.delete() -Post.byId("373143473420763648") /* not found */ -``` - -If we try to fetch it, we will receive a null document: - -```ts -my_app> Post.byId("373143473420763648") -Post.byId("373143473420763648") /* not found */ -``` - -Finally you can exit the _shell_ by pressing `ctrl+d`. - -# Connecting to different endpoints - -We can add endpoints by calling the following command `endpoint add`. This is -meant to be used when connecting to a docker container. - -```sh -$ fauna endpoint add -? Endpoint name localhost -? Database URL http://localhost:8443 -? Database Secret secret -Checking secret... done -? Make this endpoint default [no] -Saved endpoint localhost to ~/.fauna-shell -``` - -The endpoint name is an arbitrary name that can be used in the `--endpoint` flag -of other commands. The database URL should typically be `http://localhost:8443` -or `https://db.fauna.com`, although it can be set to any URL to a fauna -instance. The database secret is the secret used to authenticate with that -database. - -An endpoint can be set as the default, in which case `fauna shell` and -`fauna eval` will choose that endpoint by default. - -Endpoints can be listed with the `endpoint list` command like this: - -```sh -$ fauna endpoint list - localhost -* cloud -``` - -There we see that the `cloud` endpoint has a `*` next to its name, meaning that -it's the current default one. - -Finally, endpoints will be saved to a `~/.fauna-shell` file like this: - -```ini -default=cloud - -[endpoint.localhost] -url=http://localhost:8443 -secret=secret - -[endpoint.cloud] -secret=FAUNA_SECRET_KEY -``` - -# Connecting to local endpoints - -If you are running Fauna locally using our Docker image, you will need to -configure the CLI to work with local endpoints so you can interact with the -database running in the Docker container. - -The docker container is explained in depth here: -https://docs.fauna.com/fauna/current/tools/dev. - -Once you've installed the Shell and logged in, you can configure it by doing the -following: - -By default, the Fauna Docker image serves data via port 8443. To add a -connection to this port, run `fauna endpoint add`. The Database URL should be -`http://localhost:8443` (the default), and the database secret should be -`secret` by default. - -```sh -$ fauna endpoint add -? Endpoint name localhost -? Database URL http://localhost:8443 -? Database Secret secret -Checking secret... done -? Make this endpoint default [no] -Saved endpoint localhost to ~/.fauna-shell -``` - -Now, you can interact with your local database through the Fauna Shell by -running the command below: - -```sh -fauna shell --endpoint localhost -``` - -# Overriding Connection Parameters - -Most commands support the following options. You can specify them if you want to -connect to a local instance of Fauna. - -```sh -OPTIONS - --endpoint=name Selects an endpoint from ~/.fauna-shell - --endpointURL=domain Overrides the `url` setting in the selected endpoint. - --secret=secret Overrides the `secret` setting in the selected endpoint. - --timeout=timeout [default: 5000] Connection timeout in milliseconds -``` - -`--endpoint` doesn't need to be set if `--endpointURL` and `--secret` are provided. - -They can be used like this: - -```sh -$ fauna create-database testdb --endpointURL=http://127.0.0.1:8443 --secret=YOUR_FAUNA_SECRET_KEY --timeout=42 -``` - -You could select another endpoint from `~/.fauna-shell` using `--endpoint`: +# For general help: +fauna --help -```sh-session -$ fauna shell --endpoint=localhost +# For a specific command: +fauna --help +# For example: +fauna query --help ``` -Any options that are not specified either via the `.fauna-shell` config file or -the CLI will be set to the defaults offered by the -[JS driver](https://github.com/fauna/fauna-js). +## Contributions and development -# Executing queries from a file - -You can also tell the shell to execute a list of queries that you have stored in -a file. For example, you can have a file that creates a collection called -`setup.fql`: - -```ts -Collection.create({ - name: "Post", - indexes: { - byTitle: { - terms: [{ field: ".title" }] - } - } -}) -``` - -Once the collection is created, you can execute queries against it in another -`.fql` file: - -```ts -Post.create({ - title: "What I had for breakfast .." -}) - -[ - "My cat and other marvels", - "Pondering during a commute", - "Deep meanings in a latte", -].map(title => { - Post.create({ - title: title - }) -}) -``` - -You can tell Fauna Shell to execute all those queries for you by running the -following command: - -```bash -$ fauna eval my_app --file=./setup.fql -$ fauna eval my_app --file=./queries.fql -``` - -Where `my_app` is the name of your database, and `./queries.fql` is the path to -the file where you saved the queries. If `my_app` is left out it will execute -the queries file on the default fauna shell endpoint. - - - -# List of Commands - - -* [`fauna add-endpoint [NAME]`](#fauna-add-endpoint-name) -* [`fauna cloud-login`](#fauna-cloud-login) -* [`fauna create-database DBNAME`](#fauna-create-database-dbname) -* [`fauna create-key DBNAME [ROLE]`](#fauna-create-key-dbname-role) -* [`fauna default-endpoint [NAME]`](#fauna-default-endpoint-name) -* [`fauna delete-database DBNAME`](#fauna-delete-database-dbname) -* [`fauna delete-endpoint NAME`](#fauna-delete-endpoint-name) -* [`fauna delete-key KEYNAME`](#fauna-delete-key-keyname) -* [`fauna endpoint add [NAME]`](#fauna-endpoint-add-name) -* [`fauna endpoint list`](#fauna-endpoint-list) -* [`fauna endpoint remove NAME`](#fauna-endpoint-remove-name) -* [`fauna endpoint select [NAME]`](#fauna-endpoint-select-name) -* [`fauna environment add`](#fauna-environment-add) -* [`fauna environment list`](#fauna-environment-list) -* [`fauna environment select ENVIRONMENT`](#fauna-environment-select-environment) -* [`fauna eval [DBNAME] [QUERY]`](#fauna-eval-dbname-query) -* [`fauna help [COMMANDS]`](#fauna-help-commands) -* [`fauna import`](#fauna-import) -* [`fauna list-databases`](#fauna-list-databases) -* [`fauna list-endpoints`](#fauna-list-endpoints) -* [`fauna list-keys`](#fauna-list-keys) -* [`fauna project init [PROJECTDIR]`](#fauna-project-init-projectdir) -* [`fauna run-queries [DBNAME] [QUERY]`](#fauna-run-queries-dbname-query) -* [`fauna schema diff`](#fauna-schema-diff) -* [`fauna schema pull`](#fauna-schema-pull) -* [`fauna schema push`](#fauna-schema-push) -* [`fauna shell [DB_PATH]`](#fauna-shell-db_path) -* [`fauna upload-graphql-schema GRAPHQLFILEPATH`](#fauna-upload-graphql-schema-graphqlfilepath) - -## `fauna add-endpoint [NAME]` - -Add an endpoint to ~/.fauna-shell. - -``` -USAGE - $ fauna add-endpoint [NAME] [--non-interactive --url --secret ] [--set-default] - -ARGUMENTS - NAME Endpoint name - -FLAGS - --non-interactive Disables interaction - --secret= Database secret - --set-default Sets this environment as the default - --url= Database URL - -DESCRIPTION - Add an endpoint to ~/.fauna-shell. - -ALIASES - $ fauna add-endpoint - -EXAMPLES - $ fauna endpoint add - - $ fauna endpoint add localhost --url http://localhost:8443/ --secret secret - - $ fauna endpoint add localhost --set-default -``` - -## `fauna cloud-login` - -Log in to a Fauna account. - -``` -USAGE - $ fauna cloud-login - -DESCRIPTION - Log in to a Fauna account. - -EXAMPLES - $ fauna cloud-login -``` - -_See code: [dist/commands/cloud-login.ts](https://github.com/fauna/fauna-shell/blob/v1.2.1/dist/commands/cloud-login.ts)_ - -## `fauna create-database DBNAME` - -Create a database. - -``` -USAGE - $ fauna create-database DBNAME [--url ] [--timeout ] [--secret ] [--endpoint ] - [--environment ] - -ARGUMENTS - DBNAME database name - -FLAGS - --endpoint= Connection endpoint, from ~/.fauna-shell - --environment= Environment to use, from a Fauna project - --secret= Secret key. Overrides the `secret` in ~/.fauna-shell - --timeout= Connection timeout in milliseconds - --url= Database URL. Overrides the `url` in ~/.fauna-shell - -DESCRIPTION - Create a database. - -EXAMPLES - $ fauna create-database dbname -``` - -_See code: [dist/commands/create-database.ts](https://github.com/fauna/fauna-shell/blob/v1.2.1/dist/commands/create-database.ts)_ - -## `fauna create-key DBNAME [ROLE]` - -Create a key for the specified database. - -``` -USAGE - $ fauna create-key DBNAME [ROLE] [--url ] [--timeout ] [--secret ] [--endpoint ] - [--environment ] - -ARGUMENTS - DBNAME database name - ROLE (admin|server|server-readonly|client) key user role - -FLAGS - --endpoint= Connection endpoint, from ~/.fauna-shell - --environment= Environment to use, from a Fauna project - --secret= Secret key. Overrides the `secret` in ~/.fauna-shell - --timeout= Connection timeout in milliseconds - --url= Database URL. Overrides the `url` in ~/.fauna-shell - -DESCRIPTION - Create a key for the specified database. - -EXAMPLES - $ fauna create-key dbname admin -``` - -_See code: [dist/commands/create-key.ts](https://github.com/fauna/fauna-shell/blob/v1.2.1/dist/commands/create-key.ts)_ - -## `fauna default-endpoint [NAME]` - -Set an endpoint as the default one. - -``` -USAGE - $ fauna default-endpoint [NAME] - -ARGUMENTS - NAME New default endpoint - -DESCRIPTION - Set an endpoint as the default one. - -ALIASES - $ fauna default-endpoint - -EXAMPLES - $ fauna endpoint select - - $ fauna endpoint select endpoint -``` - -## `fauna delete-database DBNAME` - -Delete a database. - -``` -USAGE - $ fauna delete-database DBNAME [--url ] [--timeout ] [--secret ] [--endpoint ] - [--environment ] - -ARGUMENTS - DBNAME database name - -FLAGS - --endpoint= Connection endpoint, from ~/.fauna-shell - --environment= Environment to use, from a Fauna project - --secret= Secret key. Overrides the `secret` in ~/.fauna-shell - --timeout= Connection timeout in milliseconds - --url= Database URL. Overrides the `url` in ~/.fauna-shell - -DESCRIPTION - Delete a database. - -EXAMPLES - $ fauna delete-database dbname -``` - -_See code: [dist/commands/delete-database.ts](https://github.com/fauna/fauna-shell/blob/v1.2.1/dist/commands/delete-database.ts)_ - -## `fauna delete-endpoint NAME` - -Remove an endpoint from ~/.fauna-shell. - -``` -USAGE - $ fauna delete-endpoint NAME - -ARGUMENTS - NAME Endpoint name - -DESCRIPTION - Remove an endpoint from ~/.fauna-shell. - -ALIASES - $ fauna delete-endpoint - -EXAMPLES - $ fauna endpoint remove my_endpoint -``` - -## `fauna delete-key KEYNAME` - -Delete a key. - -``` -USAGE - $ fauna delete-key KEYNAME [--url ] [--timeout ] [--secret ] [--endpoint ] - [--environment ] - -ARGUMENTS - KEYNAME key name - -FLAGS - --endpoint= Connection endpoint, from ~/.fauna-shell - --environment= Environment to use, from a Fauna project - --secret= Secret key. Overrides the `secret` in ~/.fauna-shell - --timeout= Connection timeout in milliseconds - --url= Database URL. Overrides the `url` in ~/.fauna-shell - -DESCRIPTION - Delete a key. - -EXAMPLES - $ fauna delete-key 123456789012345678 -``` - -_See code: [dist/commands/delete-key.ts](https://github.com/fauna/fauna-shell/blob/v1.2.1/dist/commands/delete-key.ts)_ - -## `fauna endpoint add [NAME]` - -Add an endpoint to ~/.fauna-shell. - -``` -USAGE - $ fauna endpoint add [NAME] [--non-interactive --url --secret ] [--set-default] - -ARGUMENTS - NAME Endpoint name - -FLAGS - --non-interactive Disables interaction - --secret= Database secret - --set-default Sets this environment as the default - --url= Database URL - -DESCRIPTION - Add an endpoint to ~/.fauna-shell. - -ALIASES - $ fauna add-endpoint - -EXAMPLES - $ fauna endpoint add - - $ fauna endpoint add localhost --url http://localhost:8443/ --secret secret - - $ fauna endpoint add localhost --set-default -``` - -## `fauna endpoint list` - -List endpoints in ~/.fauna-shell. - -``` -USAGE - $ fauna endpoint list - -DESCRIPTION - List endpoints in ~/.fauna-shell. - -ALIASES - $ fauna list-endpoints - -EXAMPLES - $ fauna endpoint list -``` - -## `fauna endpoint remove NAME` - -Remove an endpoint from ~/.fauna-shell. - -``` -USAGE - $ fauna endpoint remove NAME - -ARGUMENTS - NAME Endpoint name - -DESCRIPTION - Remove an endpoint from ~/.fauna-shell. - -ALIASES - $ fauna delete-endpoint - -EXAMPLES - $ fauna endpoint remove my_endpoint -``` - -## `fauna endpoint select [NAME]` - -Set an endpoint as the default one. - -``` -USAGE - $ fauna endpoint select [NAME] - -ARGUMENTS - NAME New default endpoint - -DESCRIPTION - Set an endpoint as the default one. - -ALIASES - $ fauna default-endpoint - -EXAMPLES - $ fauna endpoint select - - $ fauna endpoint select endpoint -``` - -## `fauna environment add` - -Add a new environment to `.fauna-project`. - -``` -USAGE - $ fauna environment add [--non-interactive --name --endpoint --database ] [--set-default] - -FLAGS - --database= Database path to use in this environment - --endpoint= Endpoint to use in this environment - --name= New environment name - --non-interactive Disable interaction - --set-default Set this environment as the default - -DESCRIPTION - Add a new environment to `.fauna-project`. - -EXAMPLES - $ fauna environment add - - $ fauna environment add --name my-app --endpoint dev --database my-database - - $ fauna environment add --name my-app --endpoint dev --database my-database --set-default -``` - -## `fauna environment list` - -List environments available in `.fauna-project`. - -``` -USAGE - $ fauna environment list - -DESCRIPTION - List environments available in `.fauna-project`. - -EXAMPLES - $ fauna environment list -``` - -## `fauna environment select ENVIRONMENT` - -Update the default environment in `.fauna-project`. - -``` -USAGE - $ fauna environment select ENVIRONMENT - -ARGUMENTS - ENVIRONMENT The new default environment to use - -DESCRIPTION - Update the default environment in `.fauna-project`. - -EXAMPLES - $ fauna environment select my-environment -``` - -## `fauna eval [DBNAME] [QUERY]` - -Evaluate the given query. - -``` -USAGE - $ fauna eval [DBNAME] [QUERY] [--url ] [--timeout ] [--secret ] [--endpoint - ] [--environment ] [--file ] [--stdin] [--output ] [--format json|json-tagged|shell] - [--version 4|10] [--typecheck] - -ARGUMENTS - DBNAME Database name - QUERY FQL query to execute - -FLAGS - --endpoint= Connection endpoint, from ~/.fauna-shell - --environment= Environment to use, from a Fauna project - --file= File where to read queries from - --format=