ikemoji 1.0.0

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.
Files changed (3) hide show
  1. package/README.md +46 -0
  2. package/index.js +95 -0
  3. package/package.json +26 -0
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # ikemoji
2
+
3
+ Telegram Bot API 9.4 – Custom Emoji Helper
4
+
5
+ - UTF-16 correct
6
+ - ZWJ / skin tone safe
7
+ - Length = 1 (Telegram requirement)
8
+ - Handles multiple consecutive emojis and variation selectors
9
+ - Telegraf compatible
10
+
11
+ ---
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install ikemoji
17
+
18
+ ## Usage
19
+
20
+ const { emo, emoEnt, findEmo, checkEnt, mergeEntities } = require('ikemoji');
21
+
22
+ const emojiMap = {
23
+ "😀": "5444871234567890123",
24
+ "🔥": "5444879876543210123"
25
+ };
26
+
27
+ // Build text + entities
28
+ const { text, entities } = emo("Hello 😀🔥", emojiMap);
29
+ console.log(text); // "Hello 😀🔥"
30
+ console.log(entities); // [{ type: 'custom_emoji', offset: 6, length: 1, custom_emoji_id: "..." }, ...]
31
+
32
+ // Extract entities only
33
+ const onlyEntities = emoEnt("Hello 😀🔥", emojiMap);
34
+ console.log(onlyEntities);
35
+
36
+ // Find all unique emojis
37
+ const unique = findEmo("Hello 😀🔥");
38
+ console.log(unique); // ["😀","🔥"]
39
+
40
+ // Validate entities
41
+ const { valid, errors } = checkEnt(entities);
42
+ console.log(valid, errors);
43
+
44
+ // Merge with other entities
45
+ const allEntities = mergeEntities(entities, [{ type: 'bold', offset: 0, length: 5 }]);
46
+ console.log(allEntities);
package/index.js ADDED
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Telegram Bot API 9.4 – Custom Emoji Helper
3
+ * Author: ikjava
4
+ * ✔ UTF-16 correct
5
+ * ✔ ZWJ / skin tone safe
6
+ * ✔ length = 1
7
+ * ✔ Handles multiple consecutive emojis and variation selectors
8
+ * ✔ Telegraf compatible
9
+ */
10
+
11
+ const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
12
+
13
+ function emo(text, emojiMap, options = {}) {
14
+ const { stripOriginal = false, skipUnmapped = true } = options;
15
+ const entities = [];
16
+ let out = '';
17
+ let offset = 0;
18
+
19
+ for (const { segment } of segmenter.segment(text)) {
20
+ const id = emojiMap[segment];
21
+
22
+ if (id) {
23
+ entities.push({ type: 'custom_emoji', offset, length: 1, custom_emoji_id: id });
24
+ if (!stripOriginal) {
25
+ out += segment;
26
+ offset += segment.length;
27
+ }
28
+ } else {
29
+ if (!skipUnmapped || isEmo(segment) === false) {
30
+ out += segment;
31
+ offset += segment.length;
32
+ }
33
+ }
34
+ }
35
+
36
+ return { text: out, entities };
37
+ }
38
+
39
+ function emoEnt(text, emojiMap) {
40
+ const entities = [];
41
+ let offset = 0;
42
+
43
+ for (const { segment } of segmenter.segment(text)) {
44
+ if (emojiMap[segment]) {
45
+ entities.push({ type: 'custom_emoji', offset, length: 1, custom_emoji_id: emojiMap[segment] });
46
+ }
47
+ offset += segment.length;
48
+ }
49
+
50
+ return entities;
51
+ }
52
+
53
+ function findEmo(text) {
54
+ const set = new Set();
55
+
56
+ for (const { segment } of segmenter.segment(text)) {
57
+ if (isEmo(segment)) set.add(segment);
58
+ }
59
+
60
+ return [...set];
61
+ }
62
+
63
+ function checkEnt(entities) {
64
+ const errors = [];
65
+
66
+ if (entities.length > 100) errors.push(`Too many entities (${entities.length})`);
67
+
68
+ entities.forEach((e, i) => {
69
+ if (e.type !== 'custom_emoji') errors.push(`Entity ${i}: invalid type`);
70
+ if (!e.custom_emoji_id) errors.push(`Entity ${i}: missing custom_emoji_id`);
71
+ if (e.length !== 1) errors.push(`Entity ${i}: length must be 1`);
72
+ if (typeof e.offset !== 'number' || e.offset < 0) errors.push(`Entity ${i}: invalid offset`);
73
+ });
74
+
75
+ return { valid: errors.length === 0, errors };
76
+ }
77
+
78
+ function isEmo(str) {
79
+ return /\p{Extended_Pictographic}/u.test(str);
80
+ }
81
+
82
+ function mergeEntities(baseEntities, newEntities) {
83
+ const all = [...baseEntities, ...newEntities];
84
+ all.sort((a, b) => a.offset - b.offset);
85
+ return all;
86
+ }
87
+
88
+ module.exports = {
89
+ emo,
90
+ emoEnt,
91
+ findEmo,
92
+ checkEnt,
93
+ isEmo,
94
+ mergeEntities
95
+ };
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "ikemoji",
3
+ "version": "1.0.0",
4
+ "description": "Telegram Bot API 9.4 custom emoji helper - UTF-16 correct, ZWJ/skin tone safe, Telegraf compatible",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "node test.js"
8
+ },
9
+ "keywords": [
10
+ "telegram",
11
+ "bot",
12
+ "custom",
13
+ "emoji",
14
+ "telegram-bot-api",
15
+ "telegraf",
16
+ "caption",
17
+ "9.4"
18
+ ],
19
+ "author": "Saul ikjava",
20
+ "license": "MIT",
21
+ "engines": {
22
+ "node": ">=16"
23
+ },
24
+ "dependencies": {},
25
+ "devDependencies": {}
26
+ }