From 3fff0952f489c191ac6294da8e94728fa8e4d630 Mon Sep 17 00:00:00 2001 From: waynzh <waynzh19@gmail.com> Date: Sun, 6 Apr 2025 23:04:33 +0800 Subject: [PATCH 1/2] feat(no-bare-strings-in-template): allowlist support regex --- docs/rules/no-bare-strings-in-template.md | 6 +- lib/rules/no-bare-strings-in-template.js | 48 ++++++++++++--- .../lib/rules/no-bare-strings-in-template.js | 60 +++++++++++++++++++ 3 files changed, 102 insertions(+), 12 deletions(-) diff --git a/docs/rules/no-bare-strings-in-template.md b/docs/rules/no-bare-strings-in-template.md index df1fae123..b8ddc3e58 100644 --- a/docs/rules/no-bare-strings-in-template.md +++ b/docs/rules/no-bare-strings-in-template.md @@ -12,7 +12,7 @@ since: v7.0.0 ## :book: Rule Details -This rule disallows the use of bare strings in `<template>`. +This rule disallows the use of bare strings in `<template>`. In order to be able to internationalize your application, you will need to avoid using plain strings in your templates. Instead, you would need to use a template helper specializing in translation. This rule was inspired by [no-bare-strings rule in ember-template-lint](https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rule/no-bare-strings.md). @@ -50,7 +50,7 @@ This rule was inspired by [no-bare-strings rule in ember-template-lint](https:// </eslint-code-block> :::tip -This rule does not check for string literals, in bindings and mustaches interpolation. This is because it looks like a conscious decision. +This rule does not check for string literals, in bindings and mustaches interpolation. This is because it looks like a conscious decision. If you want to report these string literals, enable the [vue/no-useless-v-bind] and [vue/no-useless-mustaches] rules and fix the useless string literals. ::: @@ -72,7 +72,7 @@ If you want to report these string literals, enable the [vue/no-useless-v-bind] } ``` -- `allowlist` ... An array of allowed strings. +- `allowlist` ... An array of allowed strings or regular expression patterns (e.g. `/\d+/` to allow number). - `attributes` ... An object whose keys are tag name or patterns and value is an array of attributes to check for that tag name. - `directives` ... An array of directive names to check literal value. diff --git a/lib/rules/no-bare-strings-in-template.js b/lib/rules/no-bare-strings-in-template.js index 1c75f5092..8e4acc96d 100644 --- a/lib/rules/no-bare-strings-in-template.js +++ b/lib/rules/no-bare-strings-in-template.js @@ -149,17 +149,33 @@ module.exports = { */ const opts = context.options[0] || {} /** @type {string[]} */ - const allowlist = opts.allowlist || DEFAULT_ALLOWLIST + const rawAllowlist = opts.allowlist || DEFAULT_ALLOWLIST const attributes = parseTargetAttrs(opts.attributes || DEFAULT_ATTRIBUTES) const directives = opts.directives || DEFAULT_DIRECTIVES - const allowlistRe = new RegExp( - allowlist - .map((w) => regexp.escape(w)) - .sort((a, b) => b.length - a.length) - .join('|'), - 'gu' - ) + /** @type {string[]} */ + const stringAllowlist = [] + /** @type {RegExp[]} */ + const regexAllowlist = [] + + for (const item of rawAllowlist) { + if (regexp.isRegExp(item)) { + regexAllowlist.push(regexp.toRegExp(item)) + } else { + stringAllowlist.push(item) + } + } + + const allowlistRe = + stringAllowlist.length > 0 + ? new RegExp( + stringAllowlist + .map((w) => regexp.escape(w)) + .sort((a, b) => b.length - a.length) + .join('|'), + 'gu' + ) + : null /** @type {ElementStack | null} */ let elementStack = null @@ -168,7 +184,21 @@ module.exports = { * @param {string} str */ function getBareString(str) { - return str.trim().replace(allowlistRe, '').trim() + let result = str.trim() + + if (allowlistRe) { + result = result.replace(allowlistRe, '') + } + + for (const regex of regexAllowlist) { + const flags = regex.flags.includes('g') + ? regex.flags + : `${regex.flags}g` + const globalRegex = new RegExp(regex.source, flags) + result = result.replace(globalRegex, '') + } + + return result.trim() } /** diff --git a/tests/lib/rules/no-bare-strings-in-template.js b/tests/lib/rules/no-bare-strings-in-template.js index 4c6c89c7c..6706aaae0 100644 --- a/tests/lib/rules/no-bare-strings-in-template.js +++ b/tests/lib/rules/no-bare-strings-in-template.js @@ -132,6 +132,32 @@ tester.run('no-bare-strings-in-template', rule, { </template> `, options: [{ allowlist: ['@@'] }] + }, + // regex + { + code: ` + <template> + <h1>123 321</h1> + </template> + `, + options: [{ allowlist: [String.raw`/\d+/g`] }] + }, + { + code: ` + <template> + <h1>$foo</h1> + <h1>$bar</h1> + </template> + `, + options: [{ allowlist: [String.raw`/\$\w+/`] }] + }, + { + code: ` + <template> + <h1>foo123foo</h1> + </template> + `, + options: [{ allowlist: [String.raw`/\d+/`, 'foo'] }] } ], invalid: [ @@ -316,6 +342,40 @@ tester.run('no-bare-strings-in-template', rule, { endColumn: 34 } ] + }, + { + code: ` + <template> + <h1>123, foo is invalid, 321</h1> + </template> + `, + options: [{ allowlist: [String.raw`/^\d+$/g`] }], + errors: [ + { + messageId: 'unexpected', + line: 3, + column: 13, + endLine: 3, + endColumn: 37 + } + ] + }, + { + code: ` + <template> + <h1>foo123bar</h1> + </template> + `, + options: [{ allowlist: [String.raw`/\d+/`, 'foo'] }], + errors: [ + { + messageId: 'unexpected', + line: 3, + column: 13, + endLine: 3, + endColumn: 22 + } + ] } ] }) From d97bab696f0567ee747c270b74d187c5efe2c419 Mon Sep 17 00:00:00 2001 From: Wayne Zhang <waynzh19@gmail.com> Date: Mon, 14 Apr 2025 19:12:15 +0800 Subject: [PATCH 2/2] Update docs/rules/no-bare-strings-in-template.md Co-authored-by: Flo Edelmann <git@flo-edelmann.de> --- docs/rules/no-bare-strings-in-template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-bare-strings-in-template.md b/docs/rules/no-bare-strings-in-template.md index b8ddc3e58..23a23c116 100644 --- a/docs/rules/no-bare-strings-in-template.md +++ b/docs/rules/no-bare-strings-in-template.md @@ -72,7 +72,7 @@ If you want to report these string literals, enable the [vue/no-useless-v-bind] } ``` -- `allowlist` ... An array of allowed strings or regular expression patterns (e.g. `/\d+/` to allow number). +- `allowlist` ... An array of allowed strings or regular expression patterns (e.g. `/\d+/` to allow numbers). - `attributes` ... An object whose keys are tag name or patterns and value is an array of attributes to check for that tag name. - `directives` ... An array of directive names to check literal value.