eslint-plugin-formatjs 6.1.0 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/emoji-utils.d.ts CHANGED
@@ -5,7 +5,9 @@ import { type EmojiVersion } from "./emoji-data.generated.js";
5
5
  export type { EmojiVersion } from "./emoji-data.generated.js";
6
6
  /**
7
7
  * Check if a string contains any emoji
8
- * Uses Unicode \p{Emoji} property which covers all emoji
8
+ * Uses Unicode 17.0.0 Emoji_Presentation data and variation selector (U+FE0F)
9
+ * to properly detect emoji while avoiding false positives from characters like
10
+ * #, *, digits 0-9, and text symbols like © which have \p{Emoji} but are not visual emoji
9
11
  */
10
12
  export declare function hasEmoji(text: string): boolean;
11
13
  /**
package/emoji-utils.js CHANGED
@@ -2,19 +2,51 @@
2
2
  * Emoji detection utilities using Intl.Segmenter
3
3
  */
4
4
  import { EMOJI_VERSIONS, EMOJI_RANGES } from "./emoji-data.generated.js";
5
+ import * as emojiPresentationRegex from "@unicode/unicode-17.0.0/Binary_Property/Emoji_Presentation/regex.js";
6
+ import * as emojiPropertyRegex from "@unicode/unicode-17.0.0/Binary_Property/Emoji/regex.js";
5
7
  /**
6
8
  * Cached Intl.Segmenter instance for emoji extraction
7
9
  * Reused across all extractEmojis calls for better performance
8
10
  */
9
11
  const graphemeSegmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
10
12
  /**
13
+ * Regex for detecting emoji using Unicode 17.0.0 Emoji_Presentation data
14
+ * Generated from @unicode/unicode-17.0.0/Binary_Property/Emoji_Presentation
15
+ * This avoids false positives from #, *, digits, and text symbols like ©
16
+ */
17
+ const emojiPresentationRegexCompiled = emojiPresentationRegex.default ?? emojiPresentationRegex;
18
+ /**
19
+ * Regex for detecting emoji-capable characters using Unicode 17.0.0 Emoji property
20
+ * This includes characters that can have emoji presentation (like ❤, ☀)
21
+ */
22
+ const emojiPropertyRegexCompiled = emojiPropertyRegex.default ?? emojiPropertyRegex;
23
+ /**
11
24
  * Check if a string contains any emoji
12
- * Uses Unicode \p{Emoji} property which covers all emoji
25
+ * Uses Unicode 17.0.0 Emoji_Presentation data and variation selector (U+FE0F)
26
+ * to properly detect emoji while avoiding false positives from characters like
27
+ * #, *, digits 0-9, and text symbols like © which have \p{Emoji} but are not visual emoji
13
28
  */
14
29
  export function hasEmoji(text) {
15
- // Use \p{Emoji} to match emoji characters
16
- // This includes all emoji, both text and emoji presentation
17
- return /\p{Emoji}/u.test(text);
30
+ // First check for Emoji_Presentation characters (always displayed as emoji)
31
+ if (emojiPresentationRegexCompiled.test(text)) {
32
+ return true;
33
+ }
34
+ // Check for variation selector (U+FE0F) which indicates emoji presentation
35
+ // But only if it follows an emoji-capable character to avoid false positives
36
+ // like "Hello\uFE0F" or "A\uFE0F"
37
+ if (text.includes("️")) {
38
+ const segments = graphemeSegmenter.segment(text);
39
+ for (const { segment } of segments) {
40
+ if (segment.includes("️")) {
41
+ // Has VS, check if the character before it has the Emoji property
42
+ const beforeVS = segment.replace(/\uFE0F/g, "");
43
+ if (emojiPropertyRegexCompiled.test(beforeVS)) {
44
+ return true;
45
+ }
46
+ }
47
+ }
48
+ }
49
+ return false;
18
50
  }
19
51
  /**
20
52
  * Extract all emoji from a string using Intl.Segmenter
@@ -32,8 +64,18 @@ export function extractEmojis(text) {
32
64
  const emojis = [];
33
65
  for (const { segment } of segments) {
34
66
  // Check if this grapheme cluster contains emoji
35
- if (/\p{Emoji}/u.test(segment)) {
67
+ // First check for Emoji_Presentation (always displayed as emoji)
68
+ if (emojiPresentationRegexCompiled.test(segment)) {
36
69
  emojis.push(segment);
70
+ continue;
71
+ }
72
+ // Check for variation selector (U+FE0F) which indicates emoji presentation
73
+ // But only if it follows an emoji-capable character to avoid false positives
74
+ if (segment.includes("️")) {
75
+ const beforeVS = segment.replace(/\uFE0F/g, "");
76
+ if (emojiPropertyRegexCompiled.test(beforeVS)) {
77
+ emojis.push(segment);
78
+ }
37
79
  }
38
80
  }
39
81
  return emojis;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-formatjs",
3
3
  "description": "ESLint plugin for formatjs",
4
- "version": "6.1.0",
4
+ "version": "6.1.1",
5
5
  "license": "MIT",
6
6
  "author": "Long Ho <holevietlong@gmail.com>",
7
7
  "type": "module",
@@ -9,11 +9,12 @@
9
9
  "dependencies": {
10
10
  "@types/picomatch": "^4.0.0",
11
11
  "@typescript-eslint/utils": "^8.52.0",
12
+ "@unicode/unicode-17.0.0": "^1.6.16",
12
13
  "magic-string": "^0.30.0",
13
14
  "picomatch": "2 || 3 || 4",
14
15
  "tslib": "^2.8.1",
15
- "@formatjs/icu-messageformat-parser": "3.4.0",
16
- "@formatjs/ts-transformer": "4.3.0"
16
+ "@formatjs/icu-messageformat-parser": "3.5.0",
17
+ "@formatjs/ts-transformer": "4.3.1"
17
18
  },
18
19
  "peerDependencies": {
19
20
  "eslint": "9"