Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
A driver to query Fauna databases in browsers, Node.js, and other Javascript runtimes
This driver can only be used with FQL v10, and is not compatible with earlier versions of FQL. To query your databases with earlier API versions, see the faunadb package.
See the Fauna Documentation for additional information how to configure and query your databases.
import { Client, fql, FaunaError } from "fauna";
// configure your client
const client = new Client({
secret: YOUR_FAUNA_SECRET,
});
try {
// build queries using the `fql` function
const collectionQuery = fql`Collection.create({ name: "Dogs" })`;
// execute the query
const collectionResponse = await client.query(collectionQuery);
// define some data in your app
const dog = { name: "Scout" };
// query using your app's local variables
const documentQuery = fql`
Dogs.create(${dog}) {
id,
ts,
name
}
`;
// execute the query
const response = await client.query(documentQuery);
} catch (error) {
if (error instanceof FaunaError) {
// handle errors
}
} finally {
// clean up any remaining resources
client.close();
}
This Driver supports and is tested on:
The fauna-js driver is available on npm. You can install with your package manager of choice:
npm install fauna
or
yarn add fauna
The driver is additionally made available to browsers via CDN:
<script type="module">
import * as fauna from "https://cdn.jsdelivr.net/npm/fauna@latest/dist/browser/index.js";
</script>
fql
functionThe fql
function is your gateway to building safe, reuseable Fauna queries.
It allows you compose queries from sub-queries and variables native to your program. Variables passed in are treated as unexecutable values in Fauna's API - preventing security issues like injection attacks.
for example:
import { Client, fql } from "fauna";
const client = new Client();
// Variables can be used as arguments in an FQL query
const collectionName = "Pets";
// a reusable sub-query to determine if a collection exists
const collectionExists = (name) => fql`Collection.byName(${name}) != null`;
// define a new query that uses the prior sub-query
const upsertCollectionQuery = fql`
if (${collectionExists(collectionName)}) {
"Collection exists!"
} else {
Collection.create({ name: ${collectionName} })
"Collection exists now!"
}
`;
// execute the query
const response = await client.query(upsertCollectionQuery);
client.close();
This has several advantages:
fql
to build a library of subqueries applicable to your domain - and combinable in whatever way you need`${interpoloated_argument}`
) parts of the query.fql`copied from terminal...`
and the query will work as is.<html>
<head></head>
<body>
<h1>Test</h1>
</body>
<script type="module">
import * as fauna from "https://cdn.jsdelivr.net/npm/fauna@latest/dist/browser/index.js";
/* ... */
</script>
</html>
import * as fauna from "fauna";
or using require
for CommonJS files
const fauna = require("fauna");
With TypeScript, you can apply a type parameter to your result.
import { Client, fql } from "fauna";
const client = new Client();
type User = {
name: string;
email: string;
};
const query = fql`{
name: "Alice",
email: "alice@site.example",
}`;
const response: QuerySuccess<User> = await client.query<User>(query);
const user_doc: User = response.data;
console.assert(user_doc.name === "Alice");
console.assert(user_doc.email === "alice@site.example");
client.close();
Options are available to configure queries on each request.
import { fql, Client, type QueryOptions } from "fauna";
const client = new Client();
const options: QueryOptions = {
arguments: { name: "Alice" },
format: "tagged",
long_type: "number",
linearized: false,
max_contention_retries: 5,
query_tags: { name: "readme_query" },
query_timeout_ms: 60_000,
traceparent: "00-750efa5fb6a131eb2cf4db39f28366cb-000000000000000b-00",
typecheck: true,
};
const response = await client.query(fql`"Hello, #{name}!"`, options);
client.close();
The driver use's a default ClientConfiguration. We recommend most users stick with the defaults.
If your environment needs different configuration however, the default ClientConfiguration can be overridden.
Furthermore, on each request you can provide query specific configuration that will override the setting in your client for that request only.
import { Client, endpoints, type ClientConfiguration } from "fauna";
const config: ClientConfiguration = {
// configure client
client_timeout_buffer_ms: 5000,
endpoint: endpoints.default,
fetch_keepalive: false,
http2_max_streams: 100,
http2_session_idle_ms: 5000,
secret: YOUR_FAUNA_SECRET,
// set default query options
format: "tagged",
long_type: "number",
linearized: false,
max_attempts: 3,
max_backoff: 20,
max_contention_retries: 5,
query_tags: { name: "readme query" },
query_timeout_ms: 60_000,
traceparent: "00-750efa5fb6a131eb2cf4db39f28366cb-000000000000000b-00",
typecheck: true,
};
const client = new Client(config);
The maximum number of times a query will be attempted if a retryable exception is thrown (ThrottlingError). Default 3, inclusive of the initial call. The retry strategy implemented is a simple exponential backoff.
To disable retries, pass max_attempts less than or equal to 1.
The maximum backoff in seconds to be observed between each retry. Default 20 seconds.
There are a few different timeout settings that can be configured; each comes with a default setting. We recommend that most applications simply stick to the defaults.
The query timeout is the time, in milliseconds, that Fauna will spend executing your query before aborting with a 503 Timeout error. If a query timeout occurs, the driver will throw an instance of ServiceTimeoutError
.
The query timeout can be set using the ClientConfiguration.query_timeout_ms
option. The default value if you do not provide one is 5000 ms (5 seconds).
const client = new Client({ query_timeout_ms: 20_000 });
The query timeout can also be set to a different value for each query using the QueryOptions.query_timeout_ms
option. Doing so overrides the client configuration when performing this query.
const response = await client.query(myQuery, { query_timeout_ms: 20_000 });
The client timeout is the time, in milliseconds, that the client will wait for a network response before canceling the request. If a client timeout occurs, the driver will throw an instance of NetworkError
.
The client timeout is always the query timeout plus an additional buffer. This ensures that the client always waits for at least as long Fauna could work on your query and account for network latency. The client timeout buffer is configured by setting the client_timeout_buffer_ms
option. The default value for the buffer if you do not provide on is 5000 ms (5 seconds), therefore the default client timeout is 10000 ms (10 s) when considering the default query timeout.
const client = new Client({ client_timeout_buffer_ms: 6000 });
The HTTP/2 session idle timeout is the time, in milliseconds, that an HTTP/2 session will remain open after there is no more pending communication. Once the session idle time has elapsed the session is considered idle and the session is closed. Subsequent requests will create a new session; the session idle timeout does not result in an error.
Configure the HTTP/2 session idle timeout using the http2_session_idle_ms
option. The default value if you do not provide one is 5000 ms (5 seconds).
This setting only applies to clients using HTTP/2 implementations; for example, the default client for Node.js runtimes.
const client = new Client({ http2_session_idle_ms: 6000 });
Note Your application process may continue executing after all requests are completed for the duration of the session idle timeout. To prevent this, it is recommended to call
Client.close()
once all requests are complete. It is not recommended to sethttp2_session_idle_ms
to small values.
Warning Setting
http2_session_idle_ms
to small values can lead to a race condition where requests cannot be transmitted before the session is closed, yieldingERR_HTTP2_GOAWAY_SESSION
errors.
The driver will default to configuring your client with the values of the FAUNA_SECRET
and FAUNA_ENDPOINT
environment variable.
For example, if you set the following environment variables:
export FAUNA_SECRET=YOUR_FAUNA_SECRET
export FAUNA_ENDPOINT=https://db.fauna.com/
you can create a client without additional options
const client = new Client();
Query statistics are returned with successful query responses and ServiceError
s.
import {
fql,
Client,
ServiceError,
type QueryInfo,
type QueryStats,
type QuerySuccess,
} from "fauna";
const client = new Client();
try {
const response: QuerySuccess<string> = await client.query<string>(
fql`"Hello world"`
);
const stats: QueryStats | undefined = response.stats;
console.log(stats);
} catch (error: any) {
if (error instanceof ServiceError) {
const info: QueryInfo = error.queryInfo;
const stats: QueryStats | undefined = info.stats;
}
}
/* example output
* ```
* {
* compute_ops: 1,
* read_ops: 0,
* write_ops: 0,
* query_time_ms: 15,
* storage_bytes_read: 0,
* storage_bytes_write: 0,
* contention_retries: 0
* }
* ```
*/
Obtain a stream token using a regular query with either the toStream()
or changesOn()
FQL methods on a Set.
import { Client, fql } from "fauna"
const client = new Client({ secret: FAUNA_SECRET })
const response = await client.query(fql`
let set = MyCollection.all()
{
initialPage: set.pageSize(10),
streamToken: set.toStream()
}
`);
const { initialPage, streamToken } = response.data;
const stream = client.stream(streamToken)
The driver will take care of the initial request to convert to a stream if you provide a Query
import { Client, fql } from "fauna"
const client = new Client({ secret: FAUNA_SECRET })
const stream = await client.stream(fql`MyCollection.all().changesOn(.field1, .field2)`)
There are two Two ways to initiate the stream:
Async Iterator example
try {
for await (const event of stream) {
switch (event.type) {
case "update":
case "add":
case "remove":
console.log("Stream event:", event);
// ...
break;
}
}
} catch (error) {
// An error will be handled here if Fauna returns a terminal, "error" event, or
// if Fauna returns a non-200 response when trying to connect, or
// if the max number of retries on network errors is reached.
// ... handle fatal error
}
Callbacks example
stream.start(
function onEvent(event) {
switch (event.type) {
case "update":
case "add":
case "remove":
console.log("Stream event:", event);
// ...
break;
}
},
function onFatalError(error) {
// An error will be handled here if Fauna returns a terminal, "error" event, or
// if Fauna returns a non-200 response when trying to connect, or
// if the max number of retries on network errors is reached.
// ... handle fatal error
}
);
Any contributions are from the community are greatly appreciated!
If you have a suggestion that would make this better, please fork the repo and create a pull request. You may also simply open an issue. We provide templates, so please complete those to the best of your ability.
Don't forget to give the project a star! Thanks again!
gh repo clone fauna/fauna-js
if you use the GitHub CLIyarn install
yarn test
. This will start local fauna containers, verify they're up and run all tests.Linting runs automatically on each commit.
If you wish to run on-demand run yarn lint
.
Distributed under the MPL 2.0 License. See LICENSE for more information.
FAQs
A driver to query Fauna databases in browsers, Node.js, and other Javascript runtimes
The npm package fauna receives a total of 1,832 weekly downloads. As such, fauna popularity was classified as popular.
We found that fauna demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.