Skip to content

Commit abf361b

Browse files
authored
feat: add valid graphql wire adapter callback parameters rule (#144)
1 parent 930b82b commit abf361b

File tree

5 files changed

+176
-17
lines changed

5 files changed

+176
-17
lines changed

README.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,24 @@ To choose from three configuration settings, install the [`eslint-config-lwc`](h
4646

4747
### LWC
4848

49-
| Rule ID | Description | Fixable |
50-
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------- |
51-
| [lwc/consistent-component-name](./docs/rules/consistent-component-name.md) | ensure component class name matches file name | 🔧 |
52-
| [lwc/no-api-reassignments](./docs/rules/no-api-reassignments.md) | prevent public property reassignments | |
53-
| [lwc/no-deprecated](./docs/rules/no-deprecated.md) | disallow usage of deprecated LWC APIs | |
54-
| [lwc/no-document-query](./docs/rules/no-document-query.md) | disallow DOM query at the document level | |
55-
| [lwc/no-attributes-during-construction](./docs/rules/no-attributes-during-construction.md) | disallow setting attributes during construction | |
56-
| [lwc/no-disallowed-lwc-imports](./docs/rules/no-disallowed-lwc-imports.md) | disallow importing unsupported APIs from the `lwc` package | |
57-
| [lwc/no-leading-uppercase-api-name](./docs/rules/no-leading-uppercase-api-name.md) | ensure public property doesn't start with an upper-case character | |
58-
| [lwc/no-unexpected-wire-adapter-usages](./docs/rules/no-unexpected-wire-adapter-usages.md) | enforce wire adapters to be used with `wire` decorator | |
59-
| [lwc/no-unknown-wire-adapters](./docs/rules/no-unknown-wire-adapters.md) | disallow usage of unknown wire adapters | |
60-
| [lwc/valid-api](./docs/rules/valid-api.md) | validate `api` decorator usage | |
61-
| [lwc/valid-track](./docs/rules/valid-track.md) | validate `track` decorator usage | |
62-
| [lwc/valid-wire](./docs/rules/valid-wire.md) | validate `wire` decorator usage | |
63-
| [lwc/no-restricted-browser-globals-during-ssr](./docs/rules/no-restricted-browser-globals-during-ssr.md) | disallow access to global browser APIs during SSR | |
64-
| [lwc/no-unsupported-ssr-properties](./docs/rules/no-unsupported-ssr-properties.md) | disallow access of unsupported properties in SSR | |
65-
| [lwc/no-node-env-in-ssr](./docs/rules/no-node-env-in-ssr.md) | disallow usage of process.env.NODE_ENV in SSR | |
49+
| Rule ID | Description | Fixable |
50+
| -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ------- |
51+
| [lwc/consistent-component-name](./docs/rules/consistent-component-name.md) | ensure component class name matches file name | 🔧 |
52+
| [lwc/no-api-reassignments](./docs/rules/no-api-reassignments.md) | prevent public property reassignments | |
53+
| [lwc/no-deprecated](./docs/rules/no-deprecated.md) | disallow usage of deprecated LWC APIs | |
54+
| [lwc/no-document-query](./docs/rules/no-document-query.md) | disallow DOM query at the document level | |
55+
| [lwc/no-attributes-during-construction](./docs/rules/no-attributes-during-construction.md) | disallow setting attributes during construction | |
56+
| [lwc/no-disallowed-lwc-imports](./docs/rules/no-disallowed-lwc-imports.md) | disallow importing unsupported APIs from the `lwc` package | |
57+
| [lwc/no-leading-uppercase-api-name](./docs/rules/no-leading-uppercase-api-name.md) | ensure public property doesn't start with an upper-case character | |
58+
| [lwc/no-unexpected-wire-adapter-usages](./docs/rules/no-unexpected-wire-adapter-usages.md) | enforce wire adapters to be used with `wire` decorator | |
59+
| [lwc/no-unknown-wire-adapters](./docs/rules/no-unknown-wire-adapters.md) | disallow usage of unknown wire adapters | |
60+
| [lwc/valid-api](./docs/rules/valid-api.md) | validate `api` decorator usage | |
61+
| [lwc/valid-track](./docs/rules/valid-track.md) | validate `track` decorator usage | |
62+
| [lwc/valid-wire](./docs/rules/valid-wire.md) | validate `wire` decorator usage | |
63+
| [lwc/no-restricted-browser-globals-during-ssr](./docs/rules/no-restricted-browser-globals-during-ssr.md) | disallow access to global browser APIs during SSR | |
64+
| [lwc/no-unsupported-ssr-properties](./docs/rules/no-unsupported-ssr-properties.md) | disallow access of unsupported properties in SSR | |
65+
| [lwc/no-node-env-in-ssr](./docs/rules/no-node-env-in-ssr.md) | disallow usage of process.env.NODE_ENV in SSR | |
66+
| [lwc/valid-graphql-wire-adapter-callback-parameters](./docs/rules/valid-graphql-wire-adapter-callback-parameters.md) | ensure graphql wire adapters are using 'errors' instead of 'error' | |
6667

6768
### Best practices
6869

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Validate graphql wire adapter callback parameter usage (valid-graphql-wire-adapter-callback-parameters)
2+
3+
The graphql @wire adapter returns `{ data, errors }` instead of `{ data, error }`. Validate that graphql @wire customers are using `errors` not `error`.
4+
5+
## Rule details
6+
7+
Example of **incorrect** code:
8+
9+
```js
10+
import { wire } from 'lwc';
11+
import { gql, graphql } from 'lightning/uiGraphQLApi';
12+
13+
class Test {
14+
@wire(graphql, {})
15+
wiredMethod({ error, data }) {}
16+
}
17+
```
18+
19+
Example of **correct** code:
20+
21+
```js
22+
import { wire } from 'lwc';
23+
import { gql, graphql } from 'lightning/uiGraphQLApi';
24+
25+
class Test {
26+
@wire(graphql, {})
27+
wiredMethod({ errors, data }) {}
28+
}
29+
```

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const rules = {
2626
'no-unknown-wire-adapters': require('./rules/no-unknown-wire-adapters'),
2727
'prefer-custom-event': require('./rules/prefer-custom-event'),
2828
'valid-api': require('./rules/valid-api'),
29+
'valid-graphql-wire-adapter-callback-parameters': require('./rules/valid-graphql-wire-adapter-callback-parameters'),
2930
'valid-track': require('./rules/valid-track'),
3031
'valid-wire': require('./rules/valid-wire'),
3132
'no-restricted-browser-globals-during-ssr': require('./rules/no-restricted-browser-globals-during-ssr'),
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: MIT
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6+
*/
7+
'use strict';
8+
9+
const { docUrl } = require('../util/doc-url');
10+
module.exports = {
11+
meta: {
12+
docs: {
13+
description: 'validate graphql error callback parameter',
14+
category: 'LWC',
15+
recommended: true,
16+
url: docUrl('valid-graphql-error-callback-parameter'),
17+
},
18+
19+
schema: [],
20+
},
21+
22+
create(context) {
23+
return {
24+
MethodDefinition(node) {
25+
const { decorators } = node;
26+
27+
// Check that the @wire decorator is using graphql
28+
const graphQlDecorator = decorators.find((decorator) => {
29+
return decorator.expression.arguments.find((argument) => {
30+
return argument.name === 'graphql';
31+
});
32+
});
33+
34+
// Verify that the method definition is using 'errors' not 'error
35+
if (graphQlDecorator !== undefined) {
36+
if (node.value.type === 'FunctionExpression') {
37+
const objectPatternNode = node.value.params.find(
38+
(param) => param.type === 'ObjectPattern',
39+
);
40+
if (objectPatternNode !== undefined) {
41+
const incorrectErrorParameter = objectPatternNode.properties.find(
42+
(property) => {
43+
return property.value.name === 'error';
44+
},
45+
);
46+
if (incorrectErrorParameter !== undefined) {
47+
context.report({
48+
node,
49+
message:
50+
'@wire graphql callback function object must use "errors" instead of "error"',
51+
});
52+
}
53+
}
54+
}
55+
}
56+
},
57+
};
58+
},
59+
};
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: MIT
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6+
*/
7+
'use strict';
8+
9+
const { RuleTester } = require('eslint');
10+
11+
const { ESLINT_TEST_CONFIG } = require('../shared');
12+
const rule = require('../../../lib/rules/valid-graphql-wire-adapter-callback-parameters');
13+
14+
const ruleTester = new RuleTester(ESLINT_TEST_CONFIG);
15+
16+
ruleTester.run('valid-graphql-wire-adapter-callback-parameters', rule, {
17+
valid: [
18+
{
19+
code: `import { wire } from 'lwc';
20+
import getFoo from 'adapter';
21+
22+
class Test {
23+
@wire(getFoo)
24+
wiredMethod() {}
25+
}`,
26+
},
27+
{
28+
code: `import { wire } from 'lwc';
29+
import { gql, graphql } from 'lightning/uiGraphQLApi';
30+
31+
class Test {
32+
@wire(graphql, {})
33+
wiredMethod({errors, data}) {}
34+
}`,
35+
},
36+
],
37+
invalid: [
38+
{
39+
code: `import { wire } from 'lwc';
40+
import { gql, graphql } from 'lightning/uiGraphQLApi';
41+
42+
class Test {
43+
@wire(graphql, {})
44+
wiredMethod({error, data}) {}
45+
}`,
46+
errors: [
47+
{
48+
message:
49+
'@wire graphql callback function object must use "errors" instead of "error"',
50+
},
51+
],
52+
},
53+
{
54+
code: `import { wire } from 'lwc';
55+
import { gql, graphql } from 'lightning/uiGraphQLApi';
56+
57+
class Test {
58+
@wire(graphql, {})
59+
wiredMethod({error, errors, data}) {}
60+
}`,
61+
errors: [
62+
{
63+
message:
64+
'@wire graphql callback function object must use "errors" instead of "error"',
65+
},
66+
],
67+
},
68+
],
69+
});

0 commit comments

Comments
 (0)