diff --git a/README.md b/README.md index c4f83fb..1d62241 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ Members can be matched to positional slots using several criteria, including nam - `accessorPair`: `true|false`. True to match only getters and setters that are part of a pair. i.e., only those that have both `get` and `set` methods defined. - `static`: `true|false` to restrict the match to static or instance members. - `private`: `true|false` to restrict the match to [private members](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields). **Note**: Private members currently require a custom parser like [babel-eslint](https://github.com/babel/babel-eslint). +- `accessibility`: `"public"|"private"|"protected"` to restrict the match to members with the specified typescript accessibility modifier. **Note**: Requires `@typescript-eslint/parser`. - `async`: `true|false` to restrict the match to async members. - `sort`: `"alphabetical"|"none"`. Used to require a specific sorting within the slot for matched members. Defaults to `"none"`. - `groupByDecorator`: a string used to group properties with the same decorator name (e.g. `observable` for `@observable`). Can be used together with `sort`. **Note**: Decorators are a Stage 2 proposal and require a custom parser like [babel-eslint](https://github.com/babel/babel-eslint). diff --git a/src/rules/schema.js b/src/rules/schema.js index 0599449..6fb81ba 100644 --- a/src/rules/schema.js +++ b/src/rules/schema.js @@ -39,6 +39,7 @@ export const sortClassMembersSchema = [ static: { type: 'boolean' }, private: { type: 'boolean' }, async: { type: 'boolean' }, + accessibility: { enum: ['public', 'private', 'protected'] }, }, additionalProperties: false, }, diff --git a/src/rules/sort-class-members.js b/src/rules/sort-class-members.js index f573317..7c41794 100644 --- a/src/rules/sort-class-members.js +++ b/src/rules/sort-class-members.js @@ -175,6 +175,7 @@ function getMemberInfo(node, sourceCode) { let propertyType; let async = false; let decorators = []; + const accessibility = node.accessibility ?? 'public'; decorators = (!!node.decorators && @@ -218,6 +219,7 @@ function getMemberInfo(node, sourceCode) { static: node.static, async, private: isPrivate, + accessibility, kind: node.kind, propertyType, node, @@ -418,6 +420,7 @@ const comparers = [ { property: 'static', value: 10, test: (m, s) => s.static === m.static }, { property: 'async', value: 10, test: (m, s) => s.async === m.async }, { property: 'private', value: 10, test: (m, s) => s.private === m.private }, + { property: 'accessibility', value: 10, test: (m, s) => s.accessibility == m.accessibility }, { property: 'kind', value: 10, test: (m, s) => s.kind === m.kind }, { property: 'groupByDecorator', diff --git a/test/rules/sort-class-members.spec.js b/test/rules/sort-class-members.spec.js index eb6395d..910d3eb 100644 --- a/test/rules/sort-class-members.spec.js +++ b/test/rules/sort-class-members.spec.js @@ -236,6 +236,24 @@ const privateRegexpOptions = [ }, ]; +const typescriptAccessibilityOptions = [ + { + groups: { + private: [ + { + accessibility: 'private', + }, + ], + public: [ + { + accessibility: 'public', + }, + ], + }, + order: ['[private]', 'constructor', '[public]'], + }, +]; + ruleTester.run('sort-class-members', rule, { valid: [ { code: 'class A {}', options: defaultOptions }, @@ -344,6 +362,18 @@ ruleTester.run('sort-class-members', rule, { // Class expressions { code: 'module.exports = class A {}', options: defaultOptions }, { code: 'class { [k: string]: any; }', parser: require.resolve('@typescript-eslint/parser') }, + + // TS accessibility + { + code: 'class { private a: any; constructor(){} b(){} }', + options: typescriptAccessibilityOptions, + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: 'class { private a: any; constructor(){} public b(){} c(){} }', + options: typescriptAccessibilityOptions, + parser: require.resolve('@typescript-eslint/parser'), + }, ], invalid: [ { @@ -832,6 +862,30 @@ ruleTester.run('sort-class-members', rule, { options: privateRegexpOptions, }, ]), + { + code: 'class { constructor(){} private b: any; }', + output: 'class { private b: any; constructor(){} }', + errors: [ + { + message: 'Expected property b to come before constructor.', + type: 'PropertyDefinition', + }, + ], + options: typescriptAccessibilityOptions, + parser: require.resolve('@typescript-eslint/parser'), + }, + { + code: 'class { a(){} private b: any; }', + output: 'class { private b: any; a(){} }', + errors: [ + { + message: 'Expected property b to come before method a.', + type: 'PropertyDefinition', + }, + ], + options: typescriptAccessibilityOptions, + parser: require.resolve('@typescript-eslint/parser'), + }, ], });