Skip to content

Commit

Permalink
Fix mutation list operations not working when passing @with directi…
Browse files Browse the repository at this point in the history
…ve (#1289)
  • Loading branch information
SeppahBaws committed Mar 21, 2024
1 parent 21fca39 commit 6820d36
Show file tree
Hide file tree
Showing 8 changed files with 572 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-cobras-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini': patch
---

Mutation list operations now work if you need to pass a `@with` directive to the fragment spread
1 change: 1 addition & 0 deletions e2e/kit/src/lib/utils/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const routes = {

Lists_all: '/lists/all?limit=15',
Lists_fragment: '/lists/fragment',
Lists_mutation_insert: '/lists/mutation-insert',
blocking: '/blocking',

Stores_SSR: '/stores/ssr',
Expand Down
11 changes: 11 additions & 0 deletions e2e/kit/src/routes/lists/mutation-insert/+page.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
query UsersListMutationInsertUsers($someParam: Boolean!) {
usersConnection(first: 5, snapshot: "users-list-mutation-insert") @list(name: "MyList") {
edges {
node {
id
name
testField(someParam: $someParam)
}
}
}
}
38 changes: 38 additions & 0 deletions e2e/kit/src/routes/lists/mutation-insert/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script lang="ts">
import { graphql } from '$houdini';
import type { PageData } from './$houdini';
export let data: PageData;
$: ({ UsersListMutationInsertUsers } = data);
const addUserMutation = graphql(`
mutation UsersListMutationInsertAddUser($name: String!) {
addUser(
name: $name
birthDate: "2024-01-01T00:00:00Z"
snapshot: "users-list-mutation-insert"
) {
id
...MyList_insert @with(someParam: true) @prepend
}
}
`);
const addUser = async () => {
addUserMutation.mutate({
name: 'Test User'
});
};
</script>

<button id="addusers" on:click={addUser}>+ Add</button>

<div id="result">
{#if $UsersListMutationInsertUsers.data}
<ul>
{#each $UsersListMutationInsertUsers.data.usersConnection.edges as userEdge}
<li>{userEdge.node?.name} - {userEdge.node?.testField}</li>
{/each}
</ul>
{/if}
</div>
7 changes: 7 additions & 0 deletions e2e/kit/src/routes/lists/mutation-insert/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { UsersListMutationInsertUsersVariables } from './$houdini';

export const _UsersListMutationInsertUsersVariables: UsersListMutationInsertUsersVariables = () => {
return {
someParam: true
};
};
22 changes: 22 additions & 0 deletions e2e/kit/src/routes/lists/mutation-insert/spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { test } from '@playwright/test';
import { routes } from '../../../lib/utils/routes.js';
import { expect_to_be, goto, locator_click } from '../../../lib/utils/testsHelper.js';

test('mutation list insert with @with directive', async ({ page }) => {
await goto(page, routes.Lists_mutation_insert);

// Verify the initial page data
await expect_to_be(
page,
'Bruce Willis - Hello worldSamuel Jackson - Hello worldMorgan Freeman - Hello worldTom Hanks - Hello worldWill Smith - Hello world'
);

// Add a user
await locator_click(page, `button[id="addusers"]`);

// Verify new user is at the top
await expect_to_be(
page,
'Test User - Hello worldBruce Willis - Hello worldSamuel Jackson - Hello worldMorgan Freeman - Hello worldTom Hanks - Hello worldWill Smith - Hello world'
);
});
17 changes: 14 additions & 3 deletions packages/houdini/src/codegen/generators/artifacts/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,19 @@ export function operationsByPath(
// inside of the mutation could contain operations
graphql.visit(definition, {
FragmentSpread(node, _, __, ___, ancestors) {
// at this point, the fragment spread can contain the hashed parameters from an `@with` directive in it.
// if this fragment spread has a `@with` directive, strip the last `_asdf` from the name and check if that is a list fragment
let nameWithoutHash = node.name.value

if (
node.directives &&
node.directives.find((directive) => directive.name.value === 'with')
) {
nameWithoutHash = nameWithoutHash.substring(0, nameWithoutHash.lastIndexOf('_'))
}

// if the fragment is not a list operation, we don't care about it now
if (!config.isListFragment(node.name.value)) {
if (!config.isListFragment(nameWithoutHash)) {
return
}

Expand All @@ -44,8 +55,8 @@ export function operationsByPath(
operationObject({
config,
filepath,
listName: config.listNameFromFragment(node.name.value),
operationKind: config.listOperationFromFragment(node.name.value),
listName: config.listNameFromFragment(nameWithoutHash),
operationKind: config.listOperationFromFragment(nameWithoutHash),
type: parentTypeFromAncestors(config.schema, filepath, ancestors).name,
selection: node,
})
Expand Down

0 comments on commit 6820d36

Please sign in to comment.