Skip to content

Commit

Permalink
Better support for interfaces as query responses (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
ptpaterson authored Nov 13, 2024
1 parent 6baf2b1 commit 3de4b6d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ See the [Fauna Documentation](https://docs.fauna.com/fauna/current/) for additio
- [Usage](#usage)
- [Write FQL queries](#write-fql-queries)
- [Typescript support](#typescript-support)
- [Interfaces as `QueryValue` responses](#interfaces-as-queryvalue-responses)
- [Query options](#query-options)
- [Query statistics](#query-statistics)
- [Pagination](#pagination)
Expand Down Expand Up @@ -239,6 +240,25 @@ console.assert(userDoc.email === "alice@site.example");
client.close();
```

#### Interfaces as `QueryValue` responses

To use a custom interface as a query response, extend the `QueryValueObject`
interface.

```typescript
interface User extends QueryValueObject {
name: string;
email: string;
}

const query = fql`{
name: "Alice",
email: "alice@site.example",
}`;

const response: QuerySuccess<User> = await client.query<User>(query);
```

### Query options

Options are available to configure queries on each request. These override any
Expand Down
33 changes: 32 additions & 1 deletion __tests__/integration/query-typings.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { fql, Page, QueryCheckError } from "../../src";
import { fql, Page, QueryCheckError, QueryValueObject } from "../../src";
import { getClient } from "../client";

// added in a junk property that is not part of QueryValue
type MyType = { x: number; t: QueryCheckError };

interface IMyTYpe extends QueryValueObject {
x: number;
t: QueryCheckError;
}

const client = getClient();

afterAll(() => {
Expand Down Expand Up @@ -41,6 +46,32 @@ describe.each`
}
});

it("allows customers to use their own interfaces in queries", async () => {
const query = fql`{ "x": 123 }`;
const paginatedQuery = fql`[{ "x": 123}].toSet()`;

if ("query" === method) {
const result = (await client.query<IMyTYpe>(query)).data;
expect(result).toEqual({ x: 123 });
} else {
expect.assertions(2);
for await (const page of client.paginate<IMyTYpe>(paginatedQuery)) {
for (const result of page) {
expect(result).toEqual({ x: 123 });
}
}

// It is also allowed to provide a query that does not return a page.
// When this happenes, the driver treats the result as if a page with
// exactly one item is returned.
for await (const page of client.paginate<IMyTYpe>(query)) {
for (const result of page) {
expect(result).toEqual({ x: 123 });
}
}
}
});

it("allows customers to infer their own types in queries from fql statements", async () => {
const query = fql<MyType>`{ "x": 123 }`;
const paginatedQuery = fql<Page<MyType>>`[{ "x": 123}].toSet()`;
Expand Down
4 changes: 2 additions & 2 deletions src/wire-protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,9 @@ export interface Span {
* QueryValue.
* These objects can be returned in {@link QuerySuccess}.
*/
export type QueryValueObject = {
export interface QueryValueObject {
[key: string]: QueryValue;
};
}

/**
* A QueryValue represents the possible return values in a {@link QuerySuccess}.
Expand Down

0 comments on commit 3de4b6d

Please sign in to comment.