ardatan / ardatan/graphql-tools
directive on FIELD_DEFINITION doesn't get called when subscribe
- 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
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