-
Notifications
You must be signed in to change notification settings - Fork 2k
[#4169] UniqueInputFieldNamesRule
incorrectly identifies field names as duplicates within and/or array
#4170
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
Changes from 3 commits
9498a1d
2eb4d83
f21ba92
b1b5ca5
48dc656
3706c2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ import type { ObjMap } from '../../jsutils/ObjMap'; | |
|
||
import { GraphQLError } from '../../error/GraphQLError'; | ||
|
||
import type { NameNode } from '../../language/ast'; | ||
import type { NameNode, ObjectFieldNode } from '../../language/ast'; | ||
import type { ASTVisitor } from '../../language/visitor'; | ||
|
||
import type { ASTValidationContext } from '../ValidationContext'; | ||
|
@@ -22,6 +22,9 @@ export function UniqueInputFieldNamesRule( | |
const knownNameStack: Array<ObjMap<NameNode>> = []; | ||
let knownNames: ObjMap<NameNode> = Object.create(null); | ||
|
||
let knownNamesInList: Array<ReadonlyArray<ObjectFieldNode>> = | ||
Object.create([]); | ||
|
||
return { | ||
ObjectValue: { | ||
enter() { | ||
|
@@ -34,18 +37,54 @@ export function UniqueInputFieldNamesRule( | |
knownNames = prevKnownNames; | ||
}, | ||
}, | ||
ListValue: { | ||
enter(node) { | ||
node.values.forEach((valueNode) => { | ||
if(valueNode.kind === 'ObjectValue') { | ||
knownNamesInList.push(valueNode.fields); | ||
} | ||
}); | ||
}, | ||
leave() { | ||
knownNamesInList = Object.create([]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would also need to use a stack else it would make list --> object --> field --> list lose track of the outer object when it bubbles back up There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me address the case of this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve changed the approach to use a stack to hold |
||
}, | ||
}, | ||
ObjectField(node) { | ||
const fieldName = node.name.value; | ||
|
||
let isError = false; | ||
if (knownNames[fieldName]) { | ||
if (!knownNamesInList.length) { | ||
isError = true; | ||
} | ||
else { | ||
for (const fields of knownNamesInList) { | ||
const nestedFields = fields.filter( | ||
(field) => field.name.value === fieldName, | ||
); | ||
|
||
// expecting only one field with the same name, if there is more than one, report error. if there is no field with the same name, mean it is in the nested object instead list value, report error. | ||
if (!isError && nestedFields.length !== 1) { | ||
isError = true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
if(isError) { | ||
context.reportError( | ||
new GraphQLError( | ||
`There can be only one input field named "${fieldName}".`, | ||
{ nodes: [knownNames[fieldName], node.name] }, | ||
), | ||
); | ||
} else { | ||
} | ||
else { | ||
knownNames[fieldName] = node.name; | ||
} | ||
}, | ||
|
||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was checking your tests and all of these also pass in current 16.x.x so I don't think this shows any issue in the current shape
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yeah, you're right. Sorry, I misread the format; the issue was with the {} inside the single big object (labeled in blue).

something like
[{Id: {}, Id: {}}]
our tests cases was
[{Id: {}}, {Id: {}}]
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but
Correctly reports it as an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, based on that, I think the issue is with Salesforce rather than the current validation rule. Thank you for your response, thank you for spending time to help me validation again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, happy to help, if anything pops up feel free to reach out/create an issue so we can get to the bottom of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the error query from Salesforce docuemtn https://developer.salesforce.com/docs/platform/graphql/guide/filter-joins.html#multiple-semi-joins-or-anti-joins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, I'll the close PR right now. @JoviDeCroock