Skip to content

Commit 30ad848

Browse files
authoredApr 3, 2024··
feat: add lowercase to key-format-style rule (#492)
1 parent 4cd57e2 commit 30ad848

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed
 

‎.changeset/modern-apricots-flash.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+
add lowercase option to key-format-style rule

‎docs/rules/key-format-style.md

+28-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This rule aims to enforces specific casing for localization key names.
1313
```yaml
1414
camelCaseKey: The key for this value is camel case.
1515
kebab-case-key: The key for this value is kebab case.
16+
lowercase: The key for this value is lower case.
1617
snake_case_key: The key for this value is snake case.
1718
mixed_Case-key: Perhaps you don't want to use this casing.
1819
```
@@ -47,7 +48,7 @@ Also, the following localization key definitions are reported as errors, because
4748
{
4849
"@intlify/vue-i18n/key-format-style": [
4950
"error",
50-
"camelCase" | "kebab-case" | "snake_case",
51+
"camelCase" | "kebab-case" | "lowercase" | "snake_case",
5152
{
5253
"allowArray": false,
5354
"splitByDots": false
@@ -112,6 +113,32 @@ appTitle: I18N Management System
112113
app_title: I18N Management System
113114
```
114115
116+
:+1: Examples of **correct** code for this rule with `"lowercase"`:
117+
118+
<eslint-code-block language="yaml">
119+
120+
```yaml
121+
# eslint @intlify/vue-i18n/key-format-style: ['error', 'lowercase']
122+
123+
# ✓ GOOD
124+
apptitle: I18N Management System
125+
```
126+
127+
</eslint-code-block>
128+
129+
:-1: Examples of **incorrect** code for this rule with `"lowercase"`:
130+
131+
<eslint-code-block language="yaml">
132+
133+
```yaml
134+
# eslint @intlify/vue-i18n/key-format-style: ['error', 'lowercase']
135+
136+
# ✗ BAD
137+
appTitle: I18N Management System
138+
app_title: I18N Management System
139+
APP_TITLE: I18N Management System
140+
```
141+
115142
</eslint-code-block>
116143
117144
:+1: Examples of **correct** code for this rule with `"snake_case"`:

‎lib/rules/key-format-style.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const debug = debugBuilder('eslint-plugin-vue-i18n:key-format-style')
1616
const allowedCaseOptions = [
1717
'camelCase',
1818
'kebab-case',
19+
'lowercase',
1920
'snake_case',
2021
'SCREAMING_SNAKE_CASE'
2122
] as const

‎lib/utils/casing.ts

+16
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ export function isCamelCase(str: string): boolean {
7575
return true
7676
}
7777

78+
/**
79+
* Checks whether the given string is lowercase.
80+
*/
81+
export function isLowerCase(str: string): boolean {
82+
if (
83+
hasSymbols(str) ||
84+
hasUpper(str) ||
85+
/-|_|\s/u.exec(str) // kebab or snake or space
86+
) {
87+
return false
88+
}
89+
return true
90+
}
91+
7892
/**
7993
* Checks whether the given string is PascalCase.
8094
*/
@@ -104,6 +118,7 @@ const checkersMap = {
104118
'kebab-case': isKebabCase,
105119
snake_case: isSnakeCase,
106120
camelCase: isCamelCase,
121+
lowercase: isLowerCase,
107122
PascalCase: isPascalCase,
108123
SCREAMING_SNAKE_CASE: isScreamingSnakeCase
109124
}
@@ -127,6 +142,7 @@ export function pascalCase(str: string): string {
127142
export const allowedCaseOptions = [
128143
'camelCase',
129144
'kebab-case',
145+
'lowercase',
130146
'PascalCase',
131147
'snake_case',
132148
'SCREAMING_SNAKE_CASE'

‎tests/lib/rules/key-format-style.ts

+165
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,41 @@ tester.run('key-format-style', rule as never, {
129129
...options.json.file,
130130
options: ['kebab-case']
131131
},
132+
{
133+
code: `
134+
lowercase:
135+
foobar: kebab-value
136+
`,
137+
...options.yaml.file
138+
},
139+
{
140+
code: `{
141+
"lowercase": {
142+
"foobar": "kebab-value"
143+
}
144+
}
145+
`,
146+
...options.json.file
147+
},
148+
{
149+
code: `
150+
en-US:
151+
lowercase:
152+
foobar: kebab-value
153+
`,
154+
...options.yaml.key
155+
},
156+
{
157+
code: `{
158+
"en-US": {
159+
"lowercase": {
160+
"foobar": "kebab-value"
161+
}
162+
}
163+
}
164+
`,
165+
...options.json.key
166+
},
132167
{
133168
code: `
134169
snake_case:
@@ -379,6 +414,136 @@ tester.run('key-format-style', rule as never, {
379414
}
380415
]
381416
},
417+
{
418+
code: `
419+
foo-bar: baz
420+
`,
421+
...options.yaml.file,
422+
options: ['lowercase'],
423+
errors: [
424+
{
425+
message: '"foo-bar" is not lowercase',
426+
line: 2
427+
}
428+
]
429+
},
430+
{
431+
code: `
432+
en-US:
433+
foo-bar: baz
434+
`,
435+
...options.yaml.key,
436+
options: ['lowercase'],
437+
errors: [
438+
{
439+
message: '"foo-bar" is not lowercase',
440+
line: 3
441+
}
442+
]
443+
},
444+
{
445+
code: `
446+
{"foo-bar": "baz"}
447+
`,
448+
...options.json.file,
449+
options: ['lowercase'],
450+
errors: [
451+
{
452+
message: '"foo-bar" is not lowercase',
453+
line: 2
454+
}
455+
]
456+
},
457+
{
458+
code: `
459+
{"en-US": {
460+
"foo-bar": "baz"
461+
}}`,
462+
...options.json.key,
463+
options: ['lowercase'],
464+
errors: [
465+
{
466+
message: '"foo-bar" is not lowercase',
467+
line: 3
468+
}
469+
]
470+
},
471+
{
472+
code: `
473+
kebab-case:
474+
snake_case: camelCase
475+
`,
476+
...options.yaml.file,
477+
options: ['lowercase'],
478+
errors: [
479+
{
480+
message: '"kebab-case" is not lowercase',
481+
line: 2
482+
},
483+
{
484+
message: '"snake_case" is not lowercase',
485+
line: 3
486+
}
487+
]
488+
},
489+
{
490+
code: `{
491+
"kebab-case": {
492+
"snake_case": "camelCase"
493+
}
494+
}
495+
`,
496+
...options.json.file,
497+
options: ['lowercase'],
498+
errors: [
499+
{
500+
message: '"kebab-case" is not lowercase',
501+
line: 2
502+
},
503+
{
504+
message: '"snake_case" is not lowercase',
505+
line: 3
506+
}
507+
]
508+
},
509+
{
510+
code: `
511+
SCREAMING_SNAKE_CASE:
512+
PascalCase: camelCase
513+
`,
514+
...options.yaml.file,
515+
options: ['lowercase'],
516+
errors: [
517+
{
518+
message: '"SCREAMING_SNAKE_CASE" is not lowercase',
519+
line: 2
520+
},
521+
{
522+
message: '"PascalCase" is not lowercase',
523+
line: 3
524+
}
525+
]
526+
},
527+
{
528+
code: `{
529+
"SCREAMING_SNAKE_CASE": {
530+
"PascalCase": "camelCase"
531+
}
532+
}
533+
`,
534+
...options.json.file,
535+
options: ['lowercase'],
536+
errors: [
537+
{
538+
message: '"SCREAMING_SNAKE_CASE" is not lowercase',
539+
line: 2
540+
},
541+
{
542+
message: '"PascalCase" is not lowercase',
543+
line: 3
544+
}
545+
]
546+
},
382547
{
383548
code: `
384549
- foo

0 commit comments

Comments
 (0)
Please sign in to comment.