ardatan / ardatan/graphql-tools

directive on FIELD_DEFINITION doesn't get called when subscribe

Open
#6,328 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
5.4k
Forks
830
Avg merge
10h 59m
Merged PRs (30d)
45

Description

### Issue workflow progress

_Progress of the issue based on the
[Contributor Workflow](https://github.com/the-guild-org/Stack/blob/master/CONTRIBUTING.md#a-typical-contributor-workflow)_

- [ ] 1. The issue provides a reproduction available on Github, Stackblitz or CodeSandbox
> Make sure to fork this template and run `yarn generate` in the terminal.
>
> Please make sure the GraphQL Tools package versions under `package.json` matches yours.
- [ ] 2. A failing test has been provided
- [ ] 3. A local solution has been provided
- [ ] 4. A pull request is pending review

---

**Describe the bug**

**To Reproduce** Steps to reproduce the behavior:

```gql
extend type Subscription {
authenticated: String @authenticated
}
```

```typescript
const typeDefs = `
directive @authenticated on FIELD_DEFINITION
`;

function transformer(openidConfigurationUrl: string) {
return (schema: GraphQLSchema) =>
mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: (
fieldConfig: GraphQLFieldConfig,
) => {
const options = getDirective(schema, fieldConfig, "authenticated")?.[0];
if (!options) return fieldConfig;

const { resolve = defaultFieldResolver } = fieldConfig;
fieldConfig.resolve = async (source, args, context, info) => {
console.log("@authenticated");
const idTokenPayload =
await getIdTokenPayloadFromContext(openidConfigurationUrl)(context);
if (!idTokenPayload) throw new Error401();

context.idTokenPayload = idTokenPayload;

return await resolve(source, args, context, info);
};
return fieldConfig;
},
});
}
```
```typescript
Subscription: {
authenticated: {
subscribe: async (_, __, context) => {
console.log("subscribe authenticated", context.idTokenPayload, context.connectionParams);
return (async function* () {
for (const i of [0, 1, 2]) {
yield { authenticated: "authenticated" };
}
})();
},
},
},
```

**Expected behavior**
`console.log("@authenticated");`
should be executed before
`console.log("subscribe authenticated", context.idTokenPayload, context.connectionParams);`
But
`console.log("@authenticated");`
is executed after every emitted value

**Environment:**

- OS: Windows 10
- `@graphql-tools/...`: 10.3.1
- NodeJS: 20.14.0

**Additional context**

Contributor guide

Open the contributing guide

Research direction

Reproduce the subscription behavior using the provided SDL, transformer, and Subscription resolver, then trace mapSchema with MapperKind.OBJECT_FIELD through GraphQL subscription execution. Confirm the current ordering and add a regression test showing the directive behavior before subscription callbacks; done means the expected ordering is covered by the test.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, typescript
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.