@ecosplay/e-translate 1.1.0 → 1.1.2
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 +21 -0
- package/README.md +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -34
- package/dist/index.d.ts +34 -34
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +37 -37
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Association E-Cosplay
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -53,8 +53,8 @@ var ETranslateClient = class {
|
|
|
53
53
|
this.fetchImpl = f;
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
56
|
+
* Translate a text (or an array of texts).
|
|
57
|
+
* Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.
|
|
58
58
|
*/
|
|
59
59
|
async translate(params) {
|
|
60
60
|
if (params?.message == null) {
|
|
@@ -69,16 +69,16 @@ var ETranslateClient = class {
|
|
|
69
69
|
format: params.format ?? "text"
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
|
-
/**
|
|
72
|
+
/** Detect the language of a text via `POST /detect`. */
|
|
73
73
|
async detect(text) {
|
|
74
74
|
if (!text) throw new Error("detect: 'text' is required.");
|
|
75
75
|
return this.request("POST", "/detect", { q: text });
|
|
76
76
|
}
|
|
77
|
-
/**
|
|
77
|
+
/** List supported languages via `GET /languages`. */
|
|
78
78
|
async languages() {
|
|
79
79
|
return this.request("GET", "/languages");
|
|
80
80
|
}
|
|
81
|
-
/**
|
|
81
|
+
/** Service health via `GET /health` (no API key required). */
|
|
82
82
|
async health() {
|
|
83
83
|
return this.request("GET", "/health", void 0, { auth: false });
|
|
84
84
|
}
|
|
@@ -115,7 +115,7 @@ var ETranslateClient = class {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
if (!resp.ok) {
|
|
118
|
-
const message = data && typeof data === "object" && "error" in data ? String(data.error) : `HTTP ${resp.status}
|
|
118
|
+
const message = data && typeof data === "object" && "error" in data ? String(data.error) : `HTTP ${resp.status} on ${path}`;
|
|
119
119
|
throw new ETranslateError(message, resp.status, data);
|
|
120
120
|
}
|
|
121
121
|
return data;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * e-translate SDK — client TypeScript/JavaScript pour l'API e-translate.\n *\n * Fonctionne dans Node 18+ (fetch global) et dans le navigateur.\n *\n * @example\n * ```ts\n * import { ETranslateClient } from \"e-translate-sdk\";\n *\n * const client = new ETranslateClient({\n * baseUrl: \"https://translation.e-cosplay.fr\",\n * apiKey: \"etk_xxxxxxxx\",\n * });\n *\n * const res = await client.translate({ message: \"Bonjour\", from: \"fr\", to: \"en\" });\n * console.log(res.translatedText); // \"Hello\"\n * ```\n */\n\n/** Format du texte à traduire. */\nexport type TranslateFormat = \"text\" | \"html\";\n\n/** Méthode HTTP interne. */\ntype HttpMethod = \"GET\" | \"POST\";\n\n/** Options de construction du client. */\nexport interface ETranslateOptions {\n /** URL de base du serveur, ex. \"https://translation.e-cosplay.fr\". */\n baseUrl: string;\n /** Clé d'API (`etk_...`). Requise pour /translate, /detect, /languages. */\n apiKey: string;\n /** Timeout par requête en millisecondes (défaut : 20000). */\n timeoutMs?: number;\n /** Implémentation `fetch` personnalisée (Node < 18, tests). Défaut : `globalThis.fetch`. */\n fetch?: typeof fetch;\n /** En-têtes HTTP supplémentaires envoyés à chaque requête. */\n headers?: Record<string, string>;\n}\n\n/** Paramètres de traduction. */\nexport interface TranslateParams {\n /** Texte (ou tableau de textes) à traduire. */\n message: string | string[];\n /** Langue source (code ISO, ex. \"fr\") ou \"auto\" pour la détection automatique. */\n from: string;\n /** Langue cible (code ISO, ex. \"en\"). */\n to: string;\n /** Format du texte (défaut : \"text\"). */\n format?: TranslateFormat;\n}\n\n/** Langue détectée renvoyée par /detect ou en mode \"auto\". */\nexport interface DetectedLanguage {\n /** Indice de confiance (0–100). */\n confidence: number;\n /** Code ISO de la langue détectée. */\n language: string;\n}\n\n/** Résultat d'une traduction. */\nexport interface TranslateResult {\n /** Texte traduit (string si `message` était une string, sinon string[]). */\n translatedText: string | string[];\n /** `true` si la réponse provient du cache Redis. */\n cached: boolean;\n /** Présent uniquement si `from` valait \"auto\". */\n detectedLanguage?: DetectedLanguage;\n}\n\n/** Une langue supportée par le serveur. */\nexport interface Language {\n code: string;\n name: string;\n targets?: string[];\n}\n\n/** Réponse de /health (aucune clé requise). */\nexport interface HealthResult {\n status: string;\n redis: boolean;\n /** Disponibilité du moteur de traduction en amont. */\n engine: boolean;\n time: string;\n}\n\n/**\n * Erreur levée pour toute réponse non-2xx ou tout échec réseau.\n * `status` vaut 0 en cas d'échec réseau / timeout.\n */\nexport class ETranslateError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body?: unknown) {\n super(message);\n this.name = \"ETranslateError\";\n this.status = status;\n this.body = body;\n // Restaure la chaîne de prototype (TS ciblant ES5/ES2015).\n Object.setPrototypeOf(this, ETranslateError.prototype);\n }\n}\n\n/** Client de l'API e-translate. */\nexport class ETranslateClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly extraHeaders: Record<string, string>;\n\n constructor(options: ETranslateOptions) {\n if (!options || typeof options.baseUrl !== \"string\" || options.baseUrl.length === 0) {\n throw new Error(\"ETranslate: the 'baseUrl' option is required.\");\n }\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey ?? \"\";\n this.timeoutMs = options.timeoutMs ?? 20000;\n this.extraHeaders = options.headers ?? {};\n\n const f = options.fetch ?? (globalThis as { fetch?: typeof fetch }).fetch;\n if (typeof f !== \"function\") {\n throw new TypeError(\n \"ETranslate: no `fetch` implementation available. \" +\n \"Use Node >= 18 or pass `options.fetch`.\",\n );\n }\n this.fetchImpl = f;\n }\n\n /**\n * Traduit un texte (ou un tableau de textes).\n * Envoie `lang_src` / `lang_dest` / `message` à `POST /translate`.\n */\n async translate(params: TranslateParams): Promise<TranslateResult> {\n if (params?.message == null) {\n throw new Error(\"translate: 'message' is required.\");\n }\n if (!params.from) throw new Error(\"translate: 'from' is required (e.g. 'fr' or 'auto').\");\n if (!params.to) throw new Error(\"translate: 'to' is required (e.g. 'en').\");\n\n return this.request<TranslateResult>(\"POST\", \"/translate\", {\n lang_src: params.from,\n lang_dest: params.to,\n message: params.message,\n format: params.format ?? \"text\",\n });\n }\n\n /** Détecte la langue d'un texte via `POST /detect`. */\n async detect(text: string): Promise<DetectedLanguage[]> {\n if (!text) throw new Error(\"detect: 'text' is required.\");\n return this.request<DetectedLanguage[]>(\"POST\", \"/detect\", { q: text });\n }\n\n /** Liste les langues supportées via `GET /languages`. */\n async languages(): Promise<Language[]> {\n return this.request<Language[]>(\"GET\", \"/languages\");\n }\n\n /** État du service via `GET /health` (ne nécessite pas de clé API). */\n async health(): Promise<HealthResult> {\n return this.request<HealthResult>(\"GET\", \"/health\", undefined, { auth: false });\n }\n\n private async request<T>(\n method: HttpMethod,\n path: string,\n body?: Record<string, unknown>,\n opts?: { auth?: boolean },\n ): Promise<T> {\n const useAuth = opts?.auth !== false;\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = { Accept: \"application/json\", ...this.extraHeaders };\n if (useAuth) headers[\"X-API-Key\"] = this.apiKey;\n if (body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let resp: Response;\n try {\n resp = await this.fetchImpl(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n const e = err as { name?: string; message?: string };\n const msg =\n e?.name === \"AbortError\"\n ? `Request timed out after ${this.timeoutMs} ms (${path}).`\n : `Network error to ${url}: ${e?.message ?? String(err)}`;\n throw new ETranslateError(msg, 0);\n } finally {\n clearTimeout(timer);\n }\n\n const raw = await resp.text();\n let data: unknown = undefined;\n if (raw) {\n try {\n data = JSON.parse(raw);\n } catch {\n data = raw;\n }\n }\n\n if (!resp.ok) {\n const message =\n data && typeof data === \"object\" && \"error\" in data\n ? String((data as { error: unknown }).error)\n : `HTTP ${resp.status} sur ${path}`;\n throw new ETranslateError(message, resp.status, data);\n }\n\n return data as T;\n }\n}\n\n/** Fabrique pratique équivalente à `new ETranslateClient(options)`. */\nexport function createClient(options: ETranslateOptions): ETranslateClient {\n return new ETranslateClient(options);\n}\n\nexport default ETranslateClient;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * e-translate SDK — TypeScript/JavaScript client for the e-translate API.\n *\n * Works in Node 18+ (global fetch) and in the browser.\n *\n * @example\n * ```ts\n * import { ETranslateClient } from \"@ecosplay/e-translate\";\n *\n * const client = new ETranslateClient({\n * baseUrl: \"https://translation.e-cosplay.fr\",\n * apiKey: \"etk_xxxxxxxx\",\n * });\n *\n * const res = await client.translate({ message: \"Bonjour\", from: \"fr\", to: \"en\" });\n * console.log(res.translatedText); // \"Hello\"\n * ```\n */\n\n/** Format of the text to translate. */\nexport type TranslateFormat = \"text\" | \"html\";\n\n/** Internal HTTP method. */\ntype HttpMethod = \"GET\" | \"POST\";\n\n/** Client construction options. */\nexport interface ETranslateOptions {\n /** Server base URL, e.g. \"https://translation.e-cosplay.fr\". */\n baseUrl: string;\n /** API key (`etk_...`). Required for /translate, /detect, /languages. */\n apiKey: string;\n /** Per-request timeout in milliseconds (default: 20000). */\n timeoutMs?: number;\n /** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */\n fetch?: typeof fetch;\n /** Extra HTTP headers sent on every request. */\n headers?: Record<string, string>;\n}\n\n/** Translation parameters. */\nexport interface TranslateParams {\n /** Text (or array of texts) to translate. */\n message: string | string[];\n /** Source language (ISO code, e.g. \"fr\") or \"auto\" for automatic detection. */\n from: string;\n /** Target language (ISO code, e.g. \"en\"). */\n to: string;\n /** Text format (default: \"text\"). */\n format?: TranslateFormat;\n}\n\n/** Language detected by /detect or in \"auto\" mode. */\nexport interface DetectedLanguage {\n /** Confidence score (0–100). */\n confidence: number;\n /** ISO code of the detected language. */\n language: string;\n}\n\n/** Result of a translation. */\nexport interface TranslateResult {\n /** Translated text (string if `message` was a string, otherwise string[]). */\n translatedText: string | string[];\n /** `true` if the response came from the cache. */\n cached: boolean;\n /** Present only when `from` was \"auto\". */\n detectedLanguage?: DetectedLanguage;\n}\n\n/** A language supported by the server. */\nexport interface Language {\n code: string;\n name: string;\n targets?: string[];\n}\n\n/** Response of /health (no API key required). */\nexport interface HealthResult {\n status: string;\n redis: boolean;\n /** Availability of the upstream translation engine. */\n engine: boolean;\n time: string;\n}\n\n/**\n * Thrown for any non-2xx response or any network failure.\n * `status` is 0 on a network error / timeout.\n */\nexport class ETranslateError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body?: unknown) {\n super(message);\n this.name = \"ETranslateError\";\n this.status = status;\n this.body = body;\n // Restore the prototype chain (TS targeting ES5/ES2015).\n Object.setPrototypeOf(this, ETranslateError.prototype);\n }\n}\n\n/** Client for the e-translate API. */\nexport class ETranslateClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly extraHeaders: Record<string, string>;\n\n constructor(options: ETranslateOptions) {\n if (!options || typeof options.baseUrl !== \"string\" || options.baseUrl.length === 0) {\n throw new Error(\"ETranslate: the 'baseUrl' option is required.\");\n }\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey ?? \"\";\n this.timeoutMs = options.timeoutMs ?? 20000;\n this.extraHeaders = options.headers ?? {};\n\n const f = options.fetch ?? (globalThis as { fetch?: typeof fetch }).fetch;\n if (typeof f !== \"function\") {\n throw new TypeError(\n \"ETranslate: no `fetch` implementation available. \" +\n \"Use Node >= 18 or pass `options.fetch`.\",\n );\n }\n this.fetchImpl = f;\n }\n\n /**\n * Translate a text (or an array of texts).\n * Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.\n */\n async translate(params: TranslateParams): Promise<TranslateResult> {\n if (params?.message == null) {\n throw new Error(\"translate: 'message' is required.\");\n }\n if (!params.from) throw new Error(\"translate: 'from' is required (e.g. 'fr' or 'auto').\");\n if (!params.to) throw new Error(\"translate: 'to' is required (e.g. 'en').\");\n\n return this.request<TranslateResult>(\"POST\", \"/translate\", {\n lang_src: params.from,\n lang_dest: params.to,\n message: params.message,\n format: params.format ?? \"text\",\n });\n }\n\n /** Detect the language of a text via `POST /detect`. */\n async detect(text: string): Promise<DetectedLanguage[]> {\n if (!text) throw new Error(\"detect: 'text' is required.\");\n return this.request<DetectedLanguage[]>(\"POST\", \"/detect\", { q: text });\n }\n\n /** List supported languages via `GET /languages`. */\n async languages(): Promise<Language[]> {\n return this.request<Language[]>(\"GET\", \"/languages\");\n }\n\n /** Service health via `GET /health` (no API key required). */\n async health(): Promise<HealthResult> {\n return this.request<HealthResult>(\"GET\", \"/health\", undefined, { auth: false });\n }\n\n private async request<T>(\n method: HttpMethod,\n path: string,\n body?: Record<string, unknown>,\n opts?: { auth?: boolean },\n ): Promise<T> {\n const useAuth = opts?.auth !== false;\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = { Accept: \"application/json\", ...this.extraHeaders };\n if (useAuth) headers[\"X-API-Key\"] = this.apiKey;\n if (body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let resp: Response;\n try {\n resp = await this.fetchImpl(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n const e = err as { name?: string; message?: string };\n const msg =\n e?.name === \"AbortError\"\n ? `Request timed out after ${this.timeoutMs} ms (${path}).`\n : `Network error to ${url}: ${e?.message ?? String(err)}`;\n throw new ETranslateError(msg, 0);\n } finally {\n clearTimeout(timer);\n }\n\n const raw = await resp.text();\n let data: unknown = undefined;\n if (raw) {\n try {\n data = JSON.parse(raw);\n } catch {\n data = raw;\n }\n }\n\n if (!resp.ok) {\n const message =\n data && typeof data === \"object\" && \"error\" in data\n ? String((data as { error: unknown }).error)\n : `HTTP ${resp.status} on ${path}`;\n throw new ETranslateError(message, resp.status, data);\n }\n\n return data as T;\n }\n}\n\n/** Convenience factory equivalent to `new ETranslateClient(options)`. */\nexport function createClient(options: ETranslateOptions): ETranslateClient {\n return new ETranslateClient(options);\n}\n\nexport default ETranslateClient;\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* e-translate SDK —
|
|
2
|
+
* e-translate SDK — TypeScript/JavaScript client for the e-translate API.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Works in Node 18+ (global fetch) and in the browser.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* import { ETranslateClient } from "e-translate
|
|
8
|
+
* import { ETranslateClient } from "@ecosplay/e-translate";
|
|
9
9
|
*
|
|
10
10
|
* const client = new ETranslateClient({
|
|
11
11
|
* baseUrl: "https://translation.e-cosplay.fr",
|
|
@@ -16,72 +16,72 @@
|
|
|
16
16
|
* console.log(res.translatedText); // "Hello"
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
/** Format
|
|
19
|
+
/** Format of the text to translate. */
|
|
20
20
|
type TranslateFormat = "text" | "html";
|
|
21
|
-
/**
|
|
21
|
+
/** Client construction options. */
|
|
22
22
|
interface ETranslateOptions {
|
|
23
|
-
/**
|
|
23
|
+
/** Server base URL, e.g. "https://translation.e-cosplay.fr". */
|
|
24
24
|
baseUrl: string;
|
|
25
|
-
/**
|
|
25
|
+
/** API key (`etk_...`). Required for /translate, /detect, /languages. */
|
|
26
26
|
apiKey: string;
|
|
27
|
-
/**
|
|
27
|
+
/** Per-request timeout in milliseconds (default: 20000). */
|
|
28
28
|
timeoutMs?: number;
|
|
29
|
-
/**
|
|
29
|
+
/** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */
|
|
30
30
|
fetch?: typeof fetch;
|
|
31
|
-
/**
|
|
31
|
+
/** Extra HTTP headers sent on every request. */
|
|
32
32
|
headers?: Record<string, string>;
|
|
33
33
|
}
|
|
34
|
-
/**
|
|
34
|
+
/** Translation parameters. */
|
|
35
35
|
interface TranslateParams {
|
|
36
|
-
/**
|
|
36
|
+
/** Text (or array of texts) to translate. */
|
|
37
37
|
message: string | string[];
|
|
38
|
-
/**
|
|
38
|
+
/** Source language (ISO code, e.g. "fr") or "auto" for automatic detection. */
|
|
39
39
|
from: string;
|
|
40
|
-
/**
|
|
40
|
+
/** Target language (ISO code, e.g. "en"). */
|
|
41
41
|
to: string;
|
|
42
|
-
/**
|
|
42
|
+
/** Text format (default: "text"). */
|
|
43
43
|
format?: TranslateFormat;
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
45
|
+
/** Language detected by /detect or in "auto" mode. */
|
|
46
46
|
interface DetectedLanguage {
|
|
47
|
-
/**
|
|
47
|
+
/** Confidence score (0–100). */
|
|
48
48
|
confidence: number;
|
|
49
|
-
/**
|
|
49
|
+
/** ISO code of the detected language. */
|
|
50
50
|
language: string;
|
|
51
51
|
}
|
|
52
|
-
/**
|
|
52
|
+
/** Result of a translation. */
|
|
53
53
|
interface TranslateResult {
|
|
54
|
-
/**
|
|
54
|
+
/** Translated text (string if `message` was a string, otherwise string[]). */
|
|
55
55
|
translatedText: string | string[];
|
|
56
|
-
/** `true`
|
|
56
|
+
/** `true` if the response came from the cache. */
|
|
57
57
|
cached: boolean;
|
|
58
|
-
/**
|
|
58
|
+
/** Present only when `from` was "auto". */
|
|
59
59
|
detectedLanguage?: DetectedLanguage;
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
61
|
+
/** A language supported by the server. */
|
|
62
62
|
interface Language {
|
|
63
63
|
code: string;
|
|
64
64
|
name: string;
|
|
65
65
|
targets?: string[];
|
|
66
66
|
}
|
|
67
|
-
/**
|
|
67
|
+
/** Response of /health (no API key required). */
|
|
68
68
|
interface HealthResult {
|
|
69
69
|
status: string;
|
|
70
70
|
redis: boolean;
|
|
71
|
-
/**
|
|
71
|
+
/** Availability of the upstream translation engine. */
|
|
72
72
|
engine: boolean;
|
|
73
73
|
time: string;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
*
|
|
77
|
-
* `status`
|
|
76
|
+
* Thrown for any non-2xx response or any network failure.
|
|
77
|
+
* `status` is 0 on a network error / timeout.
|
|
78
78
|
*/
|
|
79
79
|
declare class ETranslateError extends Error {
|
|
80
80
|
readonly status: number;
|
|
81
81
|
readonly body: unknown;
|
|
82
82
|
constructor(message: string, status: number, body?: unknown);
|
|
83
83
|
}
|
|
84
|
-
/** Client
|
|
84
|
+
/** Client for the e-translate API. */
|
|
85
85
|
declare class ETranslateClient {
|
|
86
86
|
private readonly baseUrl;
|
|
87
87
|
private readonly apiKey;
|
|
@@ -90,19 +90,19 @@ declare class ETranslateClient {
|
|
|
90
90
|
private readonly extraHeaders;
|
|
91
91
|
constructor(options: ETranslateOptions);
|
|
92
92
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
93
|
+
* Translate a text (or an array of texts).
|
|
94
|
+
* Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.
|
|
95
95
|
*/
|
|
96
96
|
translate(params: TranslateParams): Promise<TranslateResult>;
|
|
97
|
-
/**
|
|
97
|
+
/** Detect the language of a text via `POST /detect`. */
|
|
98
98
|
detect(text: string): Promise<DetectedLanguage[]>;
|
|
99
|
-
/**
|
|
99
|
+
/** List supported languages via `GET /languages`. */
|
|
100
100
|
languages(): Promise<Language[]>;
|
|
101
|
-
/**
|
|
101
|
+
/** Service health via `GET /health` (no API key required). */
|
|
102
102
|
health(): Promise<HealthResult>;
|
|
103
103
|
private request;
|
|
104
104
|
}
|
|
105
|
-
/**
|
|
105
|
+
/** Convenience factory equivalent to `new ETranslateClient(options)`. */
|
|
106
106
|
declare function createClient(options: ETranslateOptions): ETranslateClient;
|
|
107
107
|
|
|
108
108
|
export { type DetectedLanguage, ETranslateClient, ETranslateError, type ETranslateOptions, type HealthResult, type Language, type TranslateFormat, type TranslateParams, type TranslateResult, createClient, ETranslateClient as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* e-translate SDK —
|
|
2
|
+
* e-translate SDK — TypeScript/JavaScript client for the e-translate API.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Works in Node 18+ (global fetch) and in the browser.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* import { ETranslateClient } from "e-translate
|
|
8
|
+
* import { ETranslateClient } from "@ecosplay/e-translate";
|
|
9
9
|
*
|
|
10
10
|
* const client = new ETranslateClient({
|
|
11
11
|
* baseUrl: "https://translation.e-cosplay.fr",
|
|
@@ -16,72 +16,72 @@
|
|
|
16
16
|
* console.log(res.translatedText); // "Hello"
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
/** Format
|
|
19
|
+
/** Format of the text to translate. */
|
|
20
20
|
type TranslateFormat = "text" | "html";
|
|
21
|
-
/**
|
|
21
|
+
/** Client construction options. */
|
|
22
22
|
interface ETranslateOptions {
|
|
23
|
-
/**
|
|
23
|
+
/** Server base URL, e.g. "https://translation.e-cosplay.fr". */
|
|
24
24
|
baseUrl: string;
|
|
25
|
-
/**
|
|
25
|
+
/** API key (`etk_...`). Required for /translate, /detect, /languages. */
|
|
26
26
|
apiKey: string;
|
|
27
|
-
/**
|
|
27
|
+
/** Per-request timeout in milliseconds (default: 20000). */
|
|
28
28
|
timeoutMs?: number;
|
|
29
|
-
/**
|
|
29
|
+
/** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */
|
|
30
30
|
fetch?: typeof fetch;
|
|
31
|
-
/**
|
|
31
|
+
/** Extra HTTP headers sent on every request. */
|
|
32
32
|
headers?: Record<string, string>;
|
|
33
33
|
}
|
|
34
|
-
/**
|
|
34
|
+
/** Translation parameters. */
|
|
35
35
|
interface TranslateParams {
|
|
36
|
-
/**
|
|
36
|
+
/** Text (or array of texts) to translate. */
|
|
37
37
|
message: string | string[];
|
|
38
|
-
/**
|
|
38
|
+
/** Source language (ISO code, e.g. "fr") or "auto" for automatic detection. */
|
|
39
39
|
from: string;
|
|
40
|
-
/**
|
|
40
|
+
/** Target language (ISO code, e.g. "en"). */
|
|
41
41
|
to: string;
|
|
42
|
-
/**
|
|
42
|
+
/** Text format (default: "text"). */
|
|
43
43
|
format?: TranslateFormat;
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
45
|
+
/** Language detected by /detect or in "auto" mode. */
|
|
46
46
|
interface DetectedLanguage {
|
|
47
|
-
/**
|
|
47
|
+
/** Confidence score (0–100). */
|
|
48
48
|
confidence: number;
|
|
49
|
-
/**
|
|
49
|
+
/** ISO code of the detected language. */
|
|
50
50
|
language: string;
|
|
51
51
|
}
|
|
52
|
-
/**
|
|
52
|
+
/** Result of a translation. */
|
|
53
53
|
interface TranslateResult {
|
|
54
|
-
/**
|
|
54
|
+
/** Translated text (string if `message` was a string, otherwise string[]). */
|
|
55
55
|
translatedText: string | string[];
|
|
56
|
-
/** `true`
|
|
56
|
+
/** `true` if the response came from the cache. */
|
|
57
57
|
cached: boolean;
|
|
58
|
-
/**
|
|
58
|
+
/** Present only when `from` was "auto". */
|
|
59
59
|
detectedLanguage?: DetectedLanguage;
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
61
|
+
/** A language supported by the server. */
|
|
62
62
|
interface Language {
|
|
63
63
|
code: string;
|
|
64
64
|
name: string;
|
|
65
65
|
targets?: string[];
|
|
66
66
|
}
|
|
67
|
-
/**
|
|
67
|
+
/** Response of /health (no API key required). */
|
|
68
68
|
interface HealthResult {
|
|
69
69
|
status: string;
|
|
70
70
|
redis: boolean;
|
|
71
|
-
/**
|
|
71
|
+
/** Availability of the upstream translation engine. */
|
|
72
72
|
engine: boolean;
|
|
73
73
|
time: string;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
|
-
*
|
|
77
|
-
* `status`
|
|
76
|
+
* Thrown for any non-2xx response or any network failure.
|
|
77
|
+
* `status` is 0 on a network error / timeout.
|
|
78
78
|
*/
|
|
79
79
|
declare class ETranslateError extends Error {
|
|
80
80
|
readonly status: number;
|
|
81
81
|
readonly body: unknown;
|
|
82
82
|
constructor(message: string, status: number, body?: unknown);
|
|
83
83
|
}
|
|
84
|
-
/** Client
|
|
84
|
+
/** Client for the e-translate API. */
|
|
85
85
|
declare class ETranslateClient {
|
|
86
86
|
private readonly baseUrl;
|
|
87
87
|
private readonly apiKey;
|
|
@@ -90,19 +90,19 @@ declare class ETranslateClient {
|
|
|
90
90
|
private readonly extraHeaders;
|
|
91
91
|
constructor(options: ETranslateOptions);
|
|
92
92
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
93
|
+
* Translate a text (or an array of texts).
|
|
94
|
+
* Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.
|
|
95
95
|
*/
|
|
96
96
|
translate(params: TranslateParams): Promise<TranslateResult>;
|
|
97
|
-
/**
|
|
97
|
+
/** Detect the language of a text via `POST /detect`. */
|
|
98
98
|
detect(text: string): Promise<DetectedLanguage[]>;
|
|
99
|
-
/**
|
|
99
|
+
/** List supported languages via `GET /languages`. */
|
|
100
100
|
languages(): Promise<Language[]>;
|
|
101
|
-
/**
|
|
101
|
+
/** Service health via `GET /health` (no API key required). */
|
|
102
102
|
health(): Promise<HealthResult>;
|
|
103
103
|
private request;
|
|
104
104
|
}
|
|
105
|
-
/**
|
|
105
|
+
/** Convenience factory equivalent to `new ETranslateClient(options)`. */
|
|
106
106
|
declare function createClient(options: ETranslateOptions): ETranslateClient;
|
|
107
107
|
|
|
108
108
|
export { type DetectedLanguage, ETranslateClient, ETranslateError, type ETranslateOptions, type HealthResult, type Language, type TranslateFormat, type TranslateParams, type TranslateResult, createClient, ETranslateClient as default };
|
package/dist/index.js
CHANGED
|
@@ -26,8 +26,8 @@ var ETranslateClient = class {
|
|
|
26
26
|
this.fetchImpl = f;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* Translate a text (or an array of texts).
|
|
30
|
+
* Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.
|
|
31
31
|
*/
|
|
32
32
|
async translate(params) {
|
|
33
33
|
if (params?.message == null) {
|
|
@@ -42,16 +42,16 @@ var ETranslateClient = class {
|
|
|
42
42
|
format: params.format ?? "text"
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
45
|
+
/** Detect the language of a text via `POST /detect`. */
|
|
46
46
|
async detect(text) {
|
|
47
47
|
if (!text) throw new Error("detect: 'text' is required.");
|
|
48
48
|
return this.request("POST", "/detect", { q: text });
|
|
49
49
|
}
|
|
50
|
-
/**
|
|
50
|
+
/** List supported languages via `GET /languages`. */
|
|
51
51
|
async languages() {
|
|
52
52
|
return this.request("GET", "/languages");
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
54
|
+
/** Service health via `GET /health` (no API key required). */
|
|
55
55
|
async health() {
|
|
56
56
|
return this.request("GET", "/health", void 0, { auth: false });
|
|
57
57
|
}
|
|
@@ -88,7 +88,7 @@ var ETranslateClient = class {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
if (!resp.ok) {
|
|
91
|
-
const message = data && typeof data === "object" && "error" in data ? String(data.error) : `HTTP ${resp.status}
|
|
91
|
+
const message = data && typeof data === "object" && "error" in data ? String(data.error) : `HTTP ${resp.status} on ${path}`;
|
|
92
92
|
throw new ETranslateError(message, resp.status, data);
|
|
93
93
|
}
|
|
94
94
|
return data;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * e-translate SDK —
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * e-translate SDK — TypeScript/JavaScript client for the e-translate API.\n *\n * Works in Node 18+ (global fetch) and in the browser.\n *\n * @example\n * ```ts\n * import { ETranslateClient } from \"@ecosplay/e-translate\";\n *\n * const client = new ETranslateClient({\n * baseUrl: \"https://translation.e-cosplay.fr\",\n * apiKey: \"etk_xxxxxxxx\",\n * });\n *\n * const res = await client.translate({ message: \"Bonjour\", from: \"fr\", to: \"en\" });\n * console.log(res.translatedText); // \"Hello\"\n * ```\n */\n\n/** Format of the text to translate. */\nexport type TranslateFormat = \"text\" | \"html\";\n\n/** Internal HTTP method. */\ntype HttpMethod = \"GET\" | \"POST\";\n\n/** Client construction options. */\nexport interface ETranslateOptions {\n /** Server base URL, e.g. \"https://translation.e-cosplay.fr\". */\n baseUrl: string;\n /** API key (`etk_...`). Required for /translate, /detect, /languages. */\n apiKey: string;\n /** Per-request timeout in milliseconds (default: 20000). */\n timeoutMs?: number;\n /** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */\n fetch?: typeof fetch;\n /** Extra HTTP headers sent on every request. */\n headers?: Record<string, string>;\n}\n\n/** Translation parameters. */\nexport interface TranslateParams {\n /** Text (or array of texts) to translate. */\n message: string | string[];\n /** Source language (ISO code, e.g. \"fr\") or \"auto\" for automatic detection. */\n from: string;\n /** Target language (ISO code, e.g. \"en\"). */\n to: string;\n /** Text format (default: \"text\"). */\n format?: TranslateFormat;\n}\n\n/** Language detected by /detect or in \"auto\" mode. */\nexport interface DetectedLanguage {\n /** Confidence score (0–100). */\n confidence: number;\n /** ISO code of the detected language. */\n language: string;\n}\n\n/** Result of a translation. */\nexport interface TranslateResult {\n /** Translated text (string if `message` was a string, otherwise string[]). */\n translatedText: string | string[];\n /** `true` if the response came from the cache. */\n cached: boolean;\n /** Present only when `from` was \"auto\". */\n detectedLanguage?: DetectedLanguage;\n}\n\n/** A language supported by the server. */\nexport interface Language {\n code: string;\n name: string;\n targets?: string[];\n}\n\n/** Response of /health (no API key required). */\nexport interface HealthResult {\n status: string;\n redis: boolean;\n /** Availability of the upstream translation engine. */\n engine: boolean;\n time: string;\n}\n\n/**\n * Thrown for any non-2xx response or any network failure.\n * `status` is 0 on a network error / timeout.\n */\nexport class ETranslateError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body?: unknown) {\n super(message);\n this.name = \"ETranslateError\";\n this.status = status;\n this.body = body;\n // Restore the prototype chain (TS targeting ES5/ES2015).\n Object.setPrototypeOf(this, ETranslateError.prototype);\n }\n}\n\n/** Client for the e-translate API. */\nexport class ETranslateClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private readonly extraHeaders: Record<string, string>;\n\n constructor(options: ETranslateOptions) {\n if (!options || typeof options.baseUrl !== \"string\" || options.baseUrl.length === 0) {\n throw new Error(\"ETranslate: the 'baseUrl' option is required.\");\n }\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey ?? \"\";\n this.timeoutMs = options.timeoutMs ?? 20000;\n this.extraHeaders = options.headers ?? {};\n\n const f = options.fetch ?? (globalThis as { fetch?: typeof fetch }).fetch;\n if (typeof f !== \"function\") {\n throw new TypeError(\n \"ETranslate: no `fetch` implementation available. \" +\n \"Use Node >= 18 or pass `options.fetch`.\",\n );\n }\n this.fetchImpl = f;\n }\n\n /**\n * Translate a text (or an array of texts).\n * Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.\n */\n async translate(params: TranslateParams): Promise<TranslateResult> {\n if (params?.message == null) {\n throw new Error(\"translate: 'message' is required.\");\n }\n if (!params.from) throw new Error(\"translate: 'from' is required (e.g. 'fr' or 'auto').\");\n if (!params.to) throw new Error(\"translate: 'to' is required (e.g. 'en').\");\n\n return this.request<TranslateResult>(\"POST\", \"/translate\", {\n lang_src: params.from,\n lang_dest: params.to,\n message: params.message,\n format: params.format ?? \"text\",\n });\n }\n\n /** Detect the language of a text via `POST /detect`. */\n async detect(text: string): Promise<DetectedLanguage[]> {\n if (!text) throw new Error(\"detect: 'text' is required.\");\n return this.request<DetectedLanguage[]>(\"POST\", \"/detect\", { q: text });\n }\n\n /** List supported languages via `GET /languages`. */\n async languages(): Promise<Language[]> {\n return this.request<Language[]>(\"GET\", \"/languages\");\n }\n\n /** Service health via `GET /health` (no API key required). */\n async health(): Promise<HealthResult> {\n return this.request<HealthResult>(\"GET\", \"/health\", undefined, { auth: false });\n }\n\n private async request<T>(\n method: HttpMethod,\n path: string,\n body?: Record<string, unknown>,\n opts?: { auth?: boolean },\n ): Promise<T> {\n const useAuth = opts?.auth !== false;\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = { Accept: \"application/json\", ...this.extraHeaders };\n if (useAuth) headers[\"X-API-Key\"] = this.apiKey;\n if (body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let resp: Response;\n try {\n resp = await this.fetchImpl(url, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n const e = err as { name?: string; message?: string };\n const msg =\n e?.name === \"AbortError\"\n ? `Request timed out after ${this.timeoutMs} ms (${path}).`\n : `Network error to ${url}: ${e?.message ?? String(err)}`;\n throw new ETranslateError(msg, 0);\n } finally {\n clearTimeout(timer);\n }\n\n const raw = await resp.text();\n let data: unknown = undefined;\n if (raw) {\n try {\n data = JSON.parse(raw);\n } catch {\n data = raw;\n }\n }\n\n if (!resp.ok) {\n const message =\n data && typeof data === \"object\" && \"error\" in data\n ? String((data as { error: unknown }).error)\n : `HTTP ${resp.status} on ${path}`;\n throw new ETranslateError(message, resp.status, data);\n }\n\n return data as T;\n }\n}\n\n/** Convenience factory equivalent to `new ETranslateClient(options)`. */\nexport function createClient(options: ETranslateOptions): ETranslateClient {\n return new ETranslateClient(options);\n}\n\nexport default ETranslateClient;\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecosplay/e-translate",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "TypeScript/JavaScript client SDK for the e-translate API (translation.e-cosplay.fr).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* e-translate SDK —
|
|
2
|
+
* e-translate SDK — TypeScript/JavaScript client for the e-translate API.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Works in Node 18+ (global fetch) and in the browser.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* import { ETranslateClient } from "e-translate
|
|
8
|
+
* import { ETranslateClient } from "@ecosplay/e-translate";
|
|
9
9
|
*
|
|
10
10
|
* const client = new ETranslateClient({
|
|
11
11
|
* baseUrl: "https://translation.e-cosplay.fr",
|
|
@@ -17,75 +17,75 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
/** Format
|
|
20
|
+
/** Format of the text to translate. */
|
|
21
21
|
export type TranslateFormat = "text" | "html";
|
|
22
22
|
|
|
23
|
-
/**
|
|
23
|
+
/** Internal HTTP method. */
|
|
24
24
|
type HttpMethod = "GET" | "POST";
|
|
25
25
|
|
|
26
|
-
/**
|
|
26
|
+
/** Client construction options. */
|
|
27
27
|
export interface ETranslateOptions {
|
|
28
|
-
/**
|
|
28
|
+
/** Server base URL, e.g. "https://translation.e-cosplay.fr". */
|
|
29
29
|
baseUrl: string;
|
|
30
|
-
/**
|
|
30
|
+
/** API key (`etk_...`). Required for /translate, /detect, /languages. */
|
|
31
31
|
apiKey: string;
|
|
32
|
-
/**
|
|
32
|
+
/** Per-request timeout in milliseconds (default: 20000). */
|
|
33
33
|
timeoutMs?: number;
|
|
34
|
-
/**
|
|
34
|
+
/** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */
|
|
35
35
|
fetch?: typeof fetch;
|
|
36
|
-
/**
|
|
36
|
+
/** Extra HTTP headers sent on every request. */
|
|
37
37
|
headers?: Record<string, string>;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
/**
|
|
40
|
+
/** Translation parameters. */
|
|
41
41
|
export interface TranslateParams {
|
|
42
|
-
/**
|
|
42
|
+
/** Text (or array of texts) to translate. */
|
|
43
43
|
message: string | string[];
|
|
44
|
-
/**
|
|
44
|
+
/** Source language (ISO code, e.g. "fr") or "auto" for automatic detection. */
|
|
45
45
|
from: string;
|
|
46
|
-
/**
|
|
46
|
+
/** Target language (ISO code, e.g. "en"). */
|
|
47
47
|
to: string;
|
|
48
|
-
/**
|
|
48
|
+
/** Text format (default: "text"). */
|
|
49
49
|
format?: TranslateFormat;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
/**
|
|
52
|
+
/** Language detected by /detect or in "auto" mode. */
|
|
53
53
|
export interface DetectedLanguage {
|
|
54
|
-
/**
|
|
54
|
+
/** Confidence score (0–100). */
|
|
55
55
|
confidence: number;
|
|
56
|
-
/**
|
|
56
|
+
/** ISO code of the detected language. */
|
|
57
57
|
language: string;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/**
|
|
60
|
+
/** Result of a translation. */
|
|
61
61
|
export interface TranslateResult {
|
|
62
|
-
/**
|
|
62
|
+
/** Translated text (string if `message` was a string, otherwise string[]). */
|
|
63
63
|
translatedText: string | string[];
|
|
64
|
-
/** `true`
|
|
64
|
+
/** `true` if the response came from the cache. */
|
|
65
65
|
cached: boolean;
|
|
66
|
-
/**
|
|
66
|
+
/** Present only when `from` was "auto". */
|
|
67
67
|
detectedLanguage?: DetectedLanguage;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
/**
|
|
70
|
+
/** A language supported by the server. */
|
|
71
71
|
export interface Language {
|
|
72
72
|
code: string;
|
|
73
73
|
name: string;
|
|
74
74
|
targets?: string[];
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/**
|
|
77
|
+
/** Response of /health (no API key required). */
|
|
78
78
|
export interface HealthResult {
|
|
79
79
|
status: string;
|
|
80
80
|
redis: boolean;
|
|
81
|
-
/**
|
|
81
|
+
/** Availability of the upstream translation engine. */
|
|
82
82
|
engine: boolean;
|
|
83
83
|
time: string;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
* `status`
|
|
87
|
+
* Thrown for any non-2xx response or any network failure.
|
|
88
|
+
* `status` is 0 on a network error / timeout.
|
|
89
89
|
*/
|
|
90
90
|
export class ETranslateError extends Error {
|
|
91
91
|
readonly status: number;
|
|
@@ -96,12 +96,12 @@ export class ETranslateError extends Error {
|
|
|
96
96
|
this.name = "ETranslateError";
|
|
97
97
|
this.status = status;
|
|
98
98
|
this.body = body;
|
|
99
|
-
//
|
|
99
|
+
// Restore the prototype chain (TS targeting ES5/ES2015).
|
|
100
100
|
Object.setPrototypeOf(this, ETranslateError.prototype);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
/** Client
|
|
104
|
+
/** Client for the e-translate API. */
|
|
105
105
|
export class ETranslateClient {
|
|
106
106
|
private readonly baseUrl: string;
|
|
107
107
|
private readonly apiKey: string;
|
|
@@ -129,8 +129,8 @@ export class ETranslateClient {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
132
|
+
* Translate a text (or an array of texts).
|
|
133
|
+
* Sends `lang_src` / `lang_dest` / `message` to `POST /translate`.
|
|
134
134
|
*/
|
|
135
135
|
async translate(params: TranslateParams): Promise<TranslateResult> {
|
|
136
136
|
if (params?.message == null) {
|
|
@@ -147,18 +147,18 @@ export class ETranslateClient {
|
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
/**
|
|
150
|
+
/** Detect the language of a text via `POST /detect`. */
|
|
151
151
|
async detect(text: string): Promise<DetectedLanguage[]> {
|
|
152
152
|
if (!text) throw new Error("detect: 'text' is required.");
|
|
153
153
|
return this.request<DetectedLanguage[]>("POST", "/detect", { q: text });
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
/**
|
|
156
|
+
/** List supported languages via `GET /languages`. */
|
|
157
157
|
async languages(): Promise<Language[]> {
|
|
158
158
|
return this.request<Language[]>("GET", "/languages");
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
/**
|
|
161
|
+
/** Service health via `GET /health` (no API key required). */
|
|
162
162
|
async health(): Promise<HealthResult> {
|
|
163
163
|
return this.request<HealthResult>("GET", "/health", undefined, { auth: false });
|
|
164
164
|
}
|
|
@@ -212,7 +212,7 @@ export class ETranslateClient {
|
|
|
212
212
|
const message =
|
|
213
213
|
data && typeof data === "object" && "error" in data
|
|
214
214
|
? String((data as { error: unknown }).error)
|
|
215
|
-
: `HTTP ${resp.status}
|
|
215
|
+
: `HTTP ${resp.status} on ${path}`;
|
|
216
216
|
throw new ETranslateError(message, resp.status, data);
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -220,7 +220,7 @@ export class ETranslateClient {
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
/**
|
|
223
|
+
/** Convenience factory equivalent to `new ETranslateClient(options)`. */
|
|
224
224
|
export function createClient(options: ETranslateOptions): ETranslateClient {
|
|
225
225
|
return new ETranslateClient(options);
|
|
226
226
|
}
|