Repository: intlify/eslint-plugin-vue-i18n
Pull request #585 (2024-12-09 00:35:25)

 feat!: update config

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: e82637aebc306b716a8ea0e19cd85dfab7b159ef

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/intlify/eslint-plugin-vue-i18n/new/config?filename=.changeset/old-islands-admire.md&value=---%0A%22%40intlify%2Feslint-plugin-vue-i18n%22%3A%20patch%0A---%0A%0A%20feat!%3A%20update%20config%0A)


cloudflare-workers-and-pages[bot]: ## Deploying eslint-plugin-vue-i18n with &nbsp;<a href="https://pages.dev"><img alt="Cloudflare Pages" src="https://user-images.githubusercontent.com/23264/106598434-9e719e00-654f-11eb-9e59-6167043cfa01.png" width="16"></a> &nbsp;Cloudflare Pages

<table><tr><td><strong>Latest commit:</strong> </td><td>
<code>1b6f052</code>
</td></tr>
<tr><td><strong>Status:</strong></td><td>⚡️&nbsp; Build in progress...</td></tr>
</table>

[View logs](https://dash.cloudflare.com/?to=/:account/pages/view/eslint-plugin-vue-i18n/d9c1ac1e-0b22-46a1-a936-ad9a7e6cf87f)


Patch:
diff --git a/.changeset/new-ligers-tan.md b/.changeset/new-ligers-tan.md
new file mode 100644
index 0000000..393c531
--- /dev/null
+++ b/.changeset/new-ligers-tan.md
@@ -0,0 +1,5 @@
+---
+"@intlify/eslint-plugin-vue-i18n": major
+---
+
+fix(deps): update dependency @intlify/message-compiler to v10
diff --git a/.changeset/old-islands-admire.md b/.changeset/old-islands-admire.md
new file mode 100644
index 0000000..7aee643
--- /dev/null
+++ b/.changeset/old-islands-admire.md
@@ -0,0 +1,5 @@
+---
+"@intlify/eslint-plugin-vue-i18n": major
+---
+
+ feat!: update config
diff --git a/lib/rules/no-deprecated-modulo-syntax.ts b/lib/rules/no-deprecated-modulo-syntax.ts
index 59e237f..3e5e56c 100644
--- a/lib/rules/no-deprecated-modulo-syntax.ts
+++ b/lib/rules/no-deprecated-modulo-syntax.ts
@@ -13,7 +13,7 @@ import {
   getMessageSyntaxVersions,
   NodeTypes
 } from '../utils/message-compiler/utils'
-import { parse } from '../utils/message-compiler/parser'
+import { parse } from '../utils/message-compiler/parser-v9'
 import { traverseNode } from '../utils/message-compiler/traverser'
 import {
   createRule,
@@ -75,8 +75,6 @@ function create(context: RuleContext): RuleListener {
     }
     if (messageSyntaxVersions.v9) {
       verifyForV9(message, reportNode, getReportOffset)
-    } else if (messageSyntaxVersions.v8) {
-      return
     }
   }
 
diff --git a/lib/rules/no-deprecated-v-t.ts b/lib/rules/no-deprecated-v-t.ts
index f34fae9..9485a30 100644
--- a/lib/rules/no-deprecated-v-t.ts
+++ b/lib/rules/no-deprecated-v-t.ts
@@ -34,7 +34,7 @@ export = createRule({
         'disallow using deprecated `v-t` custom directive (Deprecated in Vue I18n 11.0.0, removed fully in Vue I18n 12.0.0)',
       category: 'Recommended',
       url: 'https://eslint-plugin-vue-i18n.intlify.dev/rules/no-deprecated-v-t.html',
-      recommended: false
+      recommended: true
     },
     fixable: null,
     schema: []
diff --git a/lib/rules/prefer-linked-key-with-paren.ts b/lib/rules/prefer-linked-key-with-paren.ts
index b22685f..4ca8d7f 100644
--- a/lib/rules/prefer-linked-key-with-paren.ts
+++ b/lib/rules/prefer-linked-key-with-paren.ts
@@ -42,7 +42,7 @@ function create(context: RuleContext): RuleListener {
   const sourceCode = getSourceCode(context)
   const messageSyntaxVersions = getMessageSyntaxVersions(context)
 
-  function verifyForV9(
+  function verifyForNewSyntax(
     message: string,
     reportNode: JSONAST.JSONStringLiteral | YAMLAST.YAMLScalar,
     getReportOffset: GetReportOffset
@@ -134,14 +134,16 @@ function create(context: RuleContext): RuleListener {
     if (messageSyntaxVersions.reportIfMissingSetting()) {
       return
     }
-    if (messageSyntaxVersions.v9 && messageSyntaxVersions.v8) {
+    const newSyntax = messageSyntaxVersions.v9 || messageSyntaxVersions.v10
+    const v8Syntax = messageSyntaxVersions.v8
+    if (newSyntax && v8Syntax) {
       // This rule cannot support two versions in the same project.
       return
     }
 
-    if (messageSyntaxVersions.v9) {
-      verifyForV9(message, reportNode, getReportOffset)
-    } else if (messageSyntaxVersions.v8) {
+    if (newSyntax) {
+      verifyForNewSyntax(message, reportNode, getReportOffset)
+    } else if (v8Syntax) {
       verifyForV8(message, reportNode, getReportOffset)
     }
   }
diff --git a/lib/rules/valid-message-syntax.ts b/lib/rules/valid-message-syntax.ts
index f64a5ef..e7b5f4a 100644
--- a/lib/rules/valid-message-syntax.ts
+++ b/lib/rules/valid-message-syntax.ts
@@ -14,6 +14,7 @@ import {
   getReportIndex
 } from '../utils/message-compiler/utils'
 import { parse } from '../utils/message-compiler/parser'
+import { parse as parseForV9 } from '../utils/message-compiler/parser-v9'
 import { parse as parseForV8 } from '../utils/message-compiler/parser-v8'
 import type { CompileError } from '@intlify/message-compiler'
 import { createRule } from '../utils/rule'
@@ -27,9 +28,16 @@ function create(context: RuleContext): RuleListener {
   const messageSyntaxVersions = getMessageSyntaxVersions(context)
 
   function* extractMessageErrors(message: string) {
-    if (messageSyntaxVersions.v9) {
-      yield* parse(message).errors
+    // v10 and v9 generate nearly identical errors so only one of them will be returned.
+    const errorsForV10OrV9: CompileError[] = []
+    if (messageSyntaxVersions.v10) {
+      errorsForV10OrV9.push(...parse(message).errors)
     }
+    if (messageSyntaxVersions.v9 && !errorsForV10OrV9.length) {
+      errorsForV10OrV9.push(...parseForV9(message).errors)
+    }
+    yield* errorsForV10OrV9
+
     if (messageSyntaxVersions.v8) {
       yield* parseForV8(message).errors
     }
diff --git a/lib/utils/collect-linked-keys.ts b/lib/utils/collect-linked-keys.ts
index 9221dee..82fb75a 100644
--- a/lib/utils/collect-linked-keys.ts
+++ b/lib/utils/collect-linked-keys.ts
@@ -6,6 +6,7 @@ import type { ResourceNode } from '@intlify/message-compiler'
 import { traverseNode } from './message-compiler/traverser'
 import type { I18nLocaleMessageDictionary, RuleContext } from '../types'
 import { parse } from './message-compiler/parser'
+import { parse as parseForV9 } from './message-compiler/parser-v9'
 import { parse as parseForV8 } from './message-compiler/parser-v8'
 import type { MessageSyntaxVersions } from './message-compiler/utils'
 import { NodeTypes } from './message-compiler/utils'
@@ -27,9 +28,12 @@ function* extractUsedKeysFromLinks(
     if (typeof value === 'object') {
       yield* extractUsedKeysFromLinks(value, messageSyntaxVersions)
     } else if (typeof value === 'string') {
-      if (messageSyntaxVersions.v9) {
+      if (messageSyntaxVersions.v10) {
         yield* extractUsedKeysFromAST(parse(value).ast)
       }
+      if (messageSyntaxVersions.v9) {
+        yield* extractUsedKeysFromAST(parseForV9(value).ast)
+      }
       if (messageSyntaxVersions.v8) {
         yield* extractUsedKeysFromAST(parseForV8(value).ast)
       }
diff --git a/lib/utils/message-compiler/parser-v8.ts b/lib/utils/message-compiler/parser-v8.ts
index 100cc62..bce8627 100644
--- a/lib/utils/message-compiler/parser-v8.ts
+++ b/lib/utils/message-compiler/parser-v8.ts
@@ -17,6 +17,7 @@ import type {
 } from '@intlify/message-compiler'
 import { sortedLastIndex } from 'lodash'
 import { NodeTypes } from './utils'
+import type { ModuloNamedNode } from './parser-v9'
 
 export function parse(code: string): {
   ast: ResourceNode
@@ -207,7 +208,7 @@ function parseAST(code: string, errors: CompileError[]): ResourceNode {
           node = listNode
         }
         if (!node) {
-          const namedNode: NamedNode = {
+          const namedNode: ModuloNamedNode = {
             type: NodeTypes.Named,
             key: trimmedKeyValue,
             ...ctx.getNodeLoc(endOffset - 1, placeholderEndOffset)
diff --git a/lib/utils/message-compiler/parser-v9.ts b/lib/utils/message-compiler/parser-v9.ts
new file mode 100644
index 0000000..68f1ea6
--- /dev/null
+++ b/lib/utils/message-compiler/parser-v9.ts
@@ -0,0 +1,59 @@
+/**
+ * A simplified version of the message parser that handles messages like vue-i18n v8.
+ * This parser probably has poor performance.
+ */
+import type {
+  CompileError,
+  NamedNode,
+  ResourceNode
+} from '@intlify/message-compiler'
+import { NodeTypes } from './utils'
+import { parse as baseParse } from './parser'
+import type { MessageElementNode } from './traverser'
+import { traverseNode } from './traverser'
+
+// The deprecated Rails i18n format.
+export type ModuloNamedNode = NamedNode & { modulo?: boolean }
+
+export function parse(code: string): {
+  ast: ResourceNode
+  errors: CompileError[]
+} {
+  const { ast, errors } = baseParse(code)
+
+  traverseNode(ast, node => {
+    if (node.type === NodeTypes.Message) {
+      transformModuloNamedNode(node.items)
+    }
+  })
+  return {
+    ast,
+    errors
+  }
+
+  function transformModuloNamedNode(nodes: MessageElementNode[]) {
+    // Converts nodes with a '%' before the brackets into modulo nodes.
+    for (let index = nodes.length - 1; index >= 1; index--) {
+      const node = nodes[index]
+      if (
+        node.type !== NodeTypes.Named ||
+        code[node.loc!.start.offset - 1] !== '%'
+      )
+        continue
+
+      const prev = nodes[index - 1]
+      if (prev.type !== NodeTypes.Text || !prev.value?.endsWith('%')) continue
+
+      node.modulo = true
+
+      prev.loc!.end.offset -= 1
+      prev.loc!.end.column -= 1
+      prev.end! -= 1
+      prev.value = prev.value!.slice(0, -1)
+      if (prev.start === prev.end) {
+        nodes.splice(index - 1, 1)
+        index--
+      }
+    }
+  }
+}
diff --git a/lib/utils/message-compiler/traverser.ts b/lib/utils/message-compiler/traverser.ts
index 84ee1ab..360d558 100644
--- a/lib/utils/message-compiler/traverser.ts
+++ b/lib/utils/message-compiler/traverser.ts
@@ -11,13 +11,15 @@ import type {
   TextNode
 } from '@intlify/message-compiler'
 import { NodeTypes } from './utils'
+import type { ModuloNamedNode } from './parser-v9'
 
-type MessageElementNode =
+export type MessageElementNode =
   | TextNode
   | NamedNode
   | ListNode
   | LiteralNode
   | LinkedNode
+  | ModuloNamedNode
 type MessageASTNode =
   | ResourceNode
   | PluralNode
diff --git a/lib/utils/message-compiler/utils.ts b/lib/utils/message-compiler/utils.ts
index e2bdfa1..24a7e56 100644
--- a/lib/utils/message-compiler/utils.ts
+++ b/lib/utils/message-compiler/utils.ts
@@ -19,6 +19,7 @@ export const NodeTypes = {
 export type MessageSyntaxVersions = {
   v8: boolean
   v9: boolean
+  v10: boolean
   isNotSet: boolean
   reportIfMissingSetting: () => boolean
 }
@@ -37,6 +38,7 @@ export function getMessageSyntaxVersions(
     return {
       v8: true,
       v9: true,
+      v10: true,
       isNotSet: true,
       reportIfMissingSetting: () => {
         if (!puttedSettingsError.has(context)) {
@@ -54,7 +56,8 @@ export function getMessageSyntaxVersions(
   const range = new Range(messageSyntaxVersion)
   return {
     v8: intersects(range, '^8.0.0 || <=8.0.0'),
-    v9: intersects(range, '>=9.0.0-0'),
+    v9: intersects(range, '^9.0.0-0'),
+    v10: intersects(range, '>=10.0.0-0'),
     isNotSet: false,
     reportIfMissingSetting: () => false
   }
diff --git a/package.json b/package.json
index 6851f0d..9ea3af5 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
   "engines": {
     "node": ">=18.0.0"
   },
-  "packageManager": "pnpm@9.14.4",
+  "packageManager": "pnpm@9.15.0",
   "type": "commonjs",
   "files": [
     "dist"
@@ -61,7 +61,7 @@
   "dependencies": {
     "@eslint/eslintrc": "^3.0.0",
     "@intlify/core-base": "^10.0.0",
-    "@intlify/message-compiler": "^9.12.0",
+    "@intlify/message-compiler": "^10.0.5",
     "debug": "^4.3.4",
     "eslint-compat-utils": "^0.6.0",
     "glob": "^10.3.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4a3d35e..d751c78 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,8 +15,8 @@ importers:
         specifier: ^10.0.0
         version: 10.0.5
       '@intlify/message-compiler':
-        specifier: ^9.12.0
-        version: 9.12.0
+        specifier: ^10.0.5
+        version: 10.0.5
       debug:
         specifier: ^4.3.4
         version: 4.3.4
@@ -654,18 +654,10 @@ packages:
     resolution: {integrity: sha512-6GT1BJ852gZ0gItNZN2krX5QAmea+cmdjMvsWohArAZ3GmHdnNANEcF9JjPXAMRtQ6Ux5E269ymamg/+WU6tQA==}
     engines: {node: '>= 16'}
 
-  '@intlify/message-compiler@9.12.0':
-    resolution: {integrity: sha512-2c6VwhvVJ1nur+2cN2NjdrmrV6vXjvyxYVvtUYMXKsWSUwoNURHGds0xJVJmWxbF8qV9oGepcVV6xl9bvadEIg==}
-    engines: {node: '>= 16'}
-
   '@intlify/shared@10.0.5':
     resolution: {integrity: sha512-bmsP4L2HqBF6i6uaMqJMcFBONVjKt+siGluRq4Ca4C0q7W2eMaVZr8iCgF9dKbcVXutftkC7D6z2SaSMmLiDyA==}
     engines: {node: '>= 16'}
 
-  '@intlify/shared@9.12.0':
-    resolution: {integrity: sha512-uBcH55x5CfZynnerWHQxrXbT6yD6j6T7Nt+R2+dHAOAneoMd6BoGvfEzfYscE94rgmjoDqdr+PdGDBLk5I5EjA==}
-    engines: {node: '>= 16'}
-
   '@isaacs/cliui@8.0.2':
     resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
     engines: {node: '>=12'}
@@ -2791,10 +2783,6 @@ packages:
     engines: {node: '>=6'}
     hasBin: true
 
-  source-map-js@1.2.0:
-    resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
-    engines: {node: '>=0.10.0'}
-
   source-map-js@1.2.1:
     resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
     engines: {node: '>=0.10.0'}
@@ -3857,15 +3845,8 @@ snapshots:
       '@intlify/shared': 10.0.5
       source-map-js: 1.2.1
 
-  '@intlify/message-compiler@9.12.0':
-    dependencies:
-      '@intlify/shared': 9.12.0
-      source-map-js: 1.2.0
-
   '@intlify/shared@10.0.5': {}
 
-  '@intlify/shared@9.12.0': {}
-
   '@isaacs/cliui@8.0.2':
     dependencies:
       string-width: 5.1.2
@@ -6112,8 +6093,6 @@ snapshots:
       wcwidth: 1.0.1
       yargs: 15.4.1
 
-  source-map-js@1.2.0: {}
-
   source-map-js@1.2.1: {}
 
   source-map@0.6.1: {}


Test patch:
diff --git a/tests/lib/rules/no-deprecated-modulo-syntax.ts b/tests/lib/rules/no-deprecated-modulo-syntax.ts
index 448d0b9..bc4fae5 100644
--- a/tests/lib/rules/no-deprecated-modulo-syntax.ts
+++ b/tests/lib/rules/no-deprecated-modulo-syntax.ts
@@ -18,7 +18,7 @@ const tester = new RuleTester({
   languageOptions: { parser: vueParser, ecmaVersion: 2015 }
 })
 
-tester.run('no-deprecated-module-syntax', rule as never, {
+tester.run('no-deprecated-modulo-syntax', rule as never, {
   valid: [
     // text only
     {
diff --git a/tests/lib/rules/valid-message-syntax.ts b/tests/lib/rules/valid-message-syntax.ts
index 40c7da5..4b1195f 100644
--- a/tests/lib/rules/valid-message-syntax.ts
+++ b/tests/lib/rules/valid-message-syntax.ts
@@ -223,24 +223,25 @@ tester.run('valid-message-syntax', rule as never, {
         }
       ]
     },
-    {
-      code: `
-      key: message @:(v8)
-      `,
-      ...options.yaml.default,
-      errors: [
-        {
-          message: `If you want to use '${TEST_RULE_ID_PREFIX}valid-message-syntax' rule, you need to set 'messageSyntaxVersion' at 'settings'. See the 'eslint-plugin-vue-i18n' documentation`,
-          line: 1,
-          column: 1
-        },
-        {
-          message: 'Unexpected empty linked key',
-          line: 2,
-          column: 21
-        }
-      ]
-    },
+    // {
+    //   // The syntax is now allowed.
+    //   code: `
+    //   key: message @:(v8)
+    //   `,
+    //   ...options.yaml.default,
+    //   errors: [
+    //     {
+    //       message: `If you want to use '${TEST_RULE_ID_PREFIX}valid-message-syntax' rule, you need to set 'messageSyntaxVersion' at 'settings'. See the 'eslint-plugin-vue-i18n' documentation`,
+    //       line: 1,
+    //       column: 1
+    //     },
+    //     {
+    //       message: 'Unexpected empty linked key',
+    //       line: 2,
+    //       column: 21
+    //     }
+    //   ]
+    // },
     {
       code: `
       key: message { v9 }
@@ -272,61 +273,65 @@ tester.run('valid-message-syntax', rule as never, {
         }
       ]
     },
-    {
-      code: `
-      key: message @:(v8)
-      `,
-      ...options.yaml.v9,
-      errors: [
-        {
-          message: 'Unexpected empty linked key',
-          line: 2,
-          column: 21
-        }
-      ]
-    },
-    {
-      code: `
-      key: message new line
-        @:(v8)
-      `,
-      ...options.yaml.v9,
-      errors: [
-        {
-          message: 'Unexpected empty linked key',
-          line: 3,
-          column: 10
-        }
-      ]
-    },
-    {
-      code: `
-      key: "message new line
-        @:(v8)"
-      `,
-      ...options.yaml.v9,
-      errors: [
-        {
-          message: 'Unexpected empty linked key',
-          line: 3,
-          column: 10
-        }
-      ]
-    },
-    {
-      code: `
-      key: 'message new line
-        @:(v8)'
-      `,
-      ...options.yaml.v9,
-      errors: [
-        {
-          message: 'Unexpected empty linked key',
-          line: 3,
-          column: 10
-        }
-      ]
-    },
+    // {
+    //   // The syntax is now allowed.
+    //   code: `
+    //   key: message @:(v8)
+    //   `,
+    //   ...options.yaml.v9,
+    //   errors: [
+    //     {
+    //       message: 'Unexpected empty linked key',
+    //       line: 2,
+    //       column: 21
+    //     }
+    //   ]
+    // },
+    // {
+    //   // The syntax is now allowed.
+    //   code: `
+    //   key: message new line
+    //     @:(v8)
+    //   `,
+    //   ...options.yaml.v9,
+    //   errors: [
+    //     {
+    //       message: 'Unexpected empty linked key',
+    //       line: 3,
+    //       column: 10
+    //     }
+    //   ]
+    // },
+    // {
+    //   // The syntax is now allowed.
+    //   code: `
+    //   key: "message new line
+    //     @:(v8)"
+    //   `,
+    //   ...options.yaml.v9,
+    //   errors: [
+    //     {
+    //       message: 'Unexpected empty linked key',
+    //       line: 3,
+    //       column: 10
+    //     }
+    //   ]
+    // },
+    // {
+    //   // The syntax is now allowed.
+    //   code: `
+    //   key: 'message new line
+    //     @:(v8)'
+    //   `,
+    //   ...options.yaml.v9,
+    //   errors: [
+    //     {
+    //       message: 'Unexpected empty linked key',
+    //       line: 3,
+    //       column: 10
+    //     }
+    //   ]
+    // },
     {
       code: `
       <i18n lang="yaml">
@@ -476,16 +481,6 @@ tester.run('valid-message-syntax', rule as never, {
           line: 3,
           column: 22
         },
-        {
-          message: 'Unterminated closing brace',
-          line: 4,
-          column: 27
-        },
-        {
-          message: 'Unbalanced closing brace',
-          line: 4,
-          column: 34
-        },
         {
           message: "Unexpected 'null' message",
           line: 5,
diff --git a/tests/lib/utils/message-compiler/parser-v8.ts b/tests/lib/utils/message-compiler/parser-v8.ts
index f117022..5505029 100644
--- a/tests/lib/utils/message-compiler/parser-v8.ts
+++ b/tests/lib/utils/message-compiler/parser-v8.ts
@@ -3,7 +3,7 @@
  */
 import { deepStrictEqual } from 'assert'
 import { parse } from '../../../../lib/utils/message-compiler/parser-v8'
-import { parse as parseForV9 } from '../../../../lib/utils/message-compiler/parser'
+import { parse as parseForV9 } from '../../../../lib/utils/message-compiler/parser-v9'
 import { errorsFixtures } from './parser-v8-data'
 
 describe('parser-v8', () => {
diff --git a/tests/lib/utils/message-compiler/utils.ts b/tests/lib/utils/message-compiler/utils.ts
index 44cefc0..071a449 100644
--- a/tests/lib/utils/message-compiler/utils.ts
+++ b/tests/lib/utils/message-compiler/utils.ts
@@ -21,31 +21,37 @@ describe('message-compiler utils', () => {
       deepStrictEqual(get('^8.0.0'), {
         v8: true,
         v9: false,
+        v10: false,
         isNotSet: false
       })
       deepStrictEqual(get('^9.0.0'), {
         v8: false,
         v9: true,
+        v10: false,
         isNotSet: false
       })
       deepStrictEqual(get('^7.0.0'), {
         v8: true,
         v9: false,
+        v10: false,
         isNotSet: false
       })
       deepStrictEqual(get('^10.0.0'), {
         v8: false,
-        v9: true,
+        v9: false,
+        v10: true,
         isNotSet: false
       })
       deepStrictEqual(get('>=5.0.0'), {
         v8: true,
         v9: true,
+        v10: true,
         isNotSet: false
       })
       deepStrictEqual(get('^9.0.0-beta.8'), {
         v8: false,
         v9: true,
+        v10: false,
         isNotSet: false
       })
     })