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(graphql_analyze): useNamedOperation #4337

Merged

Conversation

vohoanglong0107
Copy link
Contributor

Summary

Disallow operations without name, since GraphQL clients usually use operations' name to cache.

Test Plan

Added new tests to verify this rule's behavior

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter A-Diagnostic Area: diagnostocis labels Oct 19, 2024
Copy link

codspeed-hq bot commented Oct 19, 2024

CodSpeed Performance Report

Merging #4337 will not alter performance

Comparing vohoanglong0107:graphql-no-anonymous-operations (535aa9d) with main (d02e3c1)

Summary

✅ 101 untouched benchmarks

@vohoanglong0107 vohoanglong0107 marked this pull request as ready for review October 19, 2024 10:29
@vohoanglong0107 vohoanglong0107 requested a review from a team October 19, 2024 10:29
@ematipico ematipico requested a review from a team October 19, 2024 14:30
let mut mutation = ctx.root().begin();
let node = ctx.query().clone();
let new_name = make::graphql_name_binding(make::ident(&state.suggested_name));
let new_node = node.clone().detach().with_name(Some(new_name));
Copy link
Member

Choose a reason for hiding this comment

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

Do you need detach here?

Comment on lines 71 to 76
markup! {
"Anonymous GraphQL operations are forbidden. Make sure to name your " {state.operation_type}"!"
},
)
.note(markup! {
"Rename this "{state.operation_type}" to "{state.suggested_name}"."
Copy link
Member

Choose a reason for hiding this comment

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

Let's follow our rule pillars https://biomejs.dev/linter/#rule-pillars

This means that the .note must become a message that explains the error. The core action is the solution for fixing the error.

} else {
Some(NoAnonymousOperationsState {
operation_type: operation_type.clone(),
suggested_name: get_suggested_name(node, operation_type),
Copy link
Member

Choose a reason for hiding this comment

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

We should allocate strings only when needed. Here, we should do it in the action function


fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
let node = ctx.query();
let operation_type = node.ty().ok()?.text();
Copy link
Member

Choose a reason for hiding this comment

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

Don't use text because it allocates a string, which isn't needed. Instead, use syntax().text_trimmed()

}

fn get_suggested_name(operation: &GraphqlOperationDefinition, operation_type: String) -> String {
let suggested_name = get_suggested_name_base_on_content(operation).unwrap_or(operation_type);
Copy link
Member

Choose a reason for hiding this comment

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

I don't see the need for two separate functions, because they are used once. Let's put everything in one single function

use crate::GraphqlRuleAction;

declare_lint_rule! {
/// Require specifying name for GraphQL operations.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Require specifying name for GraphQL operations.
/// Enforce specifying the name of GraphQL operations.

declare_lint_rule! {
/// Require specifying name for GraphQL operations.
///
/// This is useful since most GraphQL client libraries are using the operation name for caching purposes.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// This is useful since most GraphQL client libraries are using the operation name for caching purposes.
/// This is useful because most GraphQL client libraries use the operation name for caching purposes.

///
pub NoAnonymousOperations {
version: "next",
name: "noAnonymousOperations",
Copy link
Member

Choose a reason for hiding this comment

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

I read the documentation, and it seems the rule is more focused on the name of the operations. It doesn't say anything about operations that don't have a name.

Wouldn't it make more sense to call the rule useNamedOperation? Plus, let's use the singular

rule_category!(),
node.range(),
markup! {
"Anonymous GraphQL operations are forbidden. Make sure to name your " {operation_type.text()}"!"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"Anonymous GraphQL operations are forbidden. Make sure to name your " {operation_type.text()}"!"
"Anonymous GraphQL operations are forbidden. Make sure to name your " {operation_type.text()}"."

},
)
.note(markup! {
"Most GraphQL client libraries use operation name for caching purposes."
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"Most GraphQL client libraries use operation name for caching purposes."
"Most GraphQL client libraries use the operation name for caching purposes."

Some(
RuleDiagnostic::new(
rule_category!(),
node.range(),
Copy link
Member

Choose a reason for hiding this comment

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

I think highlighting the whole query can be too much. You used very small examples, but if you enable the rule in a big project, the whole thing is going to be red, which isn't ideal for the users. What do you think if we highlight the operation instead?

@vohoanglong0107 vohoanglong0107 changed the title feat(graphql_analyze): noAnonymousOperations feat(graphql_analyze): noUnamedOperation Oct 27, 2024
@vohoanglong0107 vohoanglong0107 changed the title feat(graphql_analyze): noUnamedOperation feat(graphql_analyze): useNamedOperation Oct 27, 2024
Disallow operations without name, since GraphQL clients usually use
operations' name to cache.
@vohoanglong0107
Copy link
Contributor Author

Oops, my bad, didn't mean to re-request a review from you there 😅

@vohoanglong0107 vohoanglong0107 merged commit 0fa6b2a into biomejs:main Oct 27, 2024
12 checks passed
@vohoanglong0107 vohoanglong0107 deleted the graphql-no-anonymous-operations branch October 27, 2024 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants