Skip to content

Commit a488f15

Browse files
authored
feat: add support for eslint v9 (#463)
* feat: add support for eslint v9 * Create shiny-colts-search.md * fix * format
1 parent 7042275 commit a488f15

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+424
-268
lines changed

.changeset/shiny-colts-search.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@intlify/eslint-plugin-vue-i18n": minor
3+
---
4+
5+
feat: add support for eslint v9

.eslintrc.cjs

+36-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,42 @@ module.exports = {
2020
rules: {
2121
'object-shorthand': 'error',
2222
'no-debugger': 'error',
23-
'vue/multi-word-component-names': 'off'
23+
'vue/multi-word-component-names': 'off',
24+
25+
'prefer-template': 'error',
26+
'no-restricted-properties': [
27+
'error',
28+
{
29+
object: 'context',
30+
property: 'getSourceCode',
31+
message: 'Use lib/utils/compat.ts'
32+
},
33+
{
34+
object: 'context',
35+
property: 'getFilename',
36+
message: 'Use lib/utils/compat.ts'
37+
},
38+
{
39+
object: 'context',
40+
property: 'getPhysicalFilename',
41+
message: 'Use lib/utils/compat.ts'
42+
},
43+
{
44+
object: 'context',
45+
property: 'getCwd',
46+
message: 'Use lib/utils/compat.ts'
47+
},
48+
{
49+
object: 'context',
50+
property: 'getScope',
51+
message: 'Use lib/utils/compat.ts'
52+
},
53+
{
54+
object: 'context',
55+
property: 'parserServices',
56+
message: 'Use lib/utils/compat.ts'
57+
}
58+
]
2459
},
2560
overrides: [
2661
{

.github/workflows/test.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ jobs:
5656
strategy:
5757
matrix:
5858
os: [ubuntu-latest]
59-
eslint: [5, 6, 7, 8]
60-
node: [16]
59+
eslint: [5, 6, 7, 8, ^9.0.0-0]
60+
node: [20]
6161
steps:
6262
- name: Checkout
6363
uses: actions/checkout@v4

docs/.vitepress/components/resource-group.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default {
1414
return {
1515
$resourceGroup: {
1616
async set(fileName, code) {
17-
Vue.set(data.fileContents, '/path/' + fileName, code)
17+
Vue.set(data.fileContents, `/path/${fileName}`, code)
1818
1919
const timeSeq = ++waitSeq
2020
await Vue.nextTick()

lib/rules/key-format-style.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { RuleContext, RuleListener } from '../types'
1010
import { getCasingChecker } from '../utils/casing'
1111
import type { LocaleMessage } from '../utils/locale-messages'
1212
import { createRule } from '../utils/rule'
13+
import { getFilename, getSourceCode } from '../utils/compat'
1314
const debug = debugBuilder('eslint-plugin-vue-i18n:key-format-style')
1415

1516
const allowedCaseOptions = [
@@ -21,7 +22,8 @@ const allowedCaseOptions = [
2122
type CaseOption = (typeof allowedCaseOptions)[number]
2223

2324
function create(context: RuleContext): RuleListener {
24-
const filename = context.getFilename()
25+
const filename = getFilename(context)
26+
const sourceCode = getSourceCode(context)
2527
const expectCasing: CaseOption = context.options[0] ?? 'camelCase'
2628
const checker = getCasingChecker(expectCasing)
2729
const allowArray: boolean = context.options[1]?.allowArray
@@ -115,7 +117,6 @@ function create(context: RuleContext): RuleListener {
115117
if (cachedLoc) {
116118
return cachedLoc
117119
}
118-
const sourceCode = context.getSourceCode()
119120
return (cachedLoc = {
120121
start: sourceCode.getLocFromIndex(offset + start),
121122
end: sourceCode.getLocFromIndex(offset + end)
@@ -264,17 +265,20 @@ function create(context: RuleContext): RuleListener {
264265
return createVisitorForYaml(targetLocaleMessage)
265266
}
266267
)
267-
} else if (context.parserServices.isJSON || context.parserServices.isYAML) {
268+
} else if (
269+
sourceCode.parserServices.isJSON ||
270+
sourceCode.parserServices.isYAML
271+
) {
268272
const localeMessages = getLocaleMessages(context)
269273
const targetLocaleMessage = localeMessages.findExistLocaleMessage(filename)
270274
if (!targetLocaleMessage) {
271275
debug(`ignore ${filename} in key-format-style`)
272276
return {}
273277
}
274278

275-
if (context.parserServices.isJSON) {
279+
if (sourceCode.parserServices.isJSON) {
276280
return createVisitorForJson(targetLocaleMessage)
277-
} else if (context.parserServices.isYAML) {
281+
} else if (sourceCode.parserServices.isYAML) {
278282
return createVisitorForYaml(targetLocaleMessage)
279283
}
280284
return {}

lib/rules/no-deprecated-i18n-component.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ import { defineTemplateBodyVisitor } from '../utils/index'
55
import type { RuleContext, RuleListener } from '../types'
66
import type { AST as VAST } from 'vue-eslint-parser'
77
import { createRule } from '../utils/rule'
8+
import { getSourceCode } from '../utils/compat'
89

910
function create(context: RuleContext): RuleListener {
1011
return defineTemplateBodyVisitor(context, {
1112
VElement(node: VAST.VElement) {
1213
if (node.name !== 'i18n') {
1314
return
1415
}
15-
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
16+
const sourceCode = getSourceCode(context)
17+
const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()
1618
const tagNameToken = tokenStore.getFirstToken(node.startTag)
1719
context.report({
1820
node: tagNameToken,

lib/rules/no-duplicate-keys-in-locale.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
import { joinPath } from '../utils/key-path'
1717
import { getCwd } from '../utils/get-cwd'
1818
import { createRule } from '../utils/rule'
19+
import { getFilename, getSourceCode } from '../utils/compat'
1920
const debug = debugBuilder('eslint-plugin-vue-i18n:no-duplicate-keys-in-locale')
2021

2122
interface DictData {
@@ -34,13 +35,14 @@ interface PathStack {
3435
function getMessageFilepath(fullPath: string, context: RuleContext) {
3536
const cwd = getCwd(context)
3637
if (fullPath.startsWith(cwd)) {
37-
return fullPath.replace(cwd + '/', './')
38+
return fullPath.replace(`${cwd}/`, './')
3839
}
3940
return fullPath
4041
}
4142

4243
function create(context: RuleContext): RuleListener {
43-
const filename = context.getFilename()
44+
const filename = getFilename(context)
45+
const sourceCode = getSourceCode(context)
4446
const options = (context.options && context.options[0]) || {}
4547
const ignoreI18nBlock = Boolean(options.ignoreI18nBlock)
4648

@@ -129,7 +131,7 @@ function create(context: RuleContext): RuleListener {
129131
}
130132
if (typeof value.value !== 'object') {
131133
reportFiles.push(
132-
'"' + getMessageFilepath(value.source.fullpath, context) + '"'
134+
`"${getMessageFilepath(value.source.fullpath, context)}"`
133135
)
134136
} else {
135137
nextOtherDictionaries.push({
@@ -145,7 +147,7 @@ function create(context: RuleContext): RuleListener {
145147
message: `duplicate key '${keyPathStr}' in '${pathStack.locale}'. ${
146148
reportFiles.length === 0
147149
? last
148-
: reportFiles.join(', ') + ', and ' + last
150+
: `${reportFiles.join(', ')}, and ${last}`
149151
} has the same key`,
150152
loc: reportNode.loc
151153
})
@@ -316,7 +318,7 @@ function create(context: RuleContext): RuleListener {
316318
lm => lm !== targetLocaleMessage
317319
)
318320
return createVisitorForJson(
319-
ctx.getSourceCode(),
321+
getSourceCode(ctx),
320322
targetLocaleMessage,
321323
otherLocaleMessages
322324
)
@@ -335,31 +337,33 @@ function create(context: RuleContext): RuleListener {
335337
lm => lm !== targetLocaleMessage
336338
)
337339
return createVisitorForYaml(
338-
ctx.getSourceCode(),
340+
getSourceCode(ctx),
339341
targetLocaleMessage,
340342
otherLocaleMessages
341343
)
342344
}
343345
)
344-
} else if (context.parserServices.isJSON || context.parserServices.isYAML) {
346+
} else if (
347+
sourceCode.parserServices.isJSON ||
348+
sourceCode.parserServices.isYAML
349+
) {
345350
const localeMessages = getLocaleMessages(context)
346351
const targetLocaleMessage = localeMessages.findExistLocaleMessage(filename)
347352
if (!targetLocaleMessage) {
348353
debug(`ignore ${filename} in no-duplicate-keys-in-locale`)
349354
return {}
350355
}
351356

352-
const sourceCode = context.getSourceCode()
353357
const otherLocaleMessages: LocaleMessage[] =
354358
localeMessages.localeMessages.filter(lm => lm !== targetLocaleMessage)
355359

356-
if (context.parserServices.isJSON) {
360+
if (sourceCode.parserServices.isJSON) {
357361
return createVisitorForJson(
358362
sourceCode,
359363
targetLocaleMessage,
360364
otherLocaleMessages
361365
)
362-
} else if (context.parserServices.isYAML) {
366+
} else if (sourceCode.parserServices.isYAML) {
363367
return createVisitorForYaml(
364368
sourceCode,
365369
targetLocaleMessage,

lib/rules/no-dynamic-keys.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import { defineTemplateBodyVisitor, isStaticLiteral } from '../utils/index'
55
import type { RuleContext, RuleListener } from '../types'
66
import type { AST as VAST } from 'vue-eslint-parser'
77
import { createRule } from '../utils/rule'
8+
import { getSourceCode } from '../utils/compat'
89

910
function getNodeName(context: RuleContext, node: VAST.Node): string {
1011
if (node.type === 'Identifier') {
1112
return node.name
1213
}
13-
const sourceCode = context.getSourceCode()
14+
const sourceCode = getSourceCode(context)
1415
if (
1516
sourceCode.ast.range[0] <= node.range[0] &&
1617
node.range[1] <= sourceCode.ast.range[1]
@@ -20,7 +21,7 @@ function getNodeName(context: RuleContext, node: VAST.Node): string {
2021
.map(t => t.value)
2122
.join('')
2223
}
23-
const tokenStore = context.parserServices.getTemplateBodyTokenStore()
24+
const tokenStore = sourceCode.parserServices.getTemplateBodyTokenStore()
2425
return tokenStore
2526
.getTokens(node)
2627
.map(t => t.value)

lib/rules/no-html-messages.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { AST as YAMLAST } from 'yaml-eslint-parser'
1010
import type { RuleContext, RuleListener } from '../types'
1111
import { createRule } from '../utils/rule'
1212
import type { DefaultTreeAdapterMap } from 'parse5'
13+
import { getFilename, getSourceCode } from '../utils/compat'
1314

1415
const debug = debugBuilder('eslint-plugin-vue-i18n:no-html-messages')
1516

@@ -25,7 +26,8 @@ function findHTMLNode(node: DocumentFragment): Element | undefined {
2526
}
2627

2728
function create(context: RuleContext): RuleListener {
28-
const filename = context.getFilename()
29+
const filename = getFilename(context)
30+
const sourceCode = getSourceCode(context)
2931

3032
/**
3133
* @param {JSONLiteral} node
@@ -97,14 +99,14 @@ function create(context: RuleContext): RuleListener {
9799
}
98100
}
99101
)
100-
} else if (context.parserServices.isJSON) {
102+
} else if (sourceCode.parserServices.isJSON) {
101103
if (!getLocaleMessages(context).findExistLocaleMessage(filename)) {
102104
return {}
103105
}
104106
return {
105107
JSONLiteral: verifyJSONLiteral
106108
}
107-
} else if (context.parserServices.isYAML) {
109+
} else if (sourceCode.parserServices.isYAML) {
108110
if (!getLocaleMessages(context).findExistLocaleMessage(filename)) {
109111
return {}
110112
}

lib/rules/no-missing-keys-in-other-locales.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import type {
1414
import type { LocaleMessage, LocaleMessages } from '../utils/locale-messages'
1515
import { joinPath } from '../utils/key-path'
1616
import { createRule } from '../utils/rule'
17+
import { getFilename, getSourceCode } from '../utils/compat'
1718
const debug = debugBuilder(
1819
'eslint-plugin-vue-i18n:no-missing-keys-in-other-locales'
1920
)
2021

2122
function create(context: RuleContext): RuleListener {
22-
const filename = context.getFilename()
23+
const filename = getFilename(context)
24+
const sourceCode = getSourceCode(context)
2325
const ignoreLocales: string[] = context.options[0]?.ignoreLocales || []
2426

2527
function reportMissing(
@@ -307,17 +309,20 @@ function create(context: RuleContext): RuleListener {
307309
return createVisitorForYaml(targetLocaleMessage, localeMessages)
308310
}
309311
)
310-
} else if (context.parserServices.isJSON || context.parserServices.isYAML) {
312+
} else if (
313+
sourceCode.parserServices.isJSON ||
314+
sourceCode.parserServices.isYAML
315+
) {
311316
const localeMessages = getLocaleMessages(context)
312317
const targetLocaleMessage = localeMessages.findExistLocaleMessage(filename)
313318
if (!targetLocaleMessage) {
314319
debug(`ignore ${filename} in no-missing-keys-in-other-locales`)
315320
return {}
316321
}
317322

318-
if (context.parserServices.isJSON) {
323+
if (sourceCode.parserServices.isJSON) {
319324
return createVisitorForJson(targetLocaleMessage, localeMessages)
320-
} else if (context.parserServices.isYAML) {
325+
} else if (sourceCode.parserServices.isYAML) {
321326
return createVisitorForYaml(targetLocaleMessage, localeMessages)
322327
}
323328
return {}

0 commit comments

Comments
 (0)