From a6578991feadc7e3c74a7c52262f63b3cfc7c3cd Mon Sep 17 00:00:00 2001 From: "haifeng.li" Date: Tue, 21 May 2024 15:48:35 -0700 Subject: [PATCH] sync the change --- CONTRIBUTING.md | 74 +++++++++++++++++++ package.json | 6 +- src/configs/base.ts | 21 +----- src/configs/recommended.ts | 22 +++++- src/index.ts | 4 +- src/rules/apex/apex-import.ts | 37 ++++++++++ src/rules/graphql/no-mutation-supported.ts | 34 ++++++++- src/util/createRule.ts | 13 ++++ src/{rules => }/utils.ts | 0 test/rules/apex/apex-import.ts | 66 +++++++++++++++++ .../graphql/no-mutation-supported.spec.ts | 23 +++++- test/rules/utils.spec.ts | 2 +- 12 files changed, 273 insertions(+), 29 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 src/rules/apex/apex-import.ts create mode 100644 src/util/createRule.ts rename src/{rules => }/utils.ts (100%) create mode 100644 test/rules/apex/apex-import.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6a76844 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,74 @@ +# Contributing Guide For @salesforce/eslint-plugin-lwc-mobile + +This page lists the operational governance model of this project, as well as the recommendations and requirements for how to best contribute to @salesforce/eslint-plugin-lwc-mobile. We strive to obey these as best as possible. As always, thanks for contributing – we hope these guidelines make it easier and shed some light on our approach and processes. + +# Governance Model + +## Salesforce Sponsored + +The intent and goal of open sourcing this project is to increase the contributor and user base. However, only Salesforce employees will be given `admin` rights and will be the final arbitrars of what contributions are accepted or not. + +# Issues, requests & ideas + +Use GitHub Issues page to submit issues, enhancement requests and discuss ideas. + +### Bug Reports and Fixes +- If you find a bug, please search for it in the [Issues](https://github.com/salesforce/eslint-plugin-lwc-mobile/issues), and if it isn't already tracked, + [create a new issue](https://github.com/salesforce/eslint-plugin-lwc-mobile/issues/new). Fill out the "Bug Report" section of the issue template. Even if an Issue is closed, feel free to comment and add details, it will still + be reviewed. +- Issues that have already been identified as a bug (note: able to reproduce) will be labelled `bug`. +- If you'd like to submit a fix for a bug, [send a Pull Request](#creating_a_pull_request) and mention the Issue number. + - Include tests that isolate the bug and verifies that it was fixed. + +### New Features +- If you'd like to add new functionality to this project, describe the problem you want to solve in a [new Issue](https://github.com/salesforce/eslint-plugin-lwc-mobile/issues/new). +- Issues that have been identified as a feature request will be labelled `enhancement`. +- If you'd like to implement the new feature, please wait for feedback from the project + maintainers before spending too much time writing the code. In some cases, `enhancement`s may + not align well with the project objectives at the time. + +### Tests, Documentation, Miscellaneous +- If you'd like to improve the tests, you want to make the documentation clearer, you have an + alternative implementation of something that may have advantages over the way its currently + done, or you have any other change, we would be happy to hear about it! + - If its a trivial change, go ahead and [send a Pull Request](#creating_a_pull_request) with the changes you have in mind. + - If not, [open an Issue](https://github.com/salesforce/eslint-plugin-lwc-mobile/issues/new) to discuss the idea first. + +If you're new to our project and looking for some way to make your first contribution, look for +Issues labelled `good first contribution`. + +# Contribution Checklist + +- [x] Clean, simple, well styled code +- [x] Commits should be atomic and messages must be descriptive. Related issues should be mentioned by Issue number. +- [x] Comments + - Module-level & function-level comments. + - Comments on complex blocks of code or algorithms (include references to sources). +- [x] Tests + - The test suite, if provided, must be complete and pass + - Increase code coverage, not versa. + - Use any of our testkits that contains a bunch of testing facilities you would need. For example: `import com.salesforce.op.test._` and borrow inspiration from existing tests. +- [x] Dependencies + - Minimize number of dependencies. + - Prefer Apache 2.0, BSD3, MIT, ISC and MPL licenses. +- [x] Reviews + - Changes must be approved via peer code review + +# Creating a Pull Request + +1. **Ensure the bug/feature was not already reported** by searching on GitHub under Issues. If none exists, create a new issue so that other contributors can keep track of what you are trying to add/fix and offer suggestions (or let you know if there is already an effort in progress). +3. **Clone** the forked repo to your machine. +4. **Create** a new branch to contain your work (e.g. `git br fix-issue-11`) +4. **Commit** changes to your own branch. +5. **Push** your work back up to your fork. (e.g. `git push fix-issue-11`) +6. **Submit** a Pull Request against the `main` branch and refer to the issue(s) you are fixing. Try not to pollute your pull request with unintended changes. Keep it simple and small. +7. **Sign** the Salesforce CLA (you will be prompted to do so when submitting the Pull Request) + +> **NOTE**: Be sure to [sync your fork](https://help.github.com/articles/syncing-a-fork/) before making a pull request. + + +# Code of Conduct +Please follow our [Code of Conduct](CODE_OF_CONDUCT.md). + +# License +By contributing your code, you agree to license your contribution under the terms of our project [LICENSE](LICENSE.txt) and to sign the [Salesforce CLA](https://cla.salesforce.com/sign-cla) \ No newline at end of file diff --git a/package.json b/package.json index da600af..e6f7334 100644 --- a/package.json +++ b/package.json @@ -58,14 +58,14 @@ "/dist" ], "dependencies": { - "@graphql-eslint/eslint-plugin": "^3.20.1", - "@types/eslint": "^8.56.10", - "@types/estree": "^1.0.5" + "@graphql-eslint/eslint-plugin": "^3.20.1" }, "devDependencies": { "@eslint/js": "^9.2.0", "@jest/globals": "^29.7.0", "@types/jest": "^29.5.12", + "@types/eslint": "^8.56.10", + "@types/estree": "^1.0.5", "@typescript-eslint/eslint-plugin": "^7.8.0", "@typescript-eslint/parser": "^7.8.0", "@typescript-eslint/rule-tester": "^7.8.0", diff --git a/src/configs/base.ts b/src/configs/base.ts index 37327d5..2ec1333 100644 --- a/src/configs/base.ts +++ b/src/configs/base.ts @@ -8,22 +8,7 @@ import type { ClassicConfig } from '@typescript-eslint/utils/ts-eslint'; export = { plugins: ['@salesforce/lwc-mobile', '@graphql-eslint'], - overrides: [ - { - files: ['*.js'], - processor: '@graphql-eslint/graphql' - }, - { - files: ['*.graphql'], - parser: '@graphql-eslint/eslint-plugin', - - parserOptions: { - skipGraphQLConfig: true - }, - rules: { - '@salesforce/lwc-mobile/mutation-not-supported': 'warn', - '@salesforce/lwc-mobile/offline-graphql-unsupported-scope': 'warn' - } - } - ] + rules: { + '@salesforce/lwc-mobile/enforce-foo-bar': 'warn' + } } satisfies ClassicConfig.Config; diff --git a/src/configs/recommended.ts b/src/configs/recommended.ts index 3eba7d7..8055ceb 100644 --- a/src/configs/recommended.ts +++ b/src/configs/recommended.ts @@ -9,6 +9,24 @@ import type { ClassicConfig } from '@typescript-eslint/utils/ts-eslint'; export = { extends: ['./configs/base'], rules: { - '@salesforce/lwc-mobile/enforce-foo-bar': 'warn' - } + '@salesforce/lwc-mobile/apex-import': 'warn' + }, + overrides: [ + { + files: ['*.js'], + processor: '@graphql-eslint/graphql' + }, + { + files: ['*.graphql'], + parser: '@graphql-eslint/eslint-plugin', + + parserOptions: { + skipGraphQLConfig: true + }, + rules: { + '@salesforce/lwc-mobile/offline-graphql-no-mutation-supported': 'warn', + '@salesforce/lwc-mobile/offline-graphql-unsupported-scope': 'warn' + } + } + ] } satisfies ClassicConfig.Config; diff --git a/src/index.ts b/src/index.ts index 05a629c..232f4ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import base from './configs/base.js'; import recommended from './configs/recommended.js'; import enforceFooBar from './rules/dummy/enforce-foo-bar.js'; +import { rule as apexImport, APEX_IMPORT_RULE_ID } from './rules/apex/apex-import.js'; import { rule as mutionNotSupported, NO_MUTATION_SUPPORTED_RULE_ID @@ -31,6 +32,7 @@ export = { rules: { 'enforce-foo-bar': enforceFooBar, [NO_MUTATION_SUPPORTED_RULE_ID]: mutionNotSupported, - [OFFLINE_GRAPHQL_UNSUPPORTED_SCOPE_RULE_ID]: offlineGraphqlUnsupportedScope + [OFFLINE_GRAPHQL_UNSUPPORTED_SCOPE_RULE_ID]: offlineGraphqlUnsupportedScope, + [APEX_IMPORT_RULE_ID]: apexImport } }; diff --git a/src/rules/apex/apex-import.ts b/src/rules/apex/apex-import.ts new file mode 100644 index 0000000..cc22b6e --- /dev/null +++ b/src/rules/apex/apex-import.ts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ + +import createRule from '../../util/createRule'; +export const APEX_IMPORT_RULE_ID = 'apex-import'; + +export const rule = createRule({ + create(context) { + return { + ImportDeclaration(node) { + if (node.source.value.startsWith('@salesforce/apex')) { + context.report({ + node, + messageId: APEX_IMPORT_RULE_ID + }); + } + } + }; + }, + name: 'apex-import', + meta: { + docs: { + description: 'Importing apex modules can have issues on mobile for offline usage.' + }, + messages: { + [APEX_IMPORT_RULE_ID]: + 'Importing apex modules can have issues on mobile for offline usage.' + }, + type: 'suggestion', + schema: [] + }, + defaultOptions: [] +}); diff --git a/src/rules/graphql/no-mutation-supported.ts b/src/rules/graphql/no-mutation-supported.ts index 186d4e4..a8b3e70 100644 --- a/src/rules/graphql/no-mutation-supported.ts +++ b/src/rules/graphql/no-mutation-supported.ts @@ -1,7 +1,13 @@ +/* + * Copyright (c) 2024, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ import { GraphQLESLintRule, GraphQLESLintRuleContext } from '@graphql-eslint/eslint-plugin'; -import { getLocation } from '../utils'; -export const NO_MUTATION_SUPPORTED_RULE_ID = 'no-mutation-supported'; +import { getLocation } from '../../utils'; +export const NO_MUTATION_SUPPORTED_RULE_ID = 'offline-graphql-no-mutation-supported'; export const rule: GraphQLESLintRule = { meta: { @@ -12,6 +18,27 @@ export const rule: GraphQLESLintRule = { category: 'Operations', recommended: true, examples: [ + { + title: 'Correct', + code: /* GraphQL */ ` + query accountQuery { + uiapi { + query { + Account { + edges { + node { + Id + Name { + value + } + } + } + } + } + } + } + ` + }, { title: 'Incorrect', code: /* GraphQL */ ` @@ -32,7 +59,8 @@ export const rule: GraphQLESLintRule = { ] }, messages: { - [NO_MUTATION_SUPPORTED_RULE_ID]: 'Mutation is not supported offline' + [NO_MUTATION_SUPPORTED_RULE_ID]: + 'Offline GraphQL: Mutation (data modification) is not supported offline.' }, schema: [] }, diff --git a/src/util/createRule.ts b/src/util/createRule.ts new file mode 100644 index 0000000..4175506 --- /dev/null +++ b/src/util/createRule.ts @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ + +import { ESLintUtils } from '@typescript-eslint/utils'; +import { version, homepage } from '../../package.json'; + +export default ESLintUtils.RuleCreator( + (name) => `${homepage}/blob/v${version}/lib/docs/${name}.md` +); diff --git a/src/rules/utils.ts b/src/utils.ts similarity index 100% rename from src/rules/utils.ts rename to src/utils.ts diff --git a/test/rules/apex/apex-import.ts b/test/rules/apex/apex-import.ts new file mode 100644 index 0000000..18afd2f --- /dev/null +++ b/test/rules/apex/apex-import.ts @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: MIT + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT + */ + +import { RuleTester } from '@typescript-eslint/rule-tester'; + +import { rule, APEX_IMPORT_RULE_ID } from '../../../src/rules/apex/apex-import'; + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser' +}); + +ruleTester.run('@salesforce/lwc-mobile/apex/apex-import', rule, { + valid: [ + { + code: ` + import { LightningElement, wire } from 'lwc'; + import getContactList from 'ContactController.getContactList'; + + export default class ApexWireMethodToFunction extends LightningElement { + contacts; + error; + + @wire(getContactList) + wiredContacts({ error, data }) { + if (data) { + this.contacts = data; + this.error = undefined; + } else if (error) { + this.error = error; + this.contacts = undefined; + } + } + } + ` + } + ], + invalid: [ + { + code: ` + import { LightningElement, wire } from 'lwc'; + import getContactList from '@salesforce/apex/ContactController.getContactList'; + + export default class ApexWireMethodToFunction extends LightningElement { + contacts; + error; + + @wire(getContactList) + wiredContacts({ error, data }) { + if (data) { + this.contacts = data; + this.error = undefined; + } else if (error) { + this.error = error; + this.contacts = undefined; + } + } + } + `, + errors: [{ messageId: APEX_IMPORT_RULE_ID }] + } + ] +}); diff --git a/test/rules/graphql/no-mutation-supported.spec.ts b/test/rules/graphql/no-mutation-supported.spec.ts index 53c6d8f..035e001 100644 --- a/test/rules/graphql/no-mutation-supported.spec.ts +++ b/test/rules/graphql/no-mutation-supported.spec.ts @@ -9,7 +9,28 @@ import { RULE_TESTER_CONFIG } from '../../shared'; const ruleTester = new RuleTester(RULE_TESTER_CONFIG); ruleTester.run('@salesforce/lwc-mobile/no-mutation-supported', rule as any, { - valid: [], + valid: [ + { + code: /* GraphQL */ ` + query accountQuery { + uiapi { + query { + Account { + edges { + node { + Id + Name { + value + } + } + } + } + } + } + } + ` + } + ], invalid: [ { code: /* GraphQL */ ` diff --git a/test/rules/utils.spec.ts b/test/rules/utils.spec.ts index 2f5f62c..b74a05b 100644 --- a/test/rules/utils.spec.ts +++ b/test/rules/utils.spec.ts @@ -1,5 +1,5 @@ import { describe } from 'node:test'; -import { getLocation } from '../../src/rules/utils'; +import { getLocation } from '../../src/utils'; import { Position } from 'estree'; import { expect } from '@jest/globals';