ztechno_core 0.0.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/LICENSE +1 -0
- package/README.md +81 -0
- package/lib/crypto_service.d.ts +10 -0
- package/lib/crypto_service.js +59 -0
- package/lib/mail_service.d.ts +19 -0
- package/lib/mail_service.js +34 -0
- package/lib/sql_service.d.ts +7 -0
- package/lib/sql_service.js +78 -0
- package/lib/translate_service.d.ts +46 -0
- package/lib/translate_service.js +243 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# ztech_jquery_ext
|
|
2
|
+
#### Extends JQuery library for more compact code base
|
|
3
|
+
|
|
4
|
+
[](https://www.npmjs.com/package/ztech_jquery_ext)
|
|
5
|
+
|
|
6
|
+
Requirements
|
|
7
|
+
-----
|
|
8
|
+
+ [jQuery](http://jquery.com/)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Installation
|
|
12
|
+
-----
|
|
13
|
+
|
|
14
|
+
### [NPM](https://www.npmjs.com/package/ztech_jquery_ext)
|
|
15
|
+
```bash
|
|
16
|
+
npm install ztech_jquery_ext
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### [Yarn](https://yarn.pm/ztech_jquery_ext)
|
|
20
|
+
```bash
|
|
21
|
+
yarn add ztech_jquery_ext
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### [CDN - jsDelivr](https://www.jsdelivr.com/package/npm/ztech_jquery_ext)
|
|
25
|
+
```html
|
|
26
|
+
<link href="https://cdn.jsdelivr.net/npm/ztech_jquery_ext/dist/css/ztech_jquery_ext.min.css" rel="stylesheet" type="text/css" />
|
|
27
|
+
<script src="https://cdn.jsdelivr.net/npm/ztech_jquery_ext/dist/js/ztech_jquery_ext.min.js" type="text/javascript"></script>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### [CDN - UNPKG](https://unpkg.com/browse/ztech_jquery_ext/)
|
|
31
|
+
```html
|
|
32
|
+
<link href="https://unpkg.com/ztech_jquery_ext/dist/css/ztech_jquery_ext.min.css" rel="stylesheet" type="text/css" />
|
|
33
|
+
<script src="https://unpkg.com/ztech_jquery_ext/dist/js/ztech_jquery_ext.min.js" type="text/javascript"></script>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
TypeScript Support
|
|
37
|
+
-----
|
|
38
|
+
In order to include types add the following in tsconfig.json
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"compilerOptions": {
|
|
42
|
+
"types": ["ztech_jquery_ext"]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Alternatively Add the following reference at the top of the javascript/typescript file
|
|
48
|
+
```js
|
|
49
|
+
/// <reference types="ztech_jquery_ext" />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Usage
|
|
53
|
+
-----
|
|
54
|
+
|
|
55
|
+
Include jQuery
|
|
56
|
+
```html
|
|
57
|
+
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Include Plugin JS
|
|
61
|
+
```html
|
|
62
|
+
<script src="https://cdn.jsdelivr.net/npm/ztech_jquery_ext/dist/js/ztech_jquery_ext.min.js" type="text/javascript"></script>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Usage
|
|
66
|
+
```js
|
|
67
|
+
// [JQuery, JQuery, JQuery, ...]
|
|
68
|
+
var rows = $('.row').$arr();
|
|
69
|
+
|
|
70
|
+
// [number, number, number, ...]
|
|
71
|
+
var userids = $('.user').$map(function ($ele) {
|
|
72
|
+
return $ele.attr('id');
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
License
|
|
77
|
+
----
|
|
78
|
+
MIT
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
Created with :heart: [create-jquery-plugin](https://www.npmjs.com/package/create-jquery-plugin)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare type HashStruct = {
|
|
2
|
+
iv: string;
|
|
3
|
+
encryptedData: string;
|
|
4
|
+
};
|
|
5
|
+
export declare class ZCryptoService {
|
|
6
|
+
static encrypt(text: string): HashStruct;
|
|
7
|
+
static decrypt(data: HashStruct): string;
|
|
8
|
+
static decryptJSON(data: HashStruct): any;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ZCryptoService = void 0;
|
|
27
|
+
const crypto = __importStar(require("crypto"));
|
|
28
|
+
const algorithm = 'aes-256-cbc';
|
|
29
|
+
const key = Buffer.from([
|
|
30
|
+
253, 144, 73, 128, 71, 94, 34, 3, 28, 128, 194, 166, 132, 154, 14, 87, 221, 202, 92, 56, 139, 10, 38, 122, 120, 7,
|
|
31
|
+
149, 40, 211, 218, 217, 3,
|
|
32
|
+
]);
|
|
33
|
+
const iv = Buffer.from([0, 209, 223, 20, 147, 45, 14, 107, 93, 6, 76, 206, 176, 55, 245, 134]);
|
|
34
|
+
class ZCryptoService {
|
|
35
|
+
static encrypt(text) {
|
|
36
|
+
const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
|
|
37
|
+
let encrypted = cipher.update(text);
|
|
38
|
+
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
|
39
|
+
return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };
|
|
40
|
+
}
|
|
41
|
+
static decrypt(data) {
|
|
42
|
+
const niv = Buffer.from(data.iv, 'hex');
|
|
43
|
+
const encryptedText = Buffer.from(data.encryptedData, 'hex');
|
|
44
|
+
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), niv);
|
|
45
|
+
let decrypted = decipher.update(encryptedText);
|
|
46
|
+
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
47
|
+
return decrypted.toString();
|
|
48
|
+
}
|
|
49
|
+
static decryptJSON(data) {
|
|
50
|
+
try {
|
|
51
|
+
const decrypted = ZCryptoService.decrypt(data);
|
|
52
|
+
return JSON.parse(decrypted);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw new Error(`Couldn't decrypt JSON ${JSON.stringify(data)}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.ZCryptoService = ZCryptoService;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare type MailServiceOptions = {
|
|
2
|
+
auth: {
|
|
3
|
+
user: string;
|
|
4
|
+
pass: string;
|
|
5
|
+
};
|
|
6
|
+
mailSender: string;
|
|
7
|
+
};
|
|
8
|
+
declare type MailOptions = {
|
|
9
|
+
recipient: string;
|
|
10
|
+
subject: string;
|
|
11
|
+
body: string;
|
|
12
|
+
};
|
|
13
|
+
export declare class ZMailService {
|
|
14
|
+
private opt;
|
|
15
|
+
constructor(opt: MailServiceOptions);
|
|
16
|
+
send(mailOpts: MailOptions): Promise<any>;
|
|
17
|
+
static get(opt: MailServiceOptions): ZMailService;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ZMailService = void 0;
|
|
4
|
+
const nodemailer = require('nodemailer');
|
|
5
|
+
let instance = null;
|
|
6
|
+
class ZMailService {
|
|
7
|
+
constructor(opt) {
|
|
8
|
+
this.opt = opt;
|
|
9
|
+
}
|
|
10
|
+
send(mailOpts) {
|
|
11
|
+
const mailTransporter = nodemailer.createTransport({
|
|
12
|
+
service: 'gmail',
|
|
13
|
+
auth: this.opt.auth,
|
|
14
|
+
});
|
|
15
|
+
const mailDetails = {
|
|
16
|
+
from: this.opt.mailSender,
|
|
17
|
+
to: mailOpts.recipient,
|
|
18
|
+
subject: mailOpts.subject,
|
|
19
|
+
text: mailOpts.body,
|
|
20
|
+
};
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
mailTransporter.sendMail(mailDetails, function (err, data) {
|
|
23
|
+
return err ? reject(err) : resolve('success'); // data)
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
static get(opt) {
|
|
28
|
+
if (instance == null) {
|
|
29
|
+
instance = new ZMailService(opt);
|
|
30
|
+
}
|
|
31
|
+
return instance;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.ZMailService = ZMailService;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.ZSqlService = void 0;
|
|
36
|
+
const mysql = __importStar(require("mysql"));
|
|
37
|
+
let instance = null;
|
|
38
|
+
const logError = (err) => {
|
|
39
|
+
if (err)
|
|
40
|
+
throw err;
|
|
41
|
+
};
|
|
42
|
+
let creds;
|
|
43
|
+
class ZSqlService {
|
|
44
|
+
static init(credentials) {
|
|
45
|
+
creds = credentials;
|
|
46
|
+
}
|
|
47
|
+
connect() {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const con = mysql.createConnection(creds);
|
|
50
|
+
con.connect((err) => {
|
|
51
|
+
if (err)
|
|
52
|
+
return reject(err);
|
|
53
|
+
resolve(con);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
query(sql, escaped = []) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const con = yield this.connect();
|
|
60
|
+
const output = yield new Promise((resolve, reject) => {
|
|
61
|
+
con.query(sql, escaped, (err, result) => {
|
|
62
|
+
if (err)
|
|
63
|
+
return reject(err);
|
|
64
|
+
resolve(result);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
con.end(logError);
|
|
68
|
+
return output;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
static get() {
|
|
72
|
+
if (instance == null) {
|
|
73
|
+
instance = new ZSqlService();
|
|
74
|
+
}
|
|
75
|
+
return instance;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.ZSqlService = ZSqlService;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
declare type TranslateData = {
|
|
2
|
+
value: string;
|
|
3
|
+
meta?: {
|
|
4
|
+
prefix: string;
|
|
5
|
+
suffix: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
declare type dbTranslationRow = {
|
|
9
|
+
lang: string;
|
|
10
|
+
key: string;
|
|
11
|
+
value: string;
|
|
12
|
+
};
|
|
13
|
+
export declare class TranslateService {
|
|
14
|
+
private localCache;
|
|
15
|
+
surpressErrors: boolean;
|
|
16
|
+
getLanguages(): string[];
|
|
17
|
+
getSourceLang(): string;
|
|
18
|
+
getDefaultLang(): string;
|
|
19
|
+
constructor();
|
|
20
|
+
static init(opt: {
|
|
21
|
+
key: string;
|
|
22
|
+
}): void;
|
|
23
|
+
private codes;
|
|
24
|
+
getLang(cookies: {
|
|
25
|
+
[key: string]: string;
|
|
26
|
+
}): string;
|
|
27
|
+
translateText(langOrReq: string | any, text: string): Promise<string>;
|
|
28
|
+
translateHtml(html: string, cookies: {
|
|
29
|
+
lang: string;
|
|
30
|
+
[key: string]: string;
|
|
31
|
+
}): Promise<string>;
|
|
32
|
+
private translateHtmlRec;
|
|
33
|
+
update(key: string, lang: string, data: TranslateData): Promise<any>;
|
|
34
|
+
private checkLocalCache;
|
|
35
|
+
private insertLocalCache;
|
|
36
|
+
private clearLocalCache;
|
|
37
|
+
private fetch;
|
|
38
|
+
private insert;
|
|
39
|
+
private fetchLang;
|
|
40
|
+
fetchAllGrouped(): Promise<{
|
|
41
|
+
[key: string]: dbTranslationRow[];
|
|
42
|
+
}>;
|
|
43
|
+
private fetchAll;
|
|
44
|
+
static get(): TranslateService;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TranslateService = void 0;
|
|
13
|
+
const sql_service_1 = require("./sql_service");
|
|
14
|
+
const DomParser = require('dom-parser');
|
|
15
|
+
const translate = require('translate');
|
|
16
|
+
const htmlParser = new DomParser();
|
|
17
|
+
const sql = sql_service_1.ZSqlService.get();
|
|
18
|
+
let instance = null;
|
|
19
|
+
class TranslateService {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.localCache = {};
|
|
22
|
+
this.surpressErrors = true;
|
|
23
|
+
this.codes = {
|
|
24
|
+
[`'`]: `'`,
|
|
25
|
+
[`"`]: `"`,
|
|
26
|
+
[`“`]: `“`,
|
|
27
|
+
[`”`]: `”`,
|
|
28
|
+
[`©`]: `©`,
|
|
29
|
+
[`®`]: `®`,
|
|
30
|
+
[`€`]: `€`,
|
|
31
|
+
[`£`]: `£`,
|
|
32
|
+
[`™`]: `™`,
|
|
33
|
+
};
|
|
34
|
+
this.getLanguages().map((lang) => (this.localCache[lang] = {}));
|
|
35
|
+
setInterval(() => this.clearLocalCache(), 1000 * 60 * 60); // Every Hour
|
|
36
|
+
}
|
|
37
|
+
getLanguages() {
|
|
38
|
+
return ['en', 'nl'];
|
|
39
|
+
}
|
|
40
|
+
getSourceLang() {
|
|
41
|
+
return 'nl';
|
|
42
|
+
}
|
|
43
|
+
getDefaultLang() {
|
|
44
|
+
return 'nl';
|
|
45
|
+
}
|
|
46
|
+
static init(opt) {
|
|
47
|
+
translate.key = opt.key;
|
|
48
|
+
}
|
|
49
|
+
getLang(cookies) {
|
|
50
|
+
const defaultLang = this.getDefaultLang();
|
|
51
|
+
const langKey = (cookies.lang || defaultLang).toLowerCase();
|
|
52
|
+
const langs = this.getLanguages();
|
|
53
|
+
if (!langs.includes(langKey)) {
|
|
54
|
+
return defaultLang;
|
|
55
|
+
}
|
|
56
|
+
return langKey;
|
|
57
|
+
}
|
|
58
|
+
translateText(langOrReq, text) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const lang = typeof langOrReq === 'string' ? langOrReq : this.getLang(langOrReq.cookies);
|
|
61
|
+
text = text.trim();
|
|
62
|
+
if (text.length === 1) {
|
|
63
|
+
return text;
|
|
64
|
+
}
|
|
65
|
+
let replaceCount = 0;
|
|
66
|
+
while (text.includes('&#')) {
|
|
67
|
+
const codeIndexStart = text.indexOf('&#');
|
|
68
|
+
const first = text.substring(codeIndexStart);
|
|
69
|
+
const codeLength = first.indexOf(';') + 1;
|
|
70
|
+
const code = first.substring(0, codeLength);
|
|
71
|
+
if (this.codes[code] === undefined) {
|
|
72
|
+
throw new Error(`Cant recognize character code="${code}"\n for text=${text}\n\n`);
|
|
73
|
+
// return text
|
|
74
|
+
}
|
|
75
|
+
text = text.substring(0, codeIndexStart) + this.codes[text] + text.substring(codeIndexStart + codeLength);
|
|
76
|
+
// text = text.replace(code, codes[text])
|
|
77
|
+
if (replaceCount++ > 1000) {
|
|
78
|
+
throw new Error(`Replace Count > 1000!!! character code="${code}"\n for text=${text}\n\n`);
|
|
79
|
+
// return text
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const localCached = this.checkLocalCache(text, lang);
|
|
83
|
+
if (localCached !== false) {
|
|
84
|
+
return localCached.value;
|
|
85
|
+
}
|
|
86
|
+
const remoteCached = yield this.fetch(text, lang);
|
|
87
|
+
if (remoteCached !== false) {
|
|
88
|
+
return remoteCached.value;
|
|
89
|
+
}
|
|
90
|
+
let result;
|
|
91
|
+
try {
|
|
92
|
+
result = yield translate(text, {
|
|
93
|
+
from: this.getSourceLang(),
|
|
94
|
+
to: lang,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
result = '?';
|
|
99
|
+
}
|
|
100
|
+
yield this.insert(text, lang, { value: result });
|
|
101
|
+
return result;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
translateHtml(html, cookies) {
|
|
105
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
const lang = this.getLang(cookies);
|
|
107
|
+
const defaultLang = this.getDefaultLang();
|
|
108
|
+
const dom = htmlParser.parseFromString(html);
|
|
109
|
+
const htmlNodes = dom.getElementsByTagName('html');
|
|
110
|
+
const mainNodes = dom.getElementsByTagName('main');
|
|
111
|
+
const isView = htmlNodes.length === 0;
|
|
112
|
+
const domNode = isView ? mainNodes[0] : htmlNodes[0];
|
|
113
|
+
if (lang !== defaultLang) {
|
|
114
|
+
const node = isView ? domNode : domNode.getElementsByTagName('body')[0];
|
|
115
|
+
const promises = [];
|
|
116
|
+
this.translateHtmlRec(lang, node, promises);
|
|
117
|
+
yield Promise.all(promises);
|
|
118
|
+
}
|
|
119
|
+
const output = domNode ? domNode.outerHTML : html;
|
|
120
|
+
return output.startsWith(`<!DOCTYPE html>`) ? output : `<!DOCTYPE html>\r\n${output}`;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
translateHtmlRec(lang, node, promises, skipTranslate = false) {
|
|
124
|
+
if (node.getAttribute('notranslate') != null) {
|
|
125
|
+
skipTranslate = true;
|
|
126
|
+
}
|
|
127
|
+
if (node.nodeName === '#text') {
|
|
128
|
+
const nodeText = node;
|
|
129
|
+
const text = nodeText.text.replace(/[\r|\n|\r\n]+/g, ' ').replace(/\s\s+/g, ' ');
|
|
130
|
+
const value = text.trim();
|
|
131
|
+
const meta = {
|
|
132
|
+
prefix: genSpaces(text.length - text.trimStart().length),
|
|
133
|
+
suffix: genSpaces(text.length - text.trimEnd().length),
|
|
134
|
+
};
|
|
135
|
+
if (skipTranslate === true || text.length === 0 || !strContainsLetters(text)) {
|
|
136
|
+
node.text = meta.prefix + text + meta.suffix;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
promises.push(this.translateText(lang, value)
|
|
140
|
+
.then((translatedText) => {
|
|
141
|
+
node.text = meta.prefix + translatedText + meta.suffix;
|
|
142
|
+
})
|
|
143
|
+
.catch((err) => {
|
|
144
|
+
node.text = text;
|
|
145
|
+
if (!this.surpressErrors) {
|
|
146
|
+
throw err; // TODO: Find out if surpressing is better
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// const hasChildren = node.childNodes !== undefined
|
|
152
|
+
for (const child of node.childNodes || []) {
|
|
153
|
+
this.translateHtmlRec(lang, child, promises, skipTranslate);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
update(key, lang, data) {
|
|
157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
158
|
+
return yield sql.query(`
|
|
159
|
+
INSERT INTO translations
|
|
160
|
+
(\`key\`, \`lang\`, \`value\`)
|
|
161
|
+
VALUES
|
|
162
|
+
(?, ?, ?)
|
|
163
|
+
ON DUPLICATE KEY UPDATE value=?
|
|
164
|
+
`, [key, lang, data.value, data.value]);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
checkLocalCache(key, lang) {
|
|
168
|
+
const hasLocal = !this.localCache[lang].hasOwnProperty(key);
|
|
169
|
+
return hasLocal ? false : this.localCache[lang][key];
|
|
170
|
+
}
|
|
171
|
+
insertLocalCache(key, lang, data) {
|
|
172
|
+
if (this.localCache[lang].hasOwnProperty(key)) {
|
|
173
|
+
// console.warn(`Translations already cached!`, { key, lang, data})
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.localCache[lang][key] = data;
|
|
177
|
+
}
|
|
178
|
+
clearLocalCache() {
|
|
179
|
+
Object.keys(this.localCache).map((k) => {
|
|
180
|
+
this.localCache[k] = {};
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
fetch(key, lang) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
const results = yield sql.query(`SELECT \`value\` FROM translations WHERE \`lang\`=? AND \`key\`=?`, [lang, key]);
|
|
186
|
+
if (results.length > 0) {
|
|
187
|
+
// api.query(`UPDATE translations SET last_used=CURRENT_TIMESTAMP WHERE \`lang\`=? AND \`key\`=?`, [lang, key])
|
|
188
|
+
// .catch(err => console.error(err))
|
|
189
|
+
const { value } = results[0];
|
|
190
|
+
this.insertLocalCache(key, lang, { value });
|
|
191
|
+
return { value };
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
insert(key, lang, data) {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
yield sql.query(`INSERT IGNORE INTO translations (\`key\`, \`lang\`, \`value\`) VALUES (?, ?, ?)`, [
|
|
199
|
+
key,
|
|
200
|
+
lang,
|
|
201
|
+
data.value,
|
|
202
|
+
]);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
fetchLang(lang) {
|
|
206
|
+
return sql.query(`SELECT \`key\`, \`lang\`, \`value\`, \`verified\`, \`created_at\` FROM translations WHERE \`lang\`=?`, [lang]);
|
|
207
|
+
}
|
|
208
|
+
fetchAllGrouped() {
|
|
209
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
210
|
+
const output = {};
|
|
211
|
+
const allTranslations = yield this.fetchAll();
|
|
212
|
+
allTranslations.map((translation) => {
|
|
213
|
+
const { key } = translation;
|
|
214
|
+
if (!output.hasOwnProperty(key)) {
|
|
215
|
+
output[key] = [];
|
|
216
|
+
}
|
|
217
|
+
output[key].push(translation);
|
|
218
|
+
});
|
|
219
|
+
return output;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
fetchAll() {
|
|
223
|
+
return sql.query(`SELECT \`key\`, \`lang\`, \`value\`, \`verified\`, \`created_at\` FROM translations`);
|
|
224
|
+
}
|
|
225
|
+
static get() {
|
|
226
|
+
if (instance == null) {
|
|
227
|
+
instance = new TranslateService();
|
|
228
|
+
}
|
|
229
|
+
return instance;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.TranslateService = TranslateService;
|
|
233
|
+
function strContainsLetters(text) {
|
|
234
|
+
const regExp = /[a-zA-Z]/g;
|
|
235
|
+
return regExp.test(text);
|
|
236
|
+
}
|
|
237
|
+
function genSpaces(length) {
|
|
238
|
+
let output = '';
|
|
239
|
+
for (let i = 0; i < length; i++) {
|
|
240
|
+
output += ' ';
|
|
241
|
+
}
|
|
242
|
+
return output;
|
|
243
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ztechno_core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Core files for ztechno framework",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "Ivan Auda (ZTechnologies International)",
|
|
9
|
+
"typings": "index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"lib/**/*"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "jest --config jestconfig.json",
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
|
|
17
|
+
"lint": "tslint -p tsconfig.json",
|
|
18
|
+
"preversion" : "npm run lint",
|
|
19
|
+
"version" : "npm run format && git add -A src",
|
|
20
|
+
"postversion" : "git push && git push --tags"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"ztechno",
|
|
24
|
+
"core",
|
|
25
|
+
"utils",
|
|
26
|
+
"service"
|
|
27
|
+
],
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/jest": "^29.2.3",
|
|
30
|
+
"@types/mysql": "^2.15.21",
|
|
31
|
+
"jest": "^29.3.1",
|
|
32
|
+
"prettier": "^2.7.1",
|
|
33
|
+
"ts-jest": "^29.0.3",
|
|
34
|
+
"tslint": "^6.1.3",
|
|
35
|
+
"tslint-config-prettier": "^1.18.0",
|
|
36
|
+
"typescript": "^4.9.3"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"dom-parser": "^0.1.6",
|
|
40
|
+
"mysql": "^2.18.1",
|
|
41
|
+
"nodemailer": "^6.8.0",
|
|
42
|
+
"translate": "^1.4.1"
|
|
43
|
+
}
|
|
44
|
+
}
|