medias-fakerator 1.0.0-dra → 1.0.0-dra.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.
Binary file
Binary file
Binary file
@@ -2,12 +2,31 @@ const fs = require("fs");
2
2
  const path = require("path");
3
3
  const runes = require("runes");
4
4
  const sharp = require("sharp");
5
- const EmojiDbLib = require("emoji-db");
6
5
  const { LRUCache } = require("lru-cache");
7
- const emojiDb = new EmojiDbLib({ useDefaultDb: true });
8
6
  const emojiImageByBrandPromise = require("emoji-cache");
9
7
  const ALLOWED_MEDIA_DIRECTORY = path.resolve(__dirname, "../");
10
8
  const { createCanvas, loadImage, registerFont } = require("canvas");
9
+ const emoji = require("node-emoji");
10
+ const emojiRegex =
11
+ /(\p{Extended_Pictographic}(?:\u200d\p{Extended_Pictographic})*)/gu;
12
+
13
+ function searchEmojiFromText(text) {
14
+ const results = [];
15
+ let match;
16
+
17
+ while ((match = emojiRegex.exec(text)) !== null) {
18
+ const emojiChar = match[0];
19
+
20
+ results.push({
21
+ emoji: emojiChar, // emoji unicode
22
+ found: emojiChar, // key untuk emoji-cache
23
+ offset: match.index,
24
+ length: emojiChar.length,
25
+ });
26
+ }
27
+
28
+ return results;
29
+ }
11
30
 
12
31
  async function loadFont() {
13
32
  const fontsDir = path.join(__dirname, "../assets/fonts");
@@ -338,10 +357,8 @@ class QuoteGenerate {
338
357
  for (let i = 0; i < charStyles.length; i++) charStyles[i].push(entities);
339
358
  }
340
359
  const styledWords = [];
341
- const emojiData = emojiDb.searchFromText({
342
- input: text,
343
- fixCodePoints: true,
344
- });
360
+ const emojiData = searchEmojiFromText(text);
361
+
345
362
  let currentIndex = 0;
346
363
  const processPlainText = (plainText, startOffset) => {
347
364
  if (!plainText) return;
@@ -540,10 +557,8 @@ class QuoteGenerate {
540
557
  }
541
558
  }
542
559
  const styledWords = [];
543
- const emojiData = emojiDb.searchFromText({
544
- input: text,
545
- fixCodePoints: true,
546
- });
560
+ const emojiData = searchEmojiFromText(text);
561
+
547
562
  let currentIndex = 0;
548
563
  const processPlainText = (plainText, startOffset) => {
549
564
  if (!plainText) return;
package/lib/utils.js CHANGED
@@ -1,66 +1,115 @@
1
- const EmojiDbLib = require('emoji-db');
1
+ const emojiRegex =
2
+ /(\p{Extended_Pictographic}(?:\u200d\p{Extended_Pictographic})*)/gu;
2
3
 
3
- let emojiDb;
4
- try {
5
- emojiDb = new EmojiDbLib({ useDefaultDb: true });
6
- if (!emojiDb || typeof emojiDb.searchFromText !== 'function') throw new Error('Gagal menginisialisasi database emoji');
7
- } catch (error) {
8
- console.error('Error saat inisialisasi database emoji:', error);
9
- throw error;
4
+ function searchEmojiFromText(text) {
5
+ const results = [];
6
+ let match;
7
+
8
+ while ((match = emojiRegex.exec(text)) !== null) {
9
+ const emojiChar = match[0];
10
+ results.push({
11
+ found: emojiChar,
12
+ emoji: emojiChar,
13
+ offset: match.index,
14
+ length: emojiChar.length,
15
+ });
16
+ }
17
+
18
+ return results;
10
19
  }
11
20
 
12
21
  function parseTextToSegments(text, ctx, fontSize) {
13
22
  try {
14
- if (typeof text !== 'string') text = String(text);
15
- if (!ctx || typeof ctx.measureText !== 'function') throw new TypeError('Invalid canvas context');
23
+ if (typeof text !== "string") text = String(text);
24
+ if (!ctx || typeof ctx.measureText !== "function")
25
+ throw new TypeError("Invalid canvas context");
16
26
  const finalSegments = [];
17
- const rawLines = text.split('\n');
27
+ const rawLines = text.split("\n");
18
28
  rawLines.forEach((line, index) => {
19
- if (line === '') {
29
+ if (line === "") {
20
30
  } else {
21
31
  const segmentsInLine = [];
22
- const emojiMatches = emojiDb.searchFromText({ input: line, fixCodePoints: true });
32
+ const emojiMatches = searchEmojiFromText(line);
33
+
23
34
  let lastIndex = 0;
24
35
  const processChunk = (chunk) => {
25
36
  if (!chunk) return;
26
- const tokenizerRegex = /(\*_.*?_\*|_\*.*?\*_)|(\*.*?\*)|(_.*?_)|(~.*?~)|(```.*?```)|(\s+)|([^\s*~_`]+)/g;
37
+ const tokenizerRegex =
38
+ /(\*_.*?_\*|_\*.*?\*_)|(\*.*?\*)|(_.*?_)|(~.*?~)|(```.*?```)|(\s+)|([^\s*~_`]+)/g;
27
39
  let match;
28
40
  while ((match = tokenizerRegex.exec(chunk)) !== null) {
29
- const [fullMatch, boldItalic, bold, italic, strikethrough, monospace, whitespace, textContent] = match;
41
+ const [
42
+ fullMatch,
43
+ boldItalic,
44
+ bold,
45
+ italic,
46
+ strikethrough,
47
+ monospace,
48
+ whitespace,
49
+ textContent,
50
+ ] = match;
30
51
  if (boldItalic) {
31
52
  const content = boldItalic.slice(2, -2);
32
53
  ctx.font = `italic bold ${fontSize}px Arial`;
33
- segmentsInLine.push({ type: 'bolditalic', content, width: ctx.measureText(content).width });
54
+ segmentsInLine.push({
55
+ type: "bolditalic",
56
+ content,
57
+ width: ctx.measureText(content).width,
58
+ });
34
59
  } else if (bold) {
35
60
  const content = bold.slice(1, -1);
36
61
  ctx.font = `bold ${fontSize}px Arial`;
37
- segmentsInLine.push({ type: 'bold', content, width: ctx.measureText(content).width });
62
+ segmentsInLine.push({
63
+ type: "bold",
64
+ content,
65
+ width: ctx.measureText(content).width,
66
+ });
38
67
  } else if (italic) {
39
68
  const content = italic.slice(1, -1);
40
69
  ctx.font = `italic ${fontSize}px Arial`;
41
- segmentsInLine.push({ type: 'italic', content, width: ctx.measureText(content).width });
70
+ segmentsInLine.push({
71
+ type: "italic",
72
+ content,
73
+ width: ctx.measureText(content).width,
74
+ });
42
75
  } else if (strikethrough) {
43
76
  const content = strikethrough.slice(1, -1);
44
77
  ctx.font = `${fontSize}px Arial`;
45
- segmentsInLine.push({ type: 'strikethrough', content, width: ctx.measureText(content).width });
78
+ segmentsInLine.push({
79
+ type: "strikethrough",
80
+ content,
81
+ width: ctx.measureText(content).width,
82
+ });
46
83
  } else if (monospace) {
47
84
  const content = monospace.slice(3, -3);
48
85
  ctx.font = `${fontSize}px 'Courier New', monospace`;
49
- segmentsInLine.push({ type: 'monospace', content, width: ctx.measureText(content).width });
86
+ segmentsInLine.push({
87
+ type: "monospace",
88
+ content,
89
+ width: ctx.measureText(content).width,
90
+ });
50
91
  } else if (whitespace) {
51
92
  ctx.font = `${fontSize}px Arial`;
52
- segmentsInLine.push({ type: 'whitespace', content: whitespace, width: ctx.measureText(whitespace).width });
93
+ segmentsInLine.push({
94
+ type: "whitespace",
95
+ content: whitespace,
96
+ width: ctx.measureText(whitespace).width,
97
+ });
53
98
  } else if (textContent) {
54
99
  ctx.font = `${fontSize}px Arial`;
55
- segmentsInLine.push({ type: 'text', content: textContent, width: ctx.measureText(textContent).width });
100
+ segmentsInLine.push({
101
+ type: "text",
102
+ content: textContent,
103
+ width: ctx.measureText(textContent).width,
104
+ });
56
105
  }
57
106
  }
58
107
  };
59
- emojiMatches.forEach(emojiInfo => {
108
+ emojiMatches.forEach((emojiInfo) => {
60
109
  const plainText = line.substring(lastIndex, emojiInfo.offset);
61
110
  processChunk(plainText);
62
111
  segmentsInLine.push({
63
- type: 'emoji',
112
+ type: "emoji",
64
113
  content: emojiInfo.found,
65
114
  width: fontSize * 1.2,
66
115
  });
@@ -72,13 +121,13 @@ function parseTextToSegments(text, ctx, fontSize) {
72
121
  finalSegments.push(...segmentsInLine);
73
122
  }
74
123
  if (index < rawLines.length - 1) {
75
- finalSegments.push({ type: 'newline', content: '\n', width: 0 });
124
+ finalSegments.push({ type: "newline", content: "\n", width: 0 });
76
125
  }
77
126
  });
78
127
  ctx.font = `${fontSize}px Arial`;
79
128
  return finalSegments;
80
129
  } catch (error) {
81
- console.error('Error in parseTextToSegments:', error);
130
+ console.error("Error in parseTextToSegments:", error);
82
131
  return [];
83
132
  }
84
133
  }
@@ -90,50 +139,70 @@ function rebuildLinesFromSegments(segments, maxWidth, ctx, fontSize) {
90
139
  let currentLineWidth = 0;
91
140
  const getFontString = (type, size) => {
92
141
  switch (type) {
93
- case 'bold': return `bold ${size}px Arial`;
94
- case 'italic': return `italic ${size}px Arial`;
95
- case 'bolditalic': return `italic bold ${size}px Arial`;
96
- case 'monospace': return `${size}px 'Courier New', monospace`;
97
- default: return `${size}px Arial`;
142
+ case "bold":
143
+ return `bold ${size}px Arial`;
144
+ case "italic":
145
+ return `italic ${size}px Arial`;
146
+ case "bolditalic":
147
+ return `italic bold ${size}px Arial`;
148
+ case "monospace":
149
+ return `${size}px 'Courier New', monospace`;
150
+ default:
151
+ return `${size}px Arial`;
98
152
  }
99
153
  };
100
- segments.forEach(segment => {
101
- if (segment.type === 'newline') {
154
+ segments.forEach((segment) => {
155
+ if (segment.type === "newline") {
102
156
  lines.push(currentLine);
103
157
  currentLine = [];
104
158
  currentLineWidth = 0;
105
159
  return;
106
160
  }
107
- if (segment.width > maxWidth && segment.type !== 'emoji') {
161
+ if (segment.width > maxWidth && segment.type !== "emoji") {
108
162
  if (currentLine.length > 0) {
109
163
  lines.push(currentLine);
110
164
  currentLine = [];
111
165
  currentLineWidth = 0;
112
166
  }
113
- let tempStr = '';
167
+ let tempStr = "";
114
168
  const originalFont = getFontString(segment.type, fontSize);
115
169
  ctx.font = originalFont;
116
170
  for (const char of segment.content) {
117
171
  const measuredWidth = ctx.measureText(tempStr + char).width;
118
172
  if (measuredWidth > maxWidth) {
119
- lines.push([{ type: segment.type, content: tempStr, width: ctx.measureText(tempStr).width }]);
173
+ lines.push([
174
+ {
175
+ type: segment.type,
176
+ content: tempStr,
177
+ width: ctx.measureText(tempStr).width,
178
+ },
179
+ ]);
120
180
  tempStr = char;
121
181
  } else {
122
182
  tempStr += char;
123
183
  }
124
184
  }
125
185
  if (tempStr) {
126
- currentLine = [{ type: segment.type, content: tempStr, width: ctx.measureText(tempStr).width }];
186
+ currentLine = [
187
+ {
188
+ type: segment.type,
189
+ content: tempStr,
190
+ width: ctx.measureText(tempStr).width,
191
+ },
192
+ ];
127
193
  currentLineWidth = currentLine[0].width;
128
194
  }
129
195
  return;
130
196
  }
131
- if (currentLineWidth + segment.width > maxWidth && currentLine.length > 0) {
197
+ if (
198
+ currentLineWidth + segment.width > maxWidth &&
199
+ currentLine.length > 0
200
+ ) {
132
201
  lines.push(currentLine);
133
202
  currentLine = [segment];
134
203
  currentLineWidth = segment.width;
135
204
  } else {
136
- if (segment.type === 'whitespace' && currentLine.length === 0) return;
205
+ if (segment.type === "whitespace" && currentLine.length === 0) return;
137
206
  currentLine.push(segment);
138
207
  currentLineWidth += segment.width;
139
208
  }
@@ -143,24 +212,24 @@ function rebuildLinesFromSegments(segments, maxWidth, ctx, fontSize) {
143
212
  }
144
213
  return lines;
145
214
  } catch (error) {
146
- console.error('Error in rebuildLinesFromSegments:', error);
215
+ console.error("Error in rebuildLinesFromSegments:", error);
147
216
  return [[]];
148
217
  }
149
218
  }
150
219
 
151
220
  function getContrastColor(hexColor) {
152
- if (!hexColor || typeof hexColor !== 'string') return '#FFFFFF';
153
- const hex = hexColor.replace('#', '');
154
- if (hex.length !== 6) return '#FFFFFF';
221
+ if (!hexColor || typeof hexColor !== "string") return "#FFFFFF";
222
+ const hex = hexColor.replace("#", "");
223
+ if (hex.length !== 6) return "#FFFFFF";
155
224
  const r = parseInt(hex.substring(0, 2), 16);
156
225
  const g = parseInt(hex.substring(2, 4), 16);
157
226
  const b = parseInt(hex.substring(4, 6), 16);
158
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b);
159
- return luminance > 140 ? '#000000' : '#FFFFFF';
160
- };
227
+ const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
228
+ return luminance > 140 ? "#000000" : "#FFFFFF";
229
+ }
161
230
 
162
231
  module.exports = {
163
232
  parseTextToSegments,
164
233
  rebuildLinesFromSegments,
165
- getContrastColor
166
- };
234
+ getContrastColor,
235
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "medias-fakerator",
3
- "version": "1.0.0-dra",
3
+ "version": "1.0.0-dra.0",
4
4
  "description": "AIO Faker generator by Iruka Devs",
5
5
  "main": "index.js",
6
6
  "author": "Iruka Devs",
@@ -11,10 +11,10 @@
11
11
  "@ffmpeg-installer/ffmpeg": "1.1.0",
12
12
  "canvas": "^3.2.0",
13
13
  "emoji-cache": "^2.0.1",
14
- "emoji-db": "github:Terror-Machine/emoji-db#master",
15
14
  "fluent-ffmpeg": "^2.1.3",
16
15
  "fs-extra": "11.3.2",
17
16
  "lru-cache": "^11.1.0",
17
+ "node-emoji": "^2.2.0",
18
18
  "runes": "^0.4.3",
19
19
  "sharp": "^0.34.3"
20
20
  },