ztechno_core 0.0.111 → 0.0.112

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 (39) hide show
  1. package/package.json +1 -1
  2. package/lib/crypto_service.d.ts +0 -23
  3. package/lib/crypto_service.js +0 -100
  4. package/lib/engine_base.d.ts +0 -11
  5. package/lib/engine_base.js +0 -9
  6. package/lib/express.d.ts +0 -1
  7. package/lib/express.js +0 -18
  8. package/lib/mail_service.d.ts +0 -85
  9. package/lib/mail_service.js +0 -156
  10. package/lib/orm/mail_blacklist_orm.d.ts +0 -22
  11. package/lib/orm/mail_blacklist_orm.js +0 -79
  12. package/lib/orm/orm.d.ts +0 -8
  13. package/lib/orm/orm.js +0 -26
  14. package/lib/scripts/docker-build.d.ts +0 -14
  15. package/lib/scripts/docker-build.js +0 -91
  16. package/lib/scripts/docker-publish.d.ts +0 -19
  17. package/lib/scripts/docker-publish.js +0 -114
  18. package/lib/scripts/docker-push.d.ts +0 -8
  19. package/lib/scripts/docker-push.js +0 -87
  20. package/lib/scripts/docker-update.d.ts +0 -27
  21. package/lib/scripts/docker-update.js +0 -207
  22. package/lib/scripts/encrypt.d.ts +0 -1
  23. package/lib/scripts/encrypt.js +0 -4
  24. package/lib/sql_service.d.ts +0 -123
  25. package/lib/sql_service.js +0 -234
  26. package/lib/translate_service.d.ts +0 -48
  27. package/lib/translate_service.js +0 -908
  28. package/lib/typings/crypto_types.d.ts +0 -4
  29. package/lib/typings/crypto_types.js +0 -2
  30. package/lib/typings/index.d.ts +0 -4
  31. package/lib/typings/index.js +0 -36
  32. package/lib/typings/mail_types.d.ts +0 -95
  33. package/lib/typings/mail_types.js +0 -2
  34. package/lib/typings/translate_types.d.ts +0 -69
  35. package/lib/typings/translate_types.js +0 -46
  36. package/lib/typings/user_types.d.ts +0 -41
  37. package/lib/typings/user_types.js +0 -2
  38. package/lib/user_service.d.ts +0 -80
  39. package/lib/user_service.js +0 -216
@@ -1,908 +0,0 @@
1
- 'use strict';
2
- var __importDefault =
3
- (this && this.__importDefault) ||
4
- function (mod) {
5
- return mod && mod.__esModule ? mod : { default: mod };
6
- };
7
- Object.defineProperty(exports, '__esModule', { value: true });
8
- exports.ZTranslateService = void 0;
9
- const typings_1 = require('./typings');
10
- const dist_1 = require('./vendor/dom-parser/dist');
11
- const translate_1 = __importDefault(require('translate'));
12
- class ZTranslateService {
13
- get sql() {
14
- return this.opt.sqlService;
15
- }
16
- getLanguages() {
17
- return (
18
- this.opt.languages || [
19
- { lang: 'en', text: 'English' },
20
- { lang: 'nl', text: 'Nederlands' },
21
- ]
22
- );
23
- }
24
- getSourceLang() {
25
- return this.opt.sourceLang || 'en';
26
- }
27
- getDefaultLang() {
28
- return this.opt.defaultLang || 'en';
29
- }
30
- constructor(opt) {
31
- this.opt = opt;
32
- this.localCache = {};
33
- this.surpressErrors = true;
34
- this.maxRetries = 3;
35
- this.retryDelay = 1000;
36
- this.fallbackText = '?';
37
- this.codes = {
38
- // Quotes and apostrophes
39
- [`'`]: `'`,
40
- [`"`]: `"`,
41
- [`“`]: `"`,
42
- [`”`]: `"`,
43
- [`‘`]: `'`,
44
- [`’`]: `'`,
45
- [`‚`]: `‚`,
46
- [`„`]: `„`,
47
- [`«`]: `«`,
48
- [`»`]: `»`,
49
- [`‹`]: `‹`,
50
- [`›`]: `›`,
51
- // Currency symbols
52
- [`©`]: `©`,
53
- [`®`]: `®`,
54
- [`€`]: `€`,
55
- [`£`]: `£`,
56
- [`¥`]: `¥`,
57
- [`¢`]: `¢`,
58
- [`™`]: `™`,
59
- [`$`]: `$`,
60
- // Mathematical and special symbols
61
- [`–`]: `–`,
62
- [`—`]: `—`,
63
- [`…`]: `…`,
64
- [`•`]: `•`,
65
- [`→`]: `→`,
66
- [`←`]: `←`,
67
- [`↑`]: `↑`,
68
- [`↓`]: `↓`,
69
- [`×`]: `×`,
70
- [`÷`]: `÷`,
71
- [`±`]: `±`,
72
- [`≤`]: `≤`,
73
- [`≥`]: `≥`,
74
- [`≠`]: `≠`,
75
- [`∞`]: `∞`,
76
- [`°`]: `°`,
77
- [`‰`]: `‰`,
78
- [`†`]: `†`,
79
- [`‡`]: `‡`,
80
- [`§`]: `§`,
81
- [`¶`]: `¶`,
82
- // Accented characters
83
- [`À`]: `À`,
84
- [`Á`]: `Á`,
85
- [`Â`]: `Â`,
86
- [`Ã`]: `Ã`,
87
- [`Ä`]: `Ä`,
88
- [`Å`]: `Å`,
89
- [`Æ`]: `Æ`,
90
- [`Ç`]: `Ç`,
91
- [`È`]: `È`,
92
- [`É`]: `É`,
93
- [`Ê`]: `Ê`,
94
- [`Ë`]: `Ë`,
95
- [`Ì`]: `Ì`,
96
- [`Í`]: `Í`,
97
- [`Î`]: `Î`,
98
- [`Ï`]: `Ï`,
99
- [`Ð`]: `Ð`,
100
- [`Ñ`]: `Ñ`,
101
- [`Ò`]: `Ò`,
102
- [`Ó`]: `Ó`,
103
- [`Ô`]: `Ô`,
104
- [`Õ`]: `Õ`,
105
- [`Ö`]: `Ö`,
106
- [`Ø`]: `Ø`,
107
- [`Ù`]: `Ù`,
108
- [`Ú`]: `Ú`,
109
- [`Û`]: `Û`,
110
- [`Ü`]: `Ü`,
111
- [`Ý`]: `Ý`,
112
- [`Þ`]: `Þ`,
113
- [`ß`]: `ß`,
114
- [`à`]: `à`,
115
- [`á`]: `á`,
116
- [`â`]: `â`,
117
- [`ã`]: `ã`,
118
- [`ä`]: `ä`,
119
- [`å`]: `å`,
120
- [`æ`]: `æ`,
121
- [`ç`]: `ç`,
122
- [`è`]: `è`,
123
- [`é`]: `é`,
124
- [`ê`]: `ê`,
125
- [`ë`]: `ë`,
126
- [`ì`]: `ì`,
127
- [`í`]: `í`,
128
- [`î`]: `î`,
129
- [`ï`]: `ï`,
130
- [`ð`]: `ð`,
131
- [`ñ`]: `ñ`,
132
- [`ò`]: `ò`,
133
- [`ó`]: `ó`,
134
- [`ô`]: `ô`,
135
- [`õ`]: `õ`,
136
- [`ö`]: `ö`,
137
- [`ø`]: `ø`,
138
- [`ù`]: `ù`,
139
- [`ú`]: `ú`,
140
- [`û`]: `û`,
141
- [`ü`]: `ü`,
142
- [`ý`]: `ý`,
143
- [`þ`]: `þ`,
144
- [`ÿ`]: `ÿ`,
145
- // Common spaces and breaks
146
- [` `]: ` `,
147
- [`­`]: `­`,
148
- [`​`]: ``,
149
- // Punctuation
150
- [`¡`]: `¡`,
151
- [`¿`]: `¿`,
152
- [`·`]: `·`,
153
- [`¸`]: `¸`,
154
- // Fractions
155
- [`¼`]: `¼`,
156
- [`½`]: `½`,
157
- [`¾`]: `¾`,
158
- [`⅓`]: `⅓`,
159
- [`⅔`]: `⅔`,
160
- [`⅕`]: `⅕`,
161
- [`⅖`]: `⅖`,
162
- [`⅗`]: `⅗`,
163
- [`⅘`]: `⅘`,
164
- [`⅙`]: `⅙`,
165
- [`⅚`]: `⅚`,
166
- [`⅛`]: `⅛`,
167
- [`⅜`]: `⅜`,
168
- [`⅝`]: `⅝`,
169
- [`⅞`]: `⅞`,
170
- // Greek letters (common ones)
171
- [`α`]: `α`,
172
- [`β`]: `β`,
173
- [`γ`]: `γ`,
174
- [`δ`]: `δ`,
175
- [`ε`]: `ε`,
176
- [`ζ`]: `ζ`,
177
- [`η`]: `η`,
178
- [`θ`]: `θ`,
179
- [`ι`]: `ι`,
180
- [`κ`]: `κ`,
181
- [`λ`]: `λ`,
182
- [`μ`]: `μ`,
183
- [`ν`]: `ν`,
184
- [`ξ`]: `ξ`,
185
- [`ο`]: `ο`,
186
- [`π`]: `π`,
187
- [`ρ`]: `ρ`,
188
- [`σ`]: `σ`,
189
- [`τ`]: `τ`,
190
- [`υ`]: `υ`,
191
- [`φ`]: `φ`,
192
- [`χ`]: `χ`,
193
- [`ψ`]: `ψ`,
194
- [`ω`]: `ω`,
195
- // Uppercase Greek letters
196
- [`Α`]: `Α`,
197
- [`Β`]: `Β`,
198
- [`Γ`]: `Γ`,
199
- [`Δ`]: `Δ`,
200
- [`Ε`]: `Ε`,
201
- [`Ζ`]: `Ζ`,
202
- [`Η`]: `Η`,
203
- [`Θ`]: `Θ`,
204
- [`Ι`]: `Ι`,
205
- [`Κ`]: `Κ`,
206
- [`Λ`]: `Λ`,
207
- [`Μ`]: `Μ`,
208
- [`Ν`]: `Ν`,
209
- [`Ξ`]: `Ξ`,
210
- [`Ο`]: `Ο`,
211
- [`Π`]: `Π`,
212
- [`Ρ`]: `Ρ`,
213
- [`Σ`]: `Σ`,
214
- [`Τ`]: `Τ`,
215
- [`Υ`]: `Υ`,
216
- [`Φ`]: `Φ`,
217
- [`Χ`]: `Χ`,
218
- [`Ψ`]: `Ψ`,
219
- [`Ω`]: `Ω`,
220
- // Additional common symbols
221
- [`₺`]: `₪`,
222
- [`₽`]: `₽`,
223
- [`₹`]: `₹`,
224
- [`¤`]: `¤`,
225
- [`¦`]: `¦`,
226
- [`¨`]: `¨`,
227
- [`ª`]: `ª`,
228
- [`¬`]: `¬`,
229
- [`¯`]: `¯`,
230
- [`²`]: `²`,
231
- [`³`]: `³`,
232
- [`¹`]: `¹`,
233
- [`º`]: `º`,
234
- // Card suits and misc symbols
235
- [`♠`]: `♠`,
236
- [`♣`]: `♣`,
237
- [`♥`]: `♥`,
238
- [`♦`]: `♦`,
239
- [`★`]: `★`,
240
- [`☆`]: `☆`,
241
- [`☎`]: `☎`,
242
- [`☕`]: `☕`,
243
- [`☺`]: `☺`,
244
- [`☻`]: `☻`,
245
- [`☼`]: `☼`,
246
- [`♀`]: `♀`,
247
- [`♂`]: `♂`,
248
- [`❤`]: `❤`,
249
- // Arabic characters (U+0600 to U+06FF range)
250
- [`؀`]: `؀`,
251
- [`؁`]: `؁`,
252
- [`؂`]: `؂`,
253
- [`؃`]: `؃`,
254
- [`؄`]: `؄`,
255
- [`؅`]: `؅`,
256
- [`؆`]: `؆`,
257
- [`؇`]: `؇`,
258
- [`؈`]: `؈`,
259
- [`؉`]: `؉`,
260
- [`؊`]: `؊`,
261
- [`؋`]: `؋`,
262
- [`،`]: `،`,
263
- [`؍`]: `؍`,
264
- [`؎`]: `؎`,
265
- [`؏`]: `؏`,
266
- [`ؐ`]: `ؐ`,
267
- [`ؑ`]: `ؑ`,
268
- [`ؒ`]: `ؒ`,
269
- [`ؓ`]: `ؓ`,
270
- [`ؔ`]: `ؔ`,
271
- [`ؕ`]: `ؕ`,
272
- [`ؖ`]: `ؖ`,
273
- [`ؗ`]: `ؗ`,
274
- [`ؘ`]: `ؘ`,
275
- [`ؙ`]: `ؙ`,
276
- [`ؚ`]: `ؚ`,
277
- [`؛`]: `؛`,
278
- [`؜`]: `؜`,
279
- [`؝`]: `؝`,
280
- [`؞`]: `؞`,
281
- [`؟`]: `؟`,
282
- [`ؠ`]: `ؠ`,
283
- [`ء`]: `ء`,
284
- [`آ`]: `آ`,
285
- [`أ`]: `أ`,
286
- [`ؤ`]: `ؤ`,
287
- [`إ`]: `إ`,
288
- [`ئ`]: `ئ`,
289
- [`ا`]: `ا`,
290
- [`ب`]: `ب`,
291
- [`ة`]: `ة`,
292
- [`ت`]: `ت`,
293
- [`ث`]: `ث`,
294
- [`ج`]: `ج`,
295
- [`ح`]: `ح`,
296
- [`خ`]: `خ`,
297
- [`د`]: `د`,
298
- [`ذ`]: `ذ`,
299
- [`ر`]: `ر`,
300
- [`ز`]: `ز`,
301
- [`س`]: `س`,
302
- [`ش`]: `ش`,
303
- [`ص`]: `ص`,
304
- [`ض`]: `ض`,
305
- [`ط`]: `ط`,
306
- [`ظ`]: `ظ`,
307
- [`ع`]: `ع`,
308
- [`غ`]: `غ`,
309
- [`ػ`]: `ػ`,
310
- [`ؼ`]: `ؼ`,
311
- [`ؽ`]: `ؽ`,
312
- [`ؾ`]: `ؾ`,
313
- [`ؿ`]: `ؿ`,
314
- [`ـ`]: `ـ`,
315
- [`ف`]: `ف`,
316
- [`ق`]: `ق`,
317
- [`ك`]: `ك`,
318
- [`ل`]: `ل`,
319
- [`م`]: `م`,
320
- [`ن`]: `ن`,
321
- [`ه`]: `ه`,
322
- [`و`]: `و`,
323
- [`ى`]: `ى`,
324
- [`ي`]: `ي`,
325
- // Arabic diacritics (most common ones)
326
- [`ً`]: `ً`,
327
- [`ٌ`]: `ٌ`,
328
- [`ٍ`]: `ٍ`,
329
- [`َ`]: `َ`,
330
- [`ُ`]: `ُ`,
331
- [`ِ`]: `ِ`,
332
- [`ّ`]: `ّ`,
333
- [`ْ`]: `ْ`,
334
- [`ٓ`]: `ٓ`,
335
- [`ٔ`]: `ٔ`,
336
- [`ٕ`]: `ٕ`,
337
- // Arabic-Indic digits
338
- [`٠`]: `٠`,
339
- [`١`]: `١`,
340
- [`٢`]: `٢`,
341
- [`٣`]: `٣`,
342
- [`٤`]: `٤`,
343
- [`٥`]: `٥`,
344
- [`٦`]: `٦`,
345
- [`٧`]: `٧`,
346
- [`٨`]: `٨`,
347
- [`٩`]: `٩`,
348
- // Extended Arabic characters (commonly used)
349
- [`٪`]: `٪`,
350
- [`٫`]: `٫`,
351
- [`٬`]: `٬`,
352
- [`٭`]: `٭`,
353
- [`ٮ`]: `ٮ`,
354
- [`ٯ`]: `ٯ`,
355
- [`ٰ`]: `ٰ`,
356
- [`ٱ`]: `ٱ`,
357
- [`ٲ`]: `ٲ`,
358
- [`ٳ`]: `ٳ`,
359
- [`ٴ`]: `ٴ`,
360
- [`ٵ`]: `ٵ`,
361
- [`ٶ`]: `ٶ`,
362
- [`ٷ`]: `ٷ`,
363
- [`ٸ`]: `ٸ`,
364
- [`ٹ`]: `ٹ`,
365
- [`ٺ`]: `ٺ`,
366
- [`ٻ`]: `ٻ`,
367
- [`ټ`]: `ټ`,
368
- [`ٽ`]: `ٽ`,
369
- [`پ`]: `پ`,
370
- [`ٿ`]: `ٿ`,
371
- [`ڀ`]: `ڀ`,
372
- [`ځ`]: `ځ`,
373
- [`ڂ`]: `ڂ`,
374
- [`ڃ`]: `ڃ`,
375
- [`ڄ`]: `ڄ`,
376
- [`څ`]: `څ`,
377
- [`چ`]: `چ`,
378
- [`ڇ`]: `ڇ`,
379
- [`ڈ`]: `ڈ`,
380
- [`ډ`]: `ډ`,
381
- [`ڊ`]: `ڊ`,
382
- [`ڋ`]: `ڋ`,
383
- [`ڌ`]: `ڌ`,
384
- [`ڍ`]: `ڍ`,
385
- [`ڎ`]: `ڎ`,
386
- [`ڏ`]: `ڏ`,
387
- [`ڐ`]: `ڐ`,
388
- [`ڑ`]: `ڑ`,
389
- [`ڒ`]: `ڒ`,
390
- [`ړ`]: `ړ`,
391
- [`ڔ`]: `ڔ`,
392
- [`ڕ`]: `ڕ`,
393
- [`ږ`]: `ږ`,
394
- [`ڗ`]: `ڗ`,
395
- [`ژ`]: `ژ`,
396
- [`ڙ`]: `ڙ`,
397
- [`ښ`]: `ښ`,
398
- [`ڛ`]: `ڛ`,
399
- [`ڜ`]: `ڜ`,
400
- [`ڝ`]: `ڝ`,
401
- [`ڞ`]: `ڞ`,
402
- [`ڟ`]: `ڟ`,
403
- [`ڠ`]: `ڠ`,
404
- [`ڡ`]: `ڡ`,
405
- [`ڢ`]: `ڢ`,
406
- [`ڣ`]: `ڣ`,
407
- [`ڤ`]: `ڤ`,
408
- [`ڥ`]: `ڥ`,
409
- [`ڦ`]: `ڦ`,
410
- [`ڧ`]: `ڧ`,
411
- [`ڨ`]: `ڨ`,
412
- [`ک`]: `ک`,
413
- [`ڪ`]: `ڪ`,
414
- [`ګ`]: `ګ`,
415
- [`ڬ`]: `ڬ`,
416
- [`ڭ`]: `ڭ`,
417
- [`ڮ`]: `ڮ`,
418
- [`گ`]: `گ`,
419
- [`ڰ`]: `ڰ`,
420
- [`ڱ`]: `ڱ`,
421
- [`ڲ`]: `ڲ`,
422
- [`ڳ`]: `ڳ`,
423
- [`ڴ`]: `ڴ`,
424
- [`ڵ`]: `ڵ`,
425
- [`ڶ`]: `ڶ`,
426
- [`ڷ`]: `ڷ`,
427
- [`ڸ`]: `ڸ`,
428
- [`ڹ`]: `ڹ`,
429
- [`ں`]: `ں`,
430
- [`ڻ`]: `ڻ`,
431
- [`ڼ`]: `ڼ`,
432
- [`ڽ`]: `ڽ`,
433
- [`ھ`]: `ھ`,
434
- [`ڿ`]: `ڿ`,
435
- [`ۀ`]: `ۀ`,
436
- [`ہ`]: `ہ`,
437
- [`ۂ`]: `ۂ`,
438
- [`ۃ`]: `ۃ`,
439
- [`ۄ`]: `ۄ`,
440
- [`ۅ`]: `ۅ`,
441
- [`ۆ`]: `ۆ`,
442
- [`ۇ`]: `ۇ`,
443
- [`ۈ`]: `ۈ`,
444
- [`ۉ`]: `ۉ`,
445
- [`ۊ`]: `ۊ`,
446
- [`ۋ`]: `ۋ`,
447
- [`ی`]: `ی`,
448
- [`ۍ`]: `ۍ`,
449
- [`ێ`]: `ێ`,
450
- [`ۏ`]: `ۏ`,
451
- [`ې`]: `ې`,
452
- [`ۑ`]: `ۑ`,
453
- [`ے`]: `ے`,
454
- [`ۓ`]: `ۓ`, // Arabic Letter Yeh Barree with Hamza Above
455
- };
456
- if (!opt.googleApiKey) {
457
- throw new typings_1.ValidationError('googleApiKey', opt.googleApiKey);
458
- }
459
- if (!opt.sqlService) {
460
- throw new typings_1.ValidationError('sqlService', opt.sqlService);
461
- }
462
- translate_1.default.key = opt.googleApiKey;
463
- this.surpressErrors = opt.surpressErrors ?? true;
464
- this.maxRetries = opt.maxRetries ?? 3;
465
- this.retryDelay = opt.retryDelay ?? 1000;
466
- this.fallbackText = opt.fallbackText ?? '?';
467
- this.getLanguages().map((lang) => (this.localCache[lang.lang] = {}));
468
- setInterval(() => this.clearLocalCache(), 1000 * 60 * 60); // Every Hour
469
- }
470
- getLang(cookies) {
471
- try {
472
- const defaultLang = this.getDefaultLang();
473
- const langKey = (cookies?.lang || defaultLang).toLowerCase();
474
- const foundLang = this.getLanguages().find((l) => l.lang === langKey);
475
- return foundLang === undefined ? defaultLang : foundLang.lang;
476
- } catch (error) {
477
- this.logError(new typings_1.ValidationError('cookies', cookies), 'getLang');
478
- return this.getDefaultLang();
479
- }
480
- }
481
- async sleep(ms) {
482
- return new Promise((resolve) => setTimeout(resolve, ms));
483
- }
484
- logError(error, context) {
485
- if (this.opt.log) {
486
- this.opt.log(error, { context, timestamp: new Date().toISOString() });
487
- }
488
- }
489
- async retryOperation(operation, operationName, maxRetries = this.maxRetries) {
490
- let lastError;
491
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
492
- try {
493
- return await operation();
494
- } catch (error) {
495
- lastError = error;
496
- this.logError(error, `${operationName} - Attempt ${attempt}/${maxRetries}`);
497
- if (attempt < maxRetries) {
498
- await this.sleep(this.retryDelay * attempt); // Exponential backoff
499
- }
500
- }
501
- }
502
- throw lastError;
503
- }
504
- async translateText(langOrReq, text) {
505
- try {
506
- // Input validation
507
- if (!text || typeof text !== 'string') {
508
- throw new typings_1.ValidationError('text', text);
509
- }
510
- const lang = typeof langOrReq === 'string' ? langOrReq : this.getLang(langOrReq.cookies);
511
- text = text.trim();
512
- if (text.length === 0) {
513
- return text;
514
- }
515
- if (text.length === 1) {
516
- return text;
517
- }
518
- // Process HTML entities with better error handling
519
- text = await this.processHtmlEntities(text);
520
- // Check local cache
521
- const localCached = this.checkLocalCache(text, lang);
522
- if (localCached !== false) {
523
- return localCached.value;
524
- }
525
- // Check remote cache
526
- const remoteCached = await this.fetch(text, lang);
527
- if (remoteCached !== false) {
528
- return remoteCached.value;
529
- }
530
- // Perform translation with retry logic
531
- let result;
532
- try {
533
- result = await this.retryOperation(async () => {
534
- return await (0, translate_1.default)(text, {
535
- from: this.getSourceLang(),
536
- to: lang,
537
- });
538
- }, 'translateText');
539
- } catch (err) {
540
- const translationError = new typings_1.ApiTranslationError(err, text, lang);
541
- this.logError(translationError, 'translateText');
542
- if (!this.surpressErrors) {
543
- throw translationError;
544
- }
545
- result = this.fallbackText;
546
- }
547
- // Save translation to cache
548
- try {
549
- await this.insert(text, lang, { value: result });
550
- } catch (err) {
551
- this.logError(new typings_1.DatabaseError(err, 'insert translation'), 'translateText');
552
- // Don't throw here, translation still succeeded
553
- }
554
- return result;
555
- } catch (error) {
556
- if (error instanceof typings_1.TranslateError) {
557
- throw error;
558
- }
559
- const wrappedError = new typings_1.TranslateError(
560
- `Unexpected error in translateText: ${error.message}`,
561
- 'UNEXPECTED_ERROR',
562
- { originalError: error },
563
- );
564
- this.logError(wrappedError, 'translateText');
565
- if (!this.surpressErrors) {
566
- throw wrappedError;
567
- }
568
- return this.fallbackText;
569
- }
570
- }
571
- async processHtmlEntities(text) {
572
- let replaceCount = 0;
573
- const maxReplacements = 1000;
574
- while (text.includes('&#')) {
575
- const codeIndexStart = text.indexOf('&#');
576
- const first = text.substring(codeIndexStart);
577
- const semicolonIndex = first.indexOf(';');
578
- if (semicolonIndex === -1) {
579
- // No closing semicolon found, break to avoid infinite loop
580
- break;
581
- }
582
- const codeLength = semicolonIndex + 1;
583
- const code = first.substring(0, codeLength);
584
- if (this.codes[code] === undefined) {
585
- const entityError = new typings_1.HtmlEntityError(code, text);
586
- this.logError(entityError, 'processHtmlEntities');
587
- if (!this.surpressErrors) {
588
- throw entityError;
589
- }
590
- // Skip this entity and continue
591
- text = text.substring(0, codeIndexStart) + code + text.substring(codeIndexStart + codeLength);
592
- break;
593
- }
594
- text = text.substring(0, codeIndexStart) + this.codes[code] + text.substring(codeIndexStart + codeLength);
595
- if (replaceCount++ > maxReplacements) {
596
- const loopError = new typings_1.TranslateError(
597
- `HTML entity replacement exceeded maximum count (${maxReplacements})`,
598
- 'MAX_REPLACEMENTS_EXCEEDED',
599
- { code, text, replaceCount },
600
- );
601
- this.logError(loopError, 'processHtmlEntities');
602
- if (!this.surpressErrors) {
603
- throw loopError;
604
- }
605
- break;
606
- }
607
- }
608
- return text;
609
- }
610
- async translateHtml(html, cookies) {
611
- try {
612
- if (!html || typeof html !== 'string') {
613
- throw new typings_1.ValidationError('html', html);
614
- }
615
- if (!cookies) {
616
- throw new typings_1.ValidationError('cookies', cookies);
617
- }
618
- const lang = this.getLang(cookies);
619
- const srcLang = this.getSourceLang();
620
- let dom;
621
- try {
622
- dom = (0, dist_1.parseFromString)(html);
623
- } catch (error) {
624
- const parseError = new typings_1.TranslateError('Failed to parse HTML', 'HTML_PARSE_ERROR', { error, html });
625
- this.logError(parseError, 'translateHtml');
626
- if (!this.surpressErrors) {
627
- throw parseError;
628
- }
629
- return html;
630
- }
631
- const htmlNodes = dom.getElementsByTagName('html');
632
- const mainNodes = dom.getElementsByTagName('main');
633
- const isView = htmlNodes.length === 0;
634
- const domNode = isView ? mainNodes[0] : htmlNodes[0];
635
- if (lang !== srcLang && domNode) {
636
- const node = isView ? domNode : domNode.getElementsByTagName('body')[0];
637
- if (node) {
638
- const promises = [];
639
- this.translateHtmlRec(lang, node, promises);
640
- try {
641
- await Promise.all(promises);
642
- } catch (error) {
643
- this.logError(
644
- new typings_1.TranslateError('Failed to translate HTML nodes', 'HTML_TRANSLATION_ERROR', { error }),
645
- 'translateHtml',
646
- );
647
- if (!this.surpressErrors) {
648
- throw error;
649
- }
650
- }
651
- }
652
- }
653
- const output = domNode ? domNode.outerHTML : html;
654
- return output.startsWith(`<!DOCTYPE html>`) ? output : `<!DOCTYPE html>\r\n${output}`;
655
- } catch (error) {
656
- if (error instanceof typings_1.TranslateError) {
657
- throw error;
658
- }
659
- const wrappedError = new typings_1.TranslateError(
660
- `Unexpected error in translateHtml: ${error.message}`,
661
- 'UNEXPECTED_ERROR',
662
- { originalError: error },
663
- );
664
- this.logError(wrappedError, 'translateHtml');
665
- if (!this.surpressErrors) {
666
- throw wrappedError;
667
- }
668
- return html;
669
- }
670
- }
671
- translateHtmlRec(lang, node, promises, skipTranslate = false) {
672
- try {
673
- if (this.opt.verbose) this.opt.verbose(node.nodeName, node);
674
- if (node.getAttribute && node.getAttribute('notranslate') != null) {
675
- skipTranslate = true;
676
- }
677
- if (node.nodeName === '#comment') {
678
- // Skip HTML comments
679
- return;
680
- }
681
- if (node.nodeName === 'script') {
682
- // Skip script tags
683
- return;
684
- }
685
- if (node.nodeName === 'style') {
686
- // Skip style tags
687
- return;
688
- }
689
- if (node.nodeName === '#text') {
690
- const nodeText = node;
691
- const text = nodeText.text.replace(/[\r|\n|\r\n]+/g, ' ').replace(/\s\s+/g, ' ');
692
- const value = text.trim();
693
- const meta = {
694
- prefix: genSpaces(text.length - text.trimStart().length),
695
- suffix: genSpaces(text.length - text.trimEnd().length),
696
- };
697
- if (skipTranslate === true || text.length === 0 || !strContainsLetters(text)) {
698
- node.text = meta.prefix + text + meta.suffix;
699
- return;
700
- }
701
- promises.push(
702
- this.translateText(lang, value)
703
- .then((translatedText) => {
704
- node.text = meta.prefix + translatedText + meta.suffix;
705
- })
706
- .catch((err) => {
707
- node.text = text;
708
- this.logError(err, 'translateHtmlRec');
709
- if (!this.surpressErrors) {
710
- throw err;
711
- }
712
- }),
713
- );
714
- return;
715
- }
716
- // Process child nodes safely
717
- if (node.childNodes && Array.isArray(node.childNodes)) {
718
- for (const child of node.childNodes) {
719
- this.translateHtmlRec(lang, child, promises, skipTranslate);
720
- }
721
- }
722
- } catch (error) {
723
- this.logError(
724
- new typings_1.TranslateError(`Error processing HTML node: ${error.message}`, 'HTML_NODE_ERROR', {
725
- error,
726
- nodeName: node?.nodeName,
727
- }),
728
- 'translateHtmlRec',
729
- );
730
- if (!this.surpressErrors) {
731
- throw error;
732
- }
733
- }
734
- }
735
- async update(key, lang, data) {
736
- try {
737
- if (!key || !lang || !data) {
738
- throw new typings_1.ValidationError('update parameters', { key, lang, data });
739
- }
740
- const res = await this.retryOperation(async () => {
741
- return await this.sql.query(
742
- `
743
- INSERT INTO translations
744
- (\`key\`, \`lang\`, \`value\`)
745
- VALUES
746
- (:key, :lang, :value)
747
- ON DUPLICATE KEY UPDATE value=:value
748
- `,
749
- { key, lang, value: data.value },
750
- );
751
- }, 'update translation');
752
- if (res.affectedRows) {
753
- this.insertLocalCache(key, lang, data);
754
- }
755
- return res;
756
- } catch (error) {
757
- const dbError = new typings_1.DatabaseError(error, 'update translation');
758
- this.logError(dbError, 'update');
759
- throw dbError;
760
- }
761
- }
762
- checkLocalCache(key, lang) {
763
- try {
764
- if (!key || !lang || !this.localCache[lang]) {
765
- return false;
766
- }
767
- const hasLocal = !this.localCache[lang].hasOwnProperty(key);
768
- return hasLocal ? false : this.localCache[lang][key];
769
- } catch (error) {
770
- this.logError(
771
- new typings_1.TranslateError('Local cache check failed', 'CACHE_ERROR', { error, key, lang }),
772
- 'checkLocalCache',
773
- );
774
- return false;
775
- }
776
- }
777
- insertLocalCache(key, lang, data) {
778
- try {
779
- if (!key || !lang || !data) {
780
- return;
781
- }
782
- if (!this.localCache[lang]) {
783
- this.localCache[lang] = {};
784
- }
785
- this.localCache[lang][key] = data;
786
- } catch (error) {
787
- this.logError(
788
- new typings_1.TranslateError('Local cache insertion failed', 'CACHE_ERROR', { error, key, lang }),
789
- 'insertLocalCache',
790
- );
791
- }
792
- }
793
- clearLocalCache() {
794
- try {
795
- Object.keys(this.localCache).map((k) => {
796
- this.localCache[k] = {};
797
- });
798
- } catch (error) {
799
- this.logError(
800
- new typings_1.TranslateError('Failed to clear local cache', 'CACHE_ERROR', { error }),
801
- 'clearLocalCache',
802
- );
803
- }
804
- }
805
- async fetch(key, lang) {
806
- try {
807
- if (!key || !lang) {
808
- return false;
809
- }
810
- const results = await this.retryOperation(async () => {
811
- return await this.sql.query(
812
- `SELECT \`value\` FROM translations WHERE \`lang\`=? AND \`key\`=CONVERT(? USING utf8mb4)`,
813
- [lang, key],
814
- );
815
- }, 'fetch translation');
816
- if (results.length > 0) {
817
- const { value } = results[0];
818
- const data = { value };
819
- this.insertLocalCache(key, lang, data);
820
- return data;
821
- }
822
- return false;
823
- } catch (error) {
824
- const dbError = new typings_1.DatabaseError(error, 'fetch translation');
825
- this.logError(dbError, 'fetch');
826
- return false; // Don't throw, let translation proceed
827
- }
828
- }
829
- async insert(key, lang, data) {
830
- try {
831
- if (!key || !lang || !data) {
832
- throw new typings_1.ValidationError('insert parameters', { key, lang, data });
833
- }
834
- await this.retryOperation(async () => {
835
- return await this.sql.query(`INSERT IGNORE INTO translations (\`key\`, \`lang\`, \`value\`) VALUES (?, ?, ?)`, [
836
- key,
837
- lang,
838
- data.value,
839
- ]);
840
- }, 'insert translation');
841
- } catch (error) {
842
- const dbError = new typings_1.DatabaseError(error, 'insert translation');
843
- this.logError(dbError, 'insert');
844
- throw dbError;
845
- }
846
- }
847
- async fetchLang(lang) {
848
- try {
849
- if (!lang) {
850
- throw new typings_1.ValidationError('lang', lang);
851
- }
852
- return await this.retryOperation(async () => {
853
- return await this.sql.query(
854
- `SELECT \`key\`, \`lang\`, \`value\`, \`verified\`, \`created_at\` FROM translations WHERE \`lang\`=?`,
855
- [lang],
856
- );
857
- }, 'fetchLang');
858
- } catch (error) {
859
- const dbError = new typings_1.DatabaseError(error, 'fetch language translations');
860
- this.logError(dbError, 'fetchLang');
861
- throw dbError;
862
- }
863
- }
864
- async fetchAllGrouped() {
865
- try {
866
- const output = {};
867
- const allTranslations = await this.fetchAll();
868
- allTranslations.forEach((translation) => {
869
- const { key } = translation;
870
- if (!output.hasOwnProperty(key)) {
871
- output[key] = [];
872
- }
873
- output[key].push(translation);
874
- });
875
- return output;
876
- } catch (error) {
877
- const dbError = new typings_1.DatabaseError(error, 'fetch all grouped translations');
878
- this.logError(dbError, 'fetchAllGrouped');
879
- throw dbError;
880
- }
881
- }
882
- async fetchAll() {
883
- try {
884
- return await this.retryOperation(async () => {
885
- return await this.sql.query(
886
- `SELECT \`key\`, \`lang\`, \`value\`, \`verified\`, \`created_at\` FROM translations`,
887
- );
888
- }, 'fetchAll');
889
- } catch (error) {
890
- const dbError = new typings_1.DatabaseError(error, 'fetch all translations');
891
- this.logError(dbError, 'fetchAll');
892
- throw dbError;
893
- }
894
- }
895
- }
896
- exports.ZTranslateService = ZTranslateService;
897
- function strContainsLetters(text) {
898
- // Updated regex to include Arabic characters (U+0600-U+06FF) and other scripts
899
- const regExp = /[a-zA-Z\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/g;
900
- return regExp.test(text);
901
- }
902
- function genSpaces(length) {
903
- let output = '';
904
- for (let i = 0; i < length; i++) {
905
- output += ' ';
906
- }
907
- return output;
908
- }