-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
--- | ||
title: '@rotki/no-deprecated-props' | ||
description: ... | ||
since: v0.2.0 | ||
--- | ||
|
||
# @rotki/no-deprecated-props | ||
|
||
> ... | ||
- :black_nib:️ The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule. | ||
|
||
## :book: Rule Details | ||
|
||
This rule reports the usage of deprecated properties in components. | ||
|
||
<eslint-code-block fix> | ||
|
||
<!-- eslint-skip --> | ||
|
||
```vue | ||
<!-- ✓ GOOD --> | ||
<template> | ||
<RuiRadio value="ok" /> | ||
</template> | ||
<!-- ✗ BAD --> | ||
<template> | ||
<RuiRadio internal-value="ok" /> | ||
</template> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :gear: Options | ||
|
||
```json | ||
{ | ||
"@rotki/no-deprecated-props": ["error"] | ||
} | ||
``` | ||
|
||
- | ||
|
||
## :rocket: Version | ||
|
||
This rule was introduced in `@rotki/eslint-plugin` v0.2.0 | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/rotki/eslint-plugin/blob/master/src/rules/no-deprecated-props.ts) | ||
- [Test source](https://github.com/rotki/eslint-plugin/tree/master/tests/rules/no-deprecated-props.ts) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { kebabCase, pascalCase } from 'scule'; | ||
import createDebug from 'debug'; | ||
import { createEslintRule, defineTemplateBodyVisitor } from '../utils'; | ||
import type { AST as VAST } from 'vue-eslint-parser'; | ||
|
||
const debug = createDebug('@rotki/eslint-plugin:no-deprecated-props'); | ||
|
||
export const RULE_NAME = 'no-deprecated-props'; | ||
|
||
export type MessageIds = 'replacedWith'; | ||
|
||
export type Options = []; | ||
|
||
const replacements = { | ||
RuiRadio: { | ||
internalValue: 'value', | ||
}, | ||
} as const; | ||
|
||
function hasReplacement(tag: string): tag is (keyof typeof replacements) { | ||
return Object.prototype.hasOwnProperty.call(replacements, tag); | ||
} | ||
|
||
function getPropName(node: VAST.VDirective | VAST.VAttribute): string | undefined { | ||
if (node.directive) { | ||
if (node.key.argument?.type !== 'VIdentifier') | ||
return undefined; | ||
return kebabCase(node.key.argument.rawName); | ||
} | ||
return kebabCase(node.key.rawName); | ||
} | ||
|
||
export default createEslintRule<Options, MessageIds>({ | ||
create(context) { | ||
return defineTemplateBodyVisitor(context, { | ||
VAttribute(node: VAST.VAttribute | VAST.VDirective) { | ||
if (node.directive && (node.value?.type === 'VExpressionContainer' && (node.key.name.name !== 'bind' || !node.key.argument))) | ||
return; | ||
|
||
const tag = pascalCase(node.parent.parent.rawName); | ||
|
||
if (!hasReplacement(tag)) | ||
return; | ||
|
||
debug(`${tag} has replacement properties`); | ||
|
||
const propName = getPropName(node); | ||
const propNameNode = node.directive ? node.key.argument : node.key; | ||
|
||
if (!propName || !propNameNode) { | ||
debug('could not get prop name and/or node'); | ||
return; | ||
} | ||
|
||
Object.entries(replacements[tag]).forEach(([prop, replacement]) => { | ||
if (kebabCase(prop) === propName) { | ||
debug(`preparing a replacement for ${tag}:${propName} -> ${replacement}`); | ||
context.report({ | ||
data: { | ||
prop, | ||
replacement, | ||
}, | ||
fix(fixer) { | ||
return fixer.replaceText(propNameNode, replacement); | ||
}, | ||
messageId: 'replacedWith', | ||
node: propNameNode, | ||
}); | ||
} | ||
}); | ||
}, | ||
}); | ||
}, | ||
defaultOptions: [], | ||
meta: { | ||
docs: { | ||
description: '...', | ||
}, | ||
fixable: 'code', | ||
messages: { | ||
replacedWith: `'{{ prop }}' has been replaced with '{{ replacement }}'`, | ||
}, | ||
schema: [], | ||
type: 'problem', | ||
}, | ||
name: RULE_NAME, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
class AssertionError extends Error { | ||
constructor(msg: string) { | ||
super(msg); | ||
this.name = 'AssertionError'; | ||
} | ||
} | ||
|
||
export function assert(condition: any, msg?: string): asserts condition { | ||
if (!condition) | ||
throw new AssertionError(msg ?? 'AssertionError'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ export * from './node'; | |
export * from './config'; | ||
|
||
export * from './array'; | ||
|
||
export * from './assertions'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { RuleTester } from 'eslint'; | ||
import rule from '../../src/rules/no-deprecated-props'; | ||
|
||
const vueParser = require.resolve('vue-eslint-parser'); | ||
|
||
const tester = new RuleTester({ | ||
parser: vueParser, | ||
parserOptions: { | ||
ecmaVersion: 2020, | ||
sourceType: 'module', | ||
}, | ||
}); | ||
|
||
tester.run('no-deprecated-props', rule as never, { | ||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script lang="ts"> | ||
const val = ref('') | ||
</script> | ||
<template> | ||
<div> | ||
<RuiRadio :value="val"/> | ||
<RuiRadio value="ok"/> | ||
</div> | ||
</template> | ||
`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: ` | ||
<script lang="ts"> | ||
const val = ref('') | ||
</script> | ||
<template> | ||
<div> | ||
<RuiRadio :internal-value="val"/> | ||
<RuiRadio internal-value="ok"/> | ||
</div> | ||
</template> | ||
`.trim(), | ||
output: ` | ||
<script lang="ts"> | ||
const val = ref('') | ||
</script> | ||
<template> | ||
<div> | ||
<RuiRadio :value="val"/> | ||
<RuiRadio value="ok"/> | ||
</div> | ||
</template> | ||
`.trim(), | ||
errors: [ | ||
{ | ||
messageId: 'replacedWith', | ||
}, | ||
{ | ||
messageId: 'replacedWith', | ||
}, | ||
], | ||
}, | ||
], | ||
}); |