tinker-translate 0.1.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.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # tinker-translate
2
+
3
+ A translation plugin for [TINKER](https://github.com/liriliri/tinker), supporting Google, Bing, and DeepL translation services.
4
+
5
+ ![Screenshot](https://raw.githubusercontent.com/liriliri/tinker-plugins/master/packages/tinker-translate/screenshot.png)
6
+
7
+ ## Features
8
+
9
+ - **Google, Bing & DeepL** translation services
10
+ - **16+ languages** support
11
+ - **Auto-detect** source language
12
+ - **i18n** support for English and Chinese
13
+
14
+ ## Installation
15
+
16
+ Download and install TINKER from `https://tinker.liriliri.io/`, then run `npm i -g tinker-translate`.
17
+
18
+ ## Usage
19
+
20
+ 1. Select translation service (Google, Bing, or DeepL)
21
+ 2. Enter text in the source text area
22
+ 3. Select source and target languages
23
+ 4. Click "Translate" button
24
+ 5. View the translated text in the result area
@@ -0,0 +1,153 @@
1
+ import { contextBridge as g } from "electron";
2
+ import f from "https";
3
+ function m(n, t) {
4
+ return new Promise((e, s) => {
5
+ const a = f.request(n, (o) => {
6
+ let c = "";
7
+ o.on("data", (i) => {
8
+ c += i;
9
+ }), o.on("end", () => {
10
+ e({ statusCode: o.statusCode, data: c });
11
+ });
12
+ });
13
+ a.on("error", s), t && a.write(t), a.end();
14
+ });
15
+ }
16
+ async function w(n, t, e) {
17
+ const a = {
18
+ hostname: "translate.google.com",
19
+ port: 443,
20
+ path: `/translate_a/single?dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&${new URLSearchParams({
21
+ client: "gtx",
22
+ sl: t,
23
+ tl: e,
24
+ hl: e,
25
+ ie: "UTF-8",
26
+ oe: "UTF-8",
27
+ otf: "1",
28
+ ssel: "0",
29
+ tsel: "0",
30
+ kc: "7",
31
+ q: n
32
+ }).toString()}`,
33
+ method: "GET",
34
+ headers: {
35
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
36
+ }
37
+ }, { statusCode: o, data: c } = await m(a);
38
+ if (o !== 200) throw new Error(`HTTP Error: ${o}`);
39
+ const i = JSON.parse(c);
40
+ let l = "";
41
+ if (i[0])
42
+ for (const r of i[0])
43
+ r[0] && (l += r[0]);
44
+ return { text: l.trim(), from: t, to: e };
45
+ }
46
+ async function T() {
47
+ const n = {
48
+ hostname: "edge.microsoft.com",
49
+ port: 443,
50
+ path: "/translate/auth",
51
+ method: "GET",
52
+ headers: {
53
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"
54
+ }
55
+ }, { statusCode: t, data: e } = await m(n);
56
+ if (t !== 200) throw new Error(`Failed to get token: ${t}`);
57
+ return e;
58
+ }
59
+ async function S(n, t, e) {
60
+ var d, p, h;
61
+ const s = await T(), a = new URLSearchParams({
62
+ from: t === "auto" ? "" : t,
63
+ to: e,
64
+ "api-version": "3.0",
65
+ includeSentenceLength: "true"
66
+ }), o = JSON.stringify([{ Text: n }]), c = {
67
+ hostname: "api-edge.cognitive.microsofttranslator.com",
68
+ port: 443,
69
+ path: `/translate?${a.toString()}`,
70
+ method: "POST",
71
+ headers: {
72
+ accept: "*/*",
73
+ "accept-language": "zh-TW,zh;q=0.9,ja;q=0.8,zh-CN;q=0.7,en-US;q=0.6,en;q=0.5",
74
+ authorization: "Bearer " + s,
75
+ "cache-control": "no-cache",
76
+ "content-type": "application/json",
77
+ "content-length": Buffer.byteLength(o),
78
+ pragma: "no-cache",
79
+ "sec-ch-ua": '"Microsoft Edge";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
80
+ "sec-ch-ua-mobile": "?0",
81
+ "sec-ch-ua-platform": '"Windows"',
82
+ "sec-fetch-dest": "empty",
83
+ "sec-fetch-mode": "cors",
84
+ "sec-fetch-site": "cross-site",
85
+ Referer: "https://appsumo.com/",
86
+ "Referrer-Policy": "strict-origin-when-cross-origin",
87
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"
88
+ }
89
+ }, { statusCode: i, data: l } = await m(c, o);
90
+ if (i !== 200) throw new Error(`HTTP Error: ${i}`);
91
+ const r = JSON.parse(l);
92
+ if (!((h = (p = (d = r[0]) == null ? void 0 : d.translations) == null ? void 0 : p[0]) != null && h.text))
93
+ throw new Error("Invalid response format");
94
+ return { text: r[0].translations[0].text.trim(), from: t, to: e };
95
+ }
96
+ function x(n) {
97
+ return n.split("i").length - 1;
98
+ }
99
+ function y(n) {
100
+ const t = Date.now();
101
+ if (n !== 0) {
102
+ const e = n + 1;
103
+ return t - t % e + e;
104
+ }
105
+ return t;
106
+ }
107
+ function C() {
108
+ return (Math.floor(Math.random() * 99999) + 1e5) * 1e3;
109
+ }
110
+ async function E(n, t, e) {
111
+ var d, p, h, u;
112
+ const s = C(), a = {
113
+ jsonrpc: "2.0",
114
+ method: "LMT_handle_texts",
115
+ id: s,
116
+ params: {
117
+ splitting: "newlines",
118
+ lang: {
119
+ source_lang_user_selected: t !== "auto" ? t.slice(0, 2).toUpperCase() : "auto",
120
+ target_lang: e.slice(0, 2).toUpperCase()
121
+ },
122
+ texts: [{ text: n, requestAlternatives: 3 }],
123
+ timestamp: y(x(n))
124
+ }
125
+ };
126
+ let o = JSON.stringify(a);
127
+ (s + 5) % 29 === 0 || (s + 3) % 13 === 0 ? o = o.replace('"method":"', '"method" : "') : o = o.replace('"method":"', '"method": "');
128
+ const c = {
129
+ hostname: "www2.deepl.com",
130
+ port: 443,
131
+ path: "/jsonrpc",
132
+ method: "POST",
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ "Content-Length": Buffer.byteLength(o)
136
+ }
137
+ }, { statusCode: i, data: l } = await m(c, o);
138
+ if (i !== 200) throw new Error(`HTTP Error: ${i}`);
139
+ const r = JSON.parse(l);
140
+ if ((h = (p = (d = r == null ? void 0 : r.result) == null ? void 0 : d.texts) == null ? void 0 : p[0]) != null && h.text)
141
+ return { text: r.result.texts[0].text.trim(), from: t, to: e };
142
+ throw new Error(((u = r == null ? void 0 : r.error) == null ? void 0 : u.message) ?? "Invalid response format");
143
+ }
144
+ const L = {
145
+ translate: async (n, t, e, s = "google") => {
146
+ try {
147
+ return s === "bing" ? await S(n, t, e) : s === "deepl" ? await E(n, t, e) : await w(n, t, e);
148
+ } catch (a) {
149
+ throw console.error("Translation failed:", a), a;
150
+ }
151
+ }
152
+ };
153
+ g.exposeInMainWorld("translate", L);