Skip to content

Commit

Permalink
add tsdoc
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Mar 9, 2023
1 parent 2bc9b10 commit 9aa1b09
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 10 deletions.
7 changes: 7 additions & 0 deletions .changeset/stupid-cherries-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@urql/exchange-populate': minor
---

Introduce `maxDepth` and `skipType` into the `populateExchange`, these options allow you to specify
the maximum depth a mutation should be populated as well as which types should not be counted towards
this depth.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`Store with storage > should be able to persist embedded data 1`] = `
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`on error > returns error data 1`] = `
{
Expand Down
96 changes: 96 additions & 0 deletions exchanges/populate/src/populateExchange.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,24 @@ const schemaDef = `
store: OnlineStore
}
type Company {
id: String
employees: [User]
}
type Query {
todos: [Todo!]
users: [User!]!
products: [Product]!
company: Company
}
type Mutation {
addTodo: [Todo]
removeTodo: [Node]
updateTodo: [UnionType]
addProduct: Product
removeCompany: Company
}
`;

Expand Down Expand Up @@ -825,3 +832,92 @@ describe('nested fragment', () => {
`);
});
});

describe('respects max-depth', () => {
const queryOp = makeOperation(
'query',
{
key: 1234,
variables: undefined,
query: gql`
query {
company {
id
employees {
id
todos {
id
}
}
}
}
`,
},
context
);

const mutationOp = makeOperation(
'mutation',
{
key: 5678,
variables: undefined,
query: gql`
mutation MyMutation {
removeCompany @populate
}
`,
},
context
);

describe('mutation query', () => {
it('matches snapshot', async () => {
const response = pipe<Operation, any, Operation[]>(
fromArray([queryOp, mutationOp]),
populateExchange({ schema, options: { maxDepth: 1 } })(exchangeArgs),
toArray
);

expect(print(response[1].query)).toMatchInlineSnapshot(`
"mutation MyMutation {
removeCompany {
__typename
id
employees {
__typename
id
}
}
}"
`);
});

it('respects skip syntax', async () => {
const response = pipe<Operation, any, Operation[]>(
fromArray([queryOp, mutationOp]),
populateExchange({
schema,
options: { maxDepth: 1, skipType: /User/ },
})(exchangeArgs),
toArray
);

expect(print(response[1].query)).toMatchInlineSnapshot(`
"mutation MyMutation {
removeCompany {
__typename
id
employees {
__typename
id
todos {
__typename
id
}
}
}
}"
`);
});
});
});
37 changes: 34 additions & 3 deletions exchanges/populate/src/populateExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ import { Exchange, Operation, stringifyVariables } from '@urql/core';
import { getName, GraphQLFlatType, unwrapType } from './helpers/node';
import { traverse } from './helpers/traverse';

interface Options {
skipType?: RegExp;
maxDepth?: number;
}

interface PopulateExchangeOpts {
schema: IntrospectionQuery;
options?: Options;
}

const makeDict = (): any => Object.create(null);
Expand All @@ -41,10 +47,35 @@ interface FieldUsage {
type FragmentMap<T extends string = string> = Record<T, FragmentDefinitionNode>;
const SKIP_COUNT_TYPE = /^PageInfo|(Connection|Edge)$/;

/** An exchange for auto-populating mutations with a required response body. */
/** Creates an `Exchange` handing automatic mutation selection-set population based on the
* query selection-sets seen.
*
*
* @remarks
* The `populateExchange` will create an exchange that monitors queries and
* extracts fields and types so it knows what is currently observed by your
* application.
* When a mutation comes in with the `@populate` directive it will fill the
* selection-set based on these prior queries.
*
* This Exchange can ease up the transition from documentCache to graphCache
*
* @example
* ```ts
* populateExchange({ schema, options: { maxDepth: 3, skipType: /Todo/ }})
*
* const query = gql`
* mutation { addTodo @popualte }
* `
* ```
*/
export const populateExchange = ({
schema: ogSchema,
options,
}: PopulateExchangeOpts): Exchange => ({ forward }) => {
const maxDepth = (options && options.maxDepth) || 2;
const skipType = (options && options.skipType) || SKIP_COUNT_TYPE;

const schema = buildClientSchema(ogSchema);
/** List of operation keys that have already been parsed. */
const parsedOperations = new Set<number>();
Expand Down Expand Up @@ -200,15 +231,15 @@ export const populateExchange = ({
} else if (
value.type instanceof GraphQLObjectType &&
!visited.has(value.type.name) &&
depth <= 3
depth < maxDepth
) {
visited.add(value.type.name);
const fieldSelections: Array<FieldNode> = [];

populateSelections(
value.type,
fieldSelections,
SKIP_COUNT_TYPE.test(value.type.name) ? depth : depth + 1
skipType.test(value.type.name) ? depth : depth + 1
);

const args = value.args
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/__snapshots__/client.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`createClient / Client > passes snapshot 1`] = `
Client2 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`on error > returns error data 1`] = `
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`should return response data from forwardSubscription observable 1`] = `
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`on error > ignores the error when a result is available 1`] = `
{
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/utils/__snapshots__/error.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
// Vitest Snapshot v1

exports[`CombinedError > behaves like a normal Error 1`] = `"[Network] test"`;

0 comments on commit 9aa1b09

Please sign in to comment.