Skip to content

Commit

Permalink
feat: support flat config (#53)
Browse files Browse the repository at this point in the history
* feat: support flat config

chore: generate rules by scripts
chore: run `lint:js`

* chore: update `export` same as pre version

* chore: update README.md
  • Loading branch information
9romise committed Aug 22, 2024
1 parent a595837 commit ac1c775
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 53 deletions.
57 changes: 53 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,32 @@ npm install eslint-plugin-pinia --save-dev

## Usage

Add `pinia` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
Add `pinia` to the plugins section of your `.eslintrc` or `eslint.config.js` configuration file. You can omit the `eslint-plugin-` prefix:

```json
// .eslintrc [Legacy Config]
{
"plugins": ["pinia"]
}
```

```js
// eslint.config.js
import pinia from 'eslint-plugin-pinia'

export default [
plugins: {
pinia
}
]
```

### Rule Configuration

Then configure the rules you want to use under the rules section.

```json
// .eslintrc [Legacy Config]
{
"rules": {
"pinia/require-export-define-store": [
Expand All @@ -43,28 +56,64 @@ Then configure the rules you want to use under the rules section.
}
```

```js
// eslint.config.js
import pinia from 'eslint-plugin-pinia'

export default [
{
plugin: {
pinia
},
rules: {
"pinia/require-export-define-store": ["warn"]
}
}
]
```

### Recommended

To use the recommended configuration, extend it in your `.eslintrc` file:
To use the recommended configuration, extend it in your `.eslintrc` or `eslint.config.js` file:

```json
// .eslintrc [Legacy Config]
{
"extends": ["plugin:pinia/recommended"]
}
```

All recommend rules will be set to error by default. You can however disable some rules by setting turning them `off` in your `.eslintrc` file or by setting them to `warn` in your `.eslintrc`.
```js
// eslint.config.js
import pinia from 'eslint-plugin-pinia'

export default [
pinia.configs["recommended-flat"],
]
```

All recommend rules will be set to error by default. You can however disable some rules by setting turning them `off` in your configuration file or by setting them to `warn` in your configuration file.

### all rules

To use the all configuration, extend it in your `.eslintrc` file:
To use the all configuration, extend it in your `.eslintrc` or `eslint.config.js` file:

```json
// .eslintrc [Legacy Config]
{
"extends": ["plugin:pinia/all"]
}
```

```js
// eslint.config.js
import pinia from 'eslint-plugin-pinia'

export default [
pinia.configs["all-flat"],
]
```

## Rules

<!-- begin auto-generated rules list -->
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
},
"scripts": {
"build": "unbuild",
"update": "tsx scripts/update",
"lint:md": "markdownlint \"**/*.md\" --fix",
"lint:eslint-docs": "npm run build && eslint-doc-generator --check",
"lint:js": "eslint . --fix",
Expand Down
37 changes: 37 additions & 0 deletions scripts/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import process from 'node:process'
import { resolve } from 'node:path'
import fs from 'node:fs'

const cwd = process.cwd()

const rulesDir = resolve(cwd, 'src', 'rules')

function camelCase(str: string) {
return str
.replace(/[^\w-]+/, '')
.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
}

function generateRules() {
const targetFile = 'index.ts'

const header = '/* GENERATED BY SCRIPTS, DO NOT EDIT DIRECTLY */'

const rules = fs.readdirSync(rulesDir)
.filter(i => i !== targetFile)
.map(i => i.replace('.ts', ''))

const content = [
header,
...rules.map(i => `import ${camelCase(i)}, { RULE_NAME as ${camelCase(i)}Name } from './${i}'`),
'',
'export default {',
...rules.map(i => ` [${camelCase(i)}Name]: ${camelCase(i)},`),
'}',
''
].join('\n')

fs.writeFileSync(resolve(rulesDir, targetFile), content)
}

generateRules()
88 changes: 43 additions & 45 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
import requireSetupStoreProps, {
RULE_NAME as requireSetupStorePropsName
} from './rules/require-setup-store-properties-export'

import neverExportInitializedStore, {
RULE_NAME as neverExportInitializedStoreName
} from './rules/never-export-initialized-store'

import preferNamingConvention, {
RULE_NAME as preferNamingConventionName
} from './rules/prefer-use-store-naming-convention'

import preferSingleStore, {
RULE_NAME as preferSingleStoreName
} from './rules/prefer-single-store-per-file'

import noReturnGlobalProperties, {
RULE_NAME as noReturnGlobalPropertiesName
} from './rules/no-return-global-properties'

import noDuplicateStoreIds, {
RULE_NAME as noDuplicateStoreIdsName
} from './rules/no-duplicate-store-ids'

const createConfig = (rules: Record<string, string>) => ({
plugins: ['pinia'],
rules: Object.keys(rules).reduce((acc, ruleName) => {
return {
...acc,
[`pinia/${ruleName}`]: rules[ruleName]
}
}, {})
})
import { RULE_NAME as requireSetupStorePropsName } from './rules/require-setup-store-properties-export'
import { RULE_NAME as neverExportInitializedStoreName } from './rules/never-export-initialized-store'
import { RULE_NAME as preferNamingConventionName } from './rules/prefer-use-store-naming-convention'
import { RULE_NAME as preferSingleStoreName } from './rules/prefer-single-store-per-file'
import { RULE_NAME as noReturnGlobalPropertiesName } from './rules/no-return-global-properties'
import { RULE_NAME as noDuplicateStoreIdsName } from './rules/no-duplicate-store-ids'
import rules from './rules'

Check failure on line 7 in src/index.ts

View workflow job for this annotation

GitHub Actions / release

Cannot find module './rules'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?

const plugin = {
rules
}

const allRules = {
[requireSetupStorePropsName]: 'warn',
Expand All @@ -48,17 +26,37 @@ const recommended = {
[neverExportInitializedStoreName]: 'error'
}

export default {
rules: {
[requireSetupStorePropsName]: requireSetupStoreProps,
[neverExportInitializedStoreName]: neverExportInitializedStore,
[preferNamingConventionName]: preferNamingConvention,
[preferSingleStoreName]: preferSingleStore,
[noReturnGlobalPropertiesName]: noReturnGlobalProperties,
[noDuplicateStoreIdsName]: noDuplicateStoreIds
},
configs: {
all: createConfig(allRules),
recommended: createConfig(recommended)
function createConfig<T extends Record<string, any>>(_rules: T, flat = false) {
const name = 'pinia'
const rules: Record<`pinia/${string}`, string> = Object.keys(_rules).reduce((acc, ruleName) => {
return {
...acc,
[`${name}/${ruleName}`]: rules[ruleName]
}
}, {})
if (flat) {
return {
plugins: {
[name]: plugin
},
rules
}
} else {
return {
plugins: [name],
rules
}
}
}

export const configs = {
all: createConfig(allRules),
recommended: createConfig(recommended),
'all-flat': createConfig(allRules, true),
'recommended-flat': createConfig(recommended, true)
}

export default {
...plugin,
configs,
}
16 changes: 16 additions & 0 deletions src/rules/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* GENERATED BY SCRIPTS, DO NOT EDIT DIRECTLY */
import neverExportInitializedStore, { RULE_NAME as neverExportInitializedStoreName } from './never-export-initialized-store'
import noDuplicateStoreIds, { RULE_NAME as noDuplicateStoreIdsName } from './no-duplicate-store-ids'
import noReturnGlobalProperties, { RULE_NAME as noReturnGlobalPropertiesName } from './no-return-global-properties'
import preferSingleStorePerFile, { RULE_NAME as preferSingleStorePerFileName } from './prefer-single-store-per-file'
import preferUseStoreNamingConvention, { RULE_NAME as preferUseStoreNamingConventionName } from './prefer-use-store-naming-convention'
import requireSetupStorePropertiesExport, { RULE_NAME as requireSetupStorePropertiesExportName } from './require-setup-store-properties-export'

export default {
[neverExportInitializedStoreName]: neverExportInitializedStore,
[noDuplicateStoreIdsName]: noDuplicateStoreIds,
[noReturnGlobalPropertiesName]: noReturnGlobalProperties,
[preferSingleStorePerFileName]: preferSingleStorePerFile,
[preferUseStoreNamingConventionName]: preferUseStoreNamingConvention,
[requireSetupStorePropertiesExportName]: requireSetupStorePropertiesExport
}
2 changes: 1 addition & 1 deletion src/rules/no-duplicate-store-ids.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createEslintRule } from '../utils/rule-creator'
import { AST_NODE_TYPES } from '@typescript-eslint/utils'
import { createEslintRule } from '../utils/rule-creator'

export const RULE_NAME = 'no-duplicate-store-ids'
export type MESSAGE_IDS = 'duplicatedStoreIds'
Expand Down
4 changes: 1 addition & 3 deletions src/rules/no-return-global-properties.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import {} from 'typescript'
import { createEslintRule } from '../utils/rule-creator'

export const RULE_NAME = 'no-return-global-properties'
Expand Down Expand Up @@ -28,9 +27,8 @@ export default createEslintRule<Options, MESSAGE_IDS>({
node.declarations.forEach((declaration) => {
if (declaration.init && declaration.init.type === 'CallExpression') {
const calleeName = declaration.init.callee.name
if (calleeName === 'useRoute' || calleeName === 'inject') {
if (calleeName === 'useRoute' || calleeName === 'inject')
variablesUsingGlobalCallee.add(declaration.id.name)
}
}
})
},
Expand Down

0 comments on commit ac1c775

Please sign in to comment.