Skip to content

Commit

Permalink
Remove actions argument to hooks (#3171)
Browse files Browse the repository at this point in the history
  • Loading branch information
timleslie committed Jul 2, 2020
1 parent e6117d2 commit 5fc97cb
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 240 deletions.
38 changes: 38 additions & 0 deletions .changeset/nice-bags-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
'@keystonejs/fields': major
'@keystonejs/keystone': major
'@keystonejs/api-tests': patch
'@keystonejs/demo-custom-fields': patch
---

Hooks no longer recieve a `{ query }` argument. This functionality has been superseded by `context.executeGraphQL()`.

```
{
...
hooks: {
resolveInput: async ({ actions: { query } } ) => {
...
const { data, errors } = await query(`{ ... }`);
...
}
}
}
```

should be changed to

```
{
...
hooks: {
resolveInput: async ({ context } ) => {
...
const { data, errors } = await context.executeGraphQL({ query: `{ ... }` });
...
}
}
}
```

See [the docs](/docs/discussions/server-side-graphql.md) for more details on how to use `context.executeGraphQL()`.
2 changes: 0 additions & 2 deletions api-tests/default-value/defaults.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ describe('defaultValue field config', () => {
expect.objectContaining({
context: expect.any(Object),
originalInput: expect.any(Object),
actions: expect.any(Object),
})
);
})
Expand Down Expand Up @@ -172,7 +171,6 @@ describe('defaultValue field config', () => {
originalInput: {
salutation: 'Doctor',
},
actions: expect.any(Object),
})
);
expect(data.createUser).toMatchObject({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ class MultiCheck extends Text.implementation {
];
}

getDefaultValue({ context, originalInput, actions }) {
getDefaultValue({ context, originalInput }) {
let result;
if (typeof this.defaultValue !== 'undefined') {
if (typeof this.defaultValue === 'function') {
result = this.defaultValue({ context, originalInput, actions });
result = this.defaultValue({ context, originalInput });
} else {
result = this.defaultValue;
}
Expand Down
61 changes: 3 additions & 58 deletions docs/api/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ The result is passed to [the next function in the execution order](/docs/guides/
| `originalInput` | `Object` | The data received by the GraphQL mutation |
| `resolvedData` | `Object` | The data received by the GraphQL mutation plus defaults values |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |

#### Usage

Expand All @@ -146,7 +145,6 @@ const resolveInput = ({
originalInput,
resolvedData,
context,
actions,
}) => {
// Input resolution logic. Object returned is used in place of `resolvedData`.
return resolvedData;
Expand All @@ -172,7 +170,6 @@ Return values are ignored.
| `originalInput` | `Object` | The data received by the GraphQL mutation |
| `resolvedData` | `Object` | The data received by the GraphQL mutation plus defaults values |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |
| `addFieldValidationError` | `Function` | Used to set a field validation error; accepts a `String` |

#### Usage
Expand All @@ -186,7 +183,6 @@ const validateInput = ({
originalInput,
resolvedData,
context,
actions,
addFieldValidationError,
}) => {
// Throw error objects or register validation errors with addFieldValidationError(<String>)
Expand All @@ -213,7 +209,6 @@ Return values are ignored.
| `originalInput` | `Object` | The data received by the GraphQL mutation |
| `resolvedData` | `Object` | The data received by the GraphQL mutation plus defaults values |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |

#### Usage

Expand All @@ -226,7 +221,6 @@ const beforeChange = ({
originalInput,
resolvedData,
context,
actions,
}) => {
// Perform side effects
// Return values ignored
Expand Down Expand Up @@ -256,7 +250,6 @@ Return values are ignored.
| `originalInput` | `Object` | The data received by the GraphQL mutation |
| `updatedItem` | `Object` | The new/currently stored item |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |

#### Usage

Expand All @@ -269,7 +262,6 @@ const afterChange = ({
originalInput,
updatedItem,
context,
actions,
}) => {
// Perform side effects
// Return values ignored
Expand All @@ -292,7 +284,6 @@ Should throw or register errors with `addFieldValidationError(<String>)` if the
| `operation` | `String` | The operation being performed (`delete` in this case) |
| `existingItem` | `Object` | The current stored item |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |
| `addFieldValidationError` | `Function` | Used to set a field validation error; accepts a `String` |

#### Usage
Expand All @@ -304,7 +295,6 @@ const validateDelete = ({
operation,
existingItem,
context,
actions,
addFieldValidationError,
}) => {
// Throw error objects or register validation errors with addFieldValidationError(<String>)
Expand All @@ -329,7 +319,6 @@ Return values are ignored.
| `operation` | `String` | The operation being performed (`delete` in this case) |
| `existingItem` | `Object` | The current stored item |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |

#### Usage

Expand All @@ -340,7 +329,6 @@ const beforeDelete = ({
operation,
existingItem,
context,
actions,
}) => {
// Perform side effects
// Return values ignored
Expand All @@ -366,7 +354,6 @@ Return values are ignored.
| `operation` | `String` | The operation being performed (`delete` in this case) |
| `existingItem` | `Object` | The previously stored item, now deleted |
| `context` | `Apollo Context` | The [Apollo `context` object](https://www.apollographql.com/docs/apollo-server/data/data/#context-argument) for this request |
| `actions` | `Object` | Contains a `query` functions that queries the list within the current operations context, see [Query Helper](#query-helper) |

#### Usage

Expand All @@ -377,55 +364,13 @@ const afterDelete = ({
operation,
existingItem,
context,
actions,
}) => {
// Perform side effects
// Return values ignored
};
```

## The `actions` argument
### Running GraphQL Queries From Hook

All hooks receive an `actions` object as an argument.

It contains helper functionality for accessing the GraphQL schema, optionally _within_ the context of the current request.
When used, this context reuse causes access control to be applied as though the caller themselves initiated an operation.
It can therefore be useful for performing additional operations on behalf of the caller.

The `actions` object currently contains a single function: `query`.

### Query helper

Perform a GraphQL query, optionally _within_ the context of the current request.
It returns a `Promise<Object>` containing the standard GraphQL `errors` and `data` properties.

#### Argument

| Argument | Type | Description |
| :-------------------------- | :-------- | :----------------------------------------------------------------------------------------------------------------------------------- |
| `queryString` | `String` | A graphQL query string |
| `options` | `Object` | Config for the query |
| `options.skipAccessControl` | `Boolean` | By default access control _of the user making the initial request_ is still tested. Pass as `true` to disable access control checks. |
| `options.variables` | `Object` | The variables passed to the graphql query for the given queryString |

#### Usage

```js
const myHook = ({
actions: { query },
}) => {
const queryString = `
query {
# GraphQL query here...
}
`;
const options = {
skipAccessControl: false,
variables: { /* GraphQL variables here.. */ },
};
const { errors, data } = await query(queryString, options);

// Check for errors
// Do something with data
};
```
If you need to execute a GraphQL query from within your hook function you can use `context.executeGraphQL()`.
See the docs on [server-side graphql operations](/docs/discussions/server-side-graphql.md) for more details.
2 changes: 1 addition & 1 deletion packages/fields/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ keystone.createList('Post', {
fields: {
title: {
type: Text,
defaultValue: ({ context, originalInput, actions }) => {
defaultValue: ({ context, originalInput }) => {
/**/
},
},
Expand Down
7 changes: 2 additions & 5 deletions packages/fields/src/Implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,6 @@ class Field {
* request
* @param {Object} data.originalInput The raw incoming item from the mutation
* (no relationships or defaults resolved)
* @param {Object} data.actions
* @param {Function} data.actions.query Perform a graphQl query
* programmatically
*/
async resolveInput({ resolvedData }) {
return resolvedData[this.path];
Expand Down Expand Up @@ -201,10 +198,10 @@ class Field {
extendAdminViews(views) {
return views;
}
getDefaultValue({ context, originalInput, actions }) {
getDefaultValue({ context, originalInput }) {
if (typeof this.defaultValue !== 'undefined') {
if (typeof this.defaultValue === 'function') {
return this.defaultValue({ context, originalInput, actions });
return this.defaultValue({ context, originalInput });
} else {
return this.defaultValue;
}
Expand Down
5 changes: 2 additions & 3 deletions packages/fields/tests/Implementation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,12 @@ describe('getDefaultValue()', () => {
const defaultValue = jest.fn(() => 'foobar');
const context = {};
const originalInput = {};
const actions = {};

const impl = new Field('path', { defaultValue }, args);

const value = impl.getDefaultValue({ context, originalInput, actions });
const value = impl.getDefaultValue({ context, originalInput });
expect(value).toEqual('foobar');
expect(defaultValue).toHaveBeenCalledTimes(1);
expect(defaultValue).toHaveBeenCalledWith({ context, originalInput, actions });
expect(defaultValue).toHaveBeenCalledWith({ context, originalInput });
});
});
1 change: 0 additions & 1 deletion packages/keystone/lib/Keystone/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ module.exports = class Keystone {
composePlugins(config.plugins || [])(config, { listKey: key, keystone: this }),
{
getListByKey,
queryHelper: this._buildQueryHelper.bind(this),
adapter: adapters[adapterName],
defaultAccess: this.defaultAccess,
registerType: type => this.registeredTypes.add(type),
Expand Down
Loading

0 comments on commit 5fc97cb

Please sign in to comment.