Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename fieldPath to fieldKey in hook arguments #6455

Merged
merged 2 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nine-hounds-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-next/keystone': major
---

The `fieldPath` argument to field hooks has been renamed to `fieldKey`. This makes the naming consistent with the Access Control APIs.
2 changes: 1 addition & 1 deletion docs/pages/docs/apis/fields.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ A `relationship` field represents a relationship between two lists.

Read our [relationships guide](../guides/relationships) for details on Keystone’s relationship model and how to configure them in your project.

- `ref` (required): A string of the form `<listKey>` or `<listKey>.<fieldPath>`.
- `ref` (required): A string of the form `<listKey>` or `<listKey>.<fieldKey>`.
- `many` (default: `false`): Configures the cardinality of the relationship.
- `defaultValue` (default: `undefined`): Can be either a relationship input value `{ connect: { id: ID } }` or an async function which takes an argument `({ context, originalInput })` and returns a relationship input value.
This value will be used for the field when creating items if no explicit value is set.
Expand Down
28 changes: 14 additions & 14 deletions docs/pages/docs/apis/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The result of `resolveInput` will be passed as `resolvedData` into the next stag
| Argument | Description |
| :-------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'create'` or `'update'`). |
| `originalInput` | The value of `data` passed into the mutation. |
| `existingItem` | The currently stored item (`undefined` for `create` operations). This object is an unresolved list item. [list item API](./list-items) for more details on unresolved list items. |
Expand Down Expand Up @@ -104,7 +104,7 @@ export default config({
hooks: {
resolveInput: async ({
listKey,
fieldPath,
fieldKey,
operation,
originalInput,
existingItem,
Expand Down Expand Up @@ -134,7 +134,7 @@ These error messages will be returned as a `ValidationFailureError` from the Gra
| Argument | Description |
| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'create'` or `'update'`). |
| `originalInput` | The value of `data` passed into the mutation. |
| `existingItem` | The current value of the item being updated (`undefined` for `create` operations). This object is an unresolved list item. See the [list item API](./list-items) for more details on unresolved list items. |
Expand Down Expand Up @@ -165,7 +165,7 @@ export default config({
hooks: {
validateInput: async ({
listKey,
fieldPath,
fieldKey,
operation,
originalInput,
existingItem,
Expand All @@ -190,7 +190,7 @@ It is invoked after all `validateInput` hooks have been run, but before the data
| Argument | Description |
| :-------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'create'` or `'update'`). |
| `originalInput` | The value of `data` passed into the mutation. |
| `existingItem` | The current value of the item being updated (`undefined` for `create` operations). This object is an unresolved list item. See the [list item API](./list-items) for more details on unresolved list items. |
Expand Down Expand Up @@ -219,7 +219,7 @@ export default config({
hooks: {
beforeChange: async ({
listKey,
fieldPath,
fieldKey,
operation,
originalInput,
existingItem,
Expand All @@ -241,7 +241,7 @@ The `afterChange` function is used to perform side effects after the data for a
| Argument | Description |
| :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'create'` or `'update'`). |
| `originalInput` | The value of `data` passed into the mutation. |
| `existingItem` | The previous value of the item being updated (`undefined` for `create` operations). This object is an unresolved list item. See the [list item API](./list-items) for more details on unresolved list items. |
Expand Down Expand Up @@ -270,7 +270,7 @@ export default config({
hooks: {
afterChange: async ({
listKey,
fieldPath,
fieldKey,
operation,
originalInput,
existingItem,
Expand Down Expand Up @@ -302,7 +302,7 @@ These error messages will be returned as a `ValidationFailureError` from the Gra
| Argument | Description |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'delete'`). |
| `existingItem` | The value of the item to be deleted. This object is an unresolved list item. See the [list item API](./list-items) for more details on unresolved list items. |
| `context` | The [`KeystoneContext`](./context) object of the originating GraphQL operation. |
Expand All @@ -329,7 +329,7 @@ export default config({
hooks: {
validateDelete: async ({
listKey,
fieldPath,
fieldKey,
operation,
existingItem,
context,
Expand All @@ -352,7 +352,7 @@ It is invoked after all `validateDelete` hooks have been run.
| Argument | Description |
| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'delete'`). |
| `existingItem` | The value of the item to be deleted. This object is an unresolved list item. See the [list item API](./list-items) for more details on unresolved list items. |
| `context` | The [`KeystoneContext`](./context) object of the originating GraphQL operation. |
Expand All @@ -372,7 +372,7 @@ export default config({
fields: {
fieldName: text({
hooks: {
beforeDelete: async ({ listKey, fieldPath, operation, existingItem, context }) => {
beforeDelete: async ({ listKey, fieldKey, operation, existingItem, context }) => {
/* ... */
},
},
Expand All @@ -390,7 +390,7 @@ The `afterDelete` function is used to perform side effects after the data for a
| Argument | Description |
| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listKey` | The key of the list being operated on. |
| `fieldPath` | The path of the field being operated on (field hooks only). |
| `fieldKey` | The key of the field being operated on (field hooks only). |
| `operation` | The operation being performed (`'delete'`). |
| `existingItem` | The value of the item, now deleted. This object is an unresolved list item. See the [list item API](./list-items) for more details on unresolved list items. |
| `context` | The [`KeystoneContext`](./context) object of the originating GraphQL operation. |
Expand All @@ -410,7 +410,7 @@ export default config({
fields: {
fieldName: text({
hooks: {
afterDelete: async ({ listKey, fieldPath, operation, existingItem, context }) => {
afterDelete: async ({ listKey, fieldKey, operation, existingItem, context }) => {
/* ... */
},
},
Expand Down
8 changes: 4 additions & 4 deletions docs/pages/docs/guides/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Similary, the `beforeDelete` and `afterDelete` hooks can be used to trigger side

All of the examples above have involved hooks associated with a particular list.
Keystone also supports setting of hooks associated with a particular field.
All the same hooks are available, and they receive all the same arguments, along with an extra `fieldPath` argument.
All the same hooks are available, and they receive all the same arguments, along with an extra `fieldKey` argument.

Field hooks can be useful if you want to have field specific rules.
For example, you might have an email validation function which want to use in your system.
Expand All @@ -208,10 +208,10 @@ export default config({
name: text(),
email: text({
hooks: {
validateInput: ({ addValidationError, resolvedData, fieldPath }) => {
const email = resolvedData[fieldPath];
validateInput: ({ addValidationError, resolvedData, fieldKey }) => {
const email = resolvedData[fieldKey];
if (email !== undefined && email !== null && !email.includes('@')) {
addValidationError(`The email address ${email} provided for the field ${fieldPath} must contain an '@' character`);
addValidationError(`The email address ${email} provided for the field ${fieldKey} must contain an '@' character`);
}
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Edit the `next.config.js` file in your project root with the following:
- module.exports = {
- reactStrictMode: true,
- }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are the result of a yarn format on the full code base. Might as well land in this PR 🤷‍♂️

+ const { withKeystone } = require("@keystone-next/keystone/next");

+ module.exports = withKeystone({
Expand Down
10 changes: 5 additions & 5 deletions packages/keystone/src/lib/core/mutations/create-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,18 +244,18 @@ async function getResolvedData(
// Field hooks
let _resolvedData: Record<string, any> = {};
const fieldsErrors: { error: Error; tag: string }[] = [];
for (const [fieldPath, field] of Object.entries(list.fields)) {
for (const [fieldKey, field] of Object.entries(list.fields)) {
if (field.hooks.resolveInput === undefined) {
_resolvedData[fieldPath] = resolvedData[fieldPath];
_resolvedData[fieldKey] = resolvedData[fieldKey];
} else {
try {
_resolvedData[fieldPath] = await field.hooks.resolveInput({
_resolvedData[fieldKey] = await field.hooks.resolveInput({
...hookArgs,
resolvedData,
fieldPath,
fieldKey,
});
} catch (error: any) {
fieldsErrors.push({ error, tag: `${list.listKey}.${fieldPath}` });
fieldsErrors.push({ error, tag: `${list.listKey}.${fieldKey}` });
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions packages/keystone/src/lib/core/mutations/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function runSideEffectOnlyHook<
string,
{
hooks: {
[Key in HookName]?: (args: { fieldPath: string } & Args) => Promise<void> | void;
[Key in HookName]?: (args: { fieldKey: string } & Args) => Promise<void> | void;
};
}
>;
Expand All @@ -32,12 +32,12 @@ export async function runSideEffectOnlyHook<

// Field hooks
const fieldsErrors: { error: Error; tag: string }[] = [];
for (const [fieldPath, field] of Object.entries(list.fields)) {
if (shouldRunFieldLevelHook(fieldPath)) {
for (const [fieldKey, field] of Object.entries(list.fields)) {
if (shouldRunFieldLevelHook(fieldKey)) {
try {
await field.hooks[hookName]?.({ fieldPath, ...args });
await field.hooks[hookName]?.({ fieldKey, ...args });
} catch (error: any) {
fieldsErrors.push({ error, tag: `${list.listKey}.${fieldPath}` });
fieldsErrors.push({ error, tag: `${list.listKey}.${fieldKey}` });
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions packages/keystone/src/lib/core/mutations/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ export async function validateUpdateCreate({
}

// Field validation hooks
for (const [fieldPath, field] of Object.entries(list.fields)) {
for (const [fieldKey, field] of Object.entries(list.fields)) {
const addValidationError = (msg: string) =>
_addValidationError(`${list.listKey}.${fieldPath}: ${msg}`);
_addValidationError(`${list.listKey}.${fieldKey}: ${msg}`);
// @ts-ignore
await field.hooks.validateInput?.({ ...hookArgs, addValidationError, fieldPath });
await field.hooks.validateInput?.({ ...hookArgs, addValidationError, fieldKey });
}

// List validation hooks
Expand All @@ -76,10 +76,10 @@ export async function validateDelete({
}) {
await validationHook(async _addValidationError => {
// Field validation
for (const [fieldPath, field] of Object.entries(list.fields)) {
for (const [fieldKey, field] of Object.entries(list.fields)) {
const addValidationError = (msg: string) =>
_addValidationError(`${list.listKey}.${fieldPath}: ${msg}`);
await field.hooks.validateDelete?.({ ...hookArgs, addValidationError, fieldPath });
_addValidationError(`${list.listKey}.${fieldKey}: ${msg}`);
await field.hooks.validateDelete?.({ ...hookArgs, addValidationError, fieldKey });
}

// List validation
Expand Down
Loading