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

feat: support repeatable directive #53

Merged
merged 5 commits into from
Dec 3, 2021
Merged

Conversation

gdorsi
Copy link

@gdorsi gdorsi commented Dec 1, 2021

fixes #50

lib/auth.js Outdated
const authDirective = astNode.directives.filter(directive => directive.name.value === this[kAuthDirective])
if (authDirective.length === 1) {
return authDirective[0]
} else if (authDirective.length > 1) {
Copy link
Author

Choose a reason for hiding this comment

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

In order to avoid to introduce breaking changes I've returned an array only when the directive ie repeted.

I could make this check more smart and return an Array when a directory is repeatable.
This way the getPolicy result would be become more predictable I think.

WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

I looked a bit and the getPolicy function is used internally, so there should not be any API breaking

auth/index.js

Line 16 in 4fc2b1b

const authSchema = auth.getPolicy(app.graphql.schema)

I think we should test this case: the user adds the directive multiple times but it is not a repeatable one. I would expect this case will be already manage by mercurius-core and this module will not have to deal with this case, but it worth testing it

Copy link
Author

Choose a reason for hiding this comment

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

Since there are no breaking changes i will also make this function return Array | null so everythink would become simpler.

When a non repeatable directive is added multiple times the graphql/validation library throws The directive "@counter" can only be used once at this location.

Do you think i should add a unit test for this?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is worth it.

Note that the CI is failing due to the .? syntax

Copy link
Author

Choose a reason for hiding this comment

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

Added the new test case and fixed the test for Node 12

lib/auth.js Outdated
const authDirective = astNode.directives.filter(directive => directive.name.value === this[kAuthDirective])
if (authDirective.length === 1) {
return authDirective[0]
} else if (authDirective.length > 1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I looked a bit and the getPolicy function is used internally, so there should not be any API breaking

auth/index.js

Line 16 in 4fc2b1b

const authSchema = auth.getPolicy(app.graphql.schema)

I think we should test this case: the user adds the directive multiple times but it is not a repeatable one. I would expect this case will be already manage by mercurius-core and this module will not have to deal with this case, but it worth testing it

promises.push(policyFunction(item, null, null, context, info))
}

for (const result of await Promise.all(promises)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would execute the policies serially.

From the standard:

The order in which directives appear may be significant, including repeatable directives.

https://github.com/graphql/graphql-spec/blame/main/spec/Section%203%20--%20Type%20System.md#L1971-L1972

Copy link
Author

Choose a reason for hiding this comment

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

done

@@ -9,11 +9,12 @@ const mercuriusAuth = require('..')
const schema = `
directive @auth on OBJECT | FIELD_DEFINITION
directive @hasRole (role: String!) on OBJECT | FIELD_DEFINITION
directive @hasPermission (grant: String!) on OBJECT | FIELD_DEFINITION
directive @hasPermission (grant: String!) repeatable on OBJECT | FIELD_DEFINITION
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this option needs a test in the gateway feature too

Copy link
Author

Choose a reason for hiding this comment

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

I've added a couple of tests cases for this

if (canShowDirectiveField instanceof Error || !canShowDirectiveField) {
canShowDirectiveField = false

if (Array.isArray(fieldPolicy)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This check should be done here too

https://github.com/mercurius-js/auth/blob/main/lib/auth.js#L113

It uses the policy structure to add the logic.

To spot this issue, you need to add a simple usage test of the repeatable directive that hit a real query a not the introspection one

Copy link
Author

Choose a reason for hiding this comment

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

I've fixed the method and added some extra test cases. Thanks for pointing me in the right direction.

Copy link
Contributor

@Eomm Eomm left a comment

Choose a reason for hiding this comment

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

I'm not a mercurius member, just approving to help the Mercurius team 😄

Copy link
Contributor

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

lgtm

@mcollina mcollina requested a review from jonnydgreen December 3, 2021 08:24
@mcollina
Copy link
Contributor

mcollina commented Dec 3, 2021

@jonnydgreen could you take a look?

Copy link
Collaborator

@jonnydgreen jonnydgreen left a comment

Choose a reason for hiding this comment

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

LGTM - really nice work!

@jonnydgreen
Copy link
Collaborator

@mcollina did you wanna do the release or shall I?

@mcollina
Copy link
Contributor

mcollina commented Dec 3, 2021

go for it!

@jonnydgreen jonnydgreen merged commit b385a02 into mercurius-js:main Dec 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support repeatable directive
4 participants