@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 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
@@ -35,7 +35,7 @@ yarn add @ecosplay/e-translate
35
35
  **Pin a version** (recommended in production):
36
36
 
37
37
  ```bash
38
- npm install @ecosplay/e-translate@1.1.0
38
+ npm install @ecosplay/e-translate@1.1.2
39
39
  ```
40
40
 
41
41
  > Published to npm automatically by CI on each `vX.Y.Z` tag (see
package/dist/index.cjs CHANGED
@@ -53,8 +53,8 @@ var ETranslateClient = class {
53
53
  this.fetchImpl = f;
54
54
  }
55
55
  /**
56
- * Traduit un texte (ou un tableau de textes).
57
- * Envoie `lang_src` / `lang_dest` / `message` à `POST /translate`.
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
- /** Détecte la langue d'un texte via `POST /detect`. */
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
- /** Liste les langues supportées via `GET /languages`. */
77
+ /** List supported languages via `GET /languages`. */
78
78
  async languages() {
79
79
  return this.request("GET", "/languages");
80
80
  }
81
- /** État du service via `GET /health` (ne nécessite pas de clé API). */
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} sur ${path}`;
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;
@@ -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 — client TypeScript/JavaScript pour l'API e-translate.
2
+ * e-translate SDK — TypeScript/JavaScript client for the e-translate API.
3
3
  *
4
- * Fonctionne dans Node 18+ (fetch global) et dans le navigateur.
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-sdk";
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 du texte à traduire. */
19
+ /** Format of the text to translate. */
20
20
  type TranslateFormat = "text" | "html";
21
- /** Options de construction du client. */
21
+ /** Client construction options. */
22
22
  interface ETranslateOptions {
23
- /** URL de base du serveur, ex. "https://translation.e-cosplay.fr". */
23
+ /** Server base URL, e.g. "https://translation.e-cosplay.fr". */
24
24
  baseUrl: string;
25
- /** Clé d'API (`etk_...`). Requise pour /translate, /detect, /languages. */
25
+ /** API key (`etk_...`). Required for /translate, /detect, /languages. */
26
26
  apiKey: string;
27
- /** Timeout par requête en millisecondes (défaut : 20000). */
27
+ /** Per-request timeout in milliseconds (default: 20000). */
28
28
  timeoutMs?: number;
29
- /** Implémentation `fetch` personnalisée (Node < 18, tests). Défaut : `globalThis.fetch`. */
29
+ /** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */
30
30
  fetch?: typeof fetch;
31
- /** En-têtes HTTP supplémentaires envoyés à chaque requête. */
31
+ /** Extra HTTP headers sent on every request. */
32
32
  headers?: Record<string, string>;
33
33
  }
34
- /** Paramètres de traduction. */
34
+ /** Translation parameters. */
35
35
  interface TranslateParams {
36
- /** Texte (ou tableau de textes) à traduire. */
36
+ /** Text (or array of texts) to translate. */
37
37
  message: string | string[];
38
- /** Langue source (code ISO, ex. "fr") ou "auto" pour la détection automatique. */
38
+ /** Source language (ISO code, e.g. "fr") or "auto" for automatic detection. */
39
39
  from: string;
40
- /** Langue cible (code ISO, ex. "en"). */
40
+ /** Target language (ISO code, e.g. "en"). */
41
41
  to: string;
42
- /** Format du texte (défaut : "text"). */
42
+ /** Text format (default: "text"). */
43
43
  format?: TranslateFormat;
44
44
  }
45
- /** Langue détectée renvoyée par /detect ou en mode "auto". */
45
+ /** Language detected by /detect or in "auto" mode. */
46
46
  interface DetectedLanguage {
47
- /** Indice de confiance (0–100). */
47
+ /** Confidence score (0–100). */
48
48
  confidence: number;
49
- /** Code ISO de la langue détectée. */
49
+ /** ISO code of the detected language. */
50
50
  language: string;
51
51
  }
52
- /** Résultat d'une traduction. */
52
+ /** Result of a translation. */
53
53
  interface TranslateResult {
54
- /** Texte traduit (string si `message` était une string, sinon string[]). */
54
+ /** Translated text (string if `message` was a string, otherwise string[]). */
55
55
  translatedText: string | string[];
56
- /** `true` si la réponse provient du cache Redis. */
56
+ /** `true` if the response came from the cache. */
57
57
  cached: boolean;
58
- /** Présent uniquement si `from` valait "auto". */
58
+ /** Present only when `from` was "auto". */
59
59
  detectedLanguage?: DetectedLanguage;
60
60
  }
61
- /** Une langue supportée par le serveur. */
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
- /** Réponse de /health (aucune clé requise). */
67
+ /** Response of /health (no API key required). */
68
68
  interface HealthResult {
69
69
  status: string;
70
70
  redis: boolean;
71
- /** Disponibilité du moteur de traduction en amont. */
71
+ /** Availability of the upstream translation engine. */
72
72
  engine: boolean;
73
73
  time: string;
74
74
  }
75
75
  /**
76
- * Erreur levée pour toute réponse non-2xx ou tout échec réseau.
77
- * `status` vaut 0 en cas d'échec réseau / timeout.
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 de l'API e-translate. */
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
- * Traduit un texte (ou un tableau de textes).
94
- * Envoie `lang_src` / `lang_dest` / `message` à `POST /translate`.
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
- /** Détecte la langue d'un texte via `POST /detect`. */
97
+ /** Detect the language of a text via `POST /detect`. */
98
98
  detect(text: string): Promise<DetectedLanguage[]>;
99
- /** Liste les langues supportées via `GET /languages`. */
99
+ /** List supported languages via `GET /languages`. */
100
100
  languages(): Promise<Language[]>;
101
- /** État du service via `GET /health` (ne nécessite pas de clé API). */
101
+ /** Service health via `GET /health` (no API key required). */
102
102
  health(): Promise<HealthResult>;
103
103
  private request;
104
104
  }
105
- /** Fabrique pratique équivalente à `new ETranslateClient(options)`. */
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 — client TypeScript/JavaScript pour l'API e-translate.
2
+ * e-translate SDK — TypeScript/JavaScript client for the e-translate API.
3
3
  *
4
- * Fonctionne dans Node 18+ (fetch global) et dans le navigateur.
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-sdk";
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 du texte à traduire. */
19
+ /** Format of the text to translate. */
20
20
  type TranslateFormat = "text" | "html";
21
- /** Options de construction du client. */
21
+ /** Client construction options. */
22
22
  interface ETranslateOptions {
23
- /** URL de base du serveur, ex. "https://translation.e-cosplay.fr". */
23
+ /** Server base URL, e.g. "https://translation.e-cosplay.fr". */
24
24
  baseUrl: string;
25
- /** Clé d'API (`etk_...`). Requise pour /translate, /detect, /languages. */
25
+ /** API key (`etk_...`). Required for /translate, /detect, /languages. */
26
26
  apiKey: string;
27
- /** Timeout par requête en millisecondes (défaut : 20000). */
27
+ /** Per-request timeout in milliseconds (default: 20000). */
28
28
  timeoutMs?: number;
29
- /** Implémentation `fetch` personnalisée (Node < 18, tests). Défaut : `globalThis.fetch`. */
29
+ /** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */
30
30
  fetch?: typeof fetch;
31
- /** En-têtes HTTP supplémentaires envoyés à chaque requête. */
31
+ /** Extra HTTP headers sent on every request. */
32
32
  headers?: Record<string, string>;
33
33
  }
34
- /** Paramètres de traduction. */
34
+ /** Translation parameters. */
35
35
  interface TranslateParams {
36
- /** Texte (ou tableau de textes) à traduire. */
36
+ /** Text (or array of texts) to translate. */
37
37
  message: string | string[];
38
- /** Langue source (code ISO, ex. "fr") ou "auto" pour la détection automatique. */
38
+ /** Source language (ISO code, e.g. "fr") or "auto" for automatic detection. */
39
39
  from: string;
40
- /** Langue cible (code ISO, ex. "en"). */
40
+ /** Target language (ISO code, e.g. "en"). */
41
41
  to: string;
42
- /** Format du texte (défaut : "text"). */
42
+ /** Text format (default: "text"). */
43
43
  format?: TranslateFormat;
44
44
  }
45
- /** Langue détectée renvoyée par /detect ou en mode "auto". */
45
+ /** Language detected by /detect or in "auto" mode. */
46
46
  interface DetectedLanguage {
47
- /** Indice de confiance (0–100). */
47
+ /** Confidence score (0–100). */
48
48
  confidence: number;
49
- /** Code ISO de la langue détectée. */
49
+ /** ISO code of the detected language. */
50
50
  language: string;
51
51
  }
52
- /** Résultat d'une traduction. */
52
+ /** Result of a translation. */
53
53
  interface TranslateResult {
54
- /** Texte traduit (string si `message` était une string, sinon string[]). */
54
+ /** Translated text (string if `message` was a string, otherwise string[]). */
55
55
  translatedText: string | string[];
56
- /** `true` si la réponse provient du cache Redis. */
56
+ /** `true` if the response came from the cache. */
57
57
  cached: boolean;
58
- /** Présent uniquement si `from` valait "auto". */
58
+ /** Present only when `from` was "auto". */
59
59
  detectedLanguage?: DetectedLanguage;
60
60
  }
61
- /** Une langue supportée par le serveur. */
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
- /** Réponse de /health (aucune clé requise). */
67
+ /** Response of /health (no API key required). */
68
68
  interface HealthResult {
69
69
  status: string;
70
70
  redis: boolean;
71
- /** Disponibilité du moteur de traduction en amont. */
71
+ /** Availability of the upstream translation engine. */
72
72
  engine: boolean;
73
73
  time: string;
74
74
  }
75
75
  /**
76
- * Erreur levée pour toute réponse non-2xx ou tout échec réseau.
77
- * `status` vaut 0 en cas d'échec réseau / timeout.
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 de l'API e-translate. */
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
- * Traduit un texte (ou un tableau de textes).
94
- * Envoie `lang_src` / `lang_dest` / `message` à `POST /translate`.
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
- /** Détecte la langue d'un texte via `POST /detect`. */
97
+ /** Detect the language of a text via `POST /detect`. */
98
98
  detect(text: string): Promise<DetectedLanguage[]>;
99
- /** Liste les langues supportées via `GET /languages`. */
99
+ /** List supported languages via `GET /languages`. */
100
100
  languages(): Promise<Language[]>;
101
- /** État du service via `GET /health` (ne nécessite pas de clé API). */
101
+ /** Service health via `GET /health` (no API key required). */
102
102
  health(): Promise<HealthResult>;
103
103
  private request;
104
104
  }
105
- /** Fabrique pratique équivalente à `new ETranslateClient(options)`. */
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
- * Traduit un texte (ou un tableau de textes).
30
- * Envoie `lang_src` / `lang_dest` / `message` à `POST /translate`.
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
- /** Détecte la langue d'un texte via `POST /detect`. */
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
- /** Liste les langues supportées via `GET /languages`. */
50
+ /** List supported languages via `GET /languages`. */
51
51
  async languages() {
52
52
  return this.request("GET", "/languages");
53
53
  }
54
- /** État du service via `GET /health` (ne nécessite pas de clé API). */
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} sur ${path}`;
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 — 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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ecosplay/e-translate",
3
- "version": "1.1.0",
4
- "description": "Client SDK (TypeScript) pour l'API e-translate (translation.e-cosplay.fr).",
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 — client TypeScript/JavaScript pour l'API e-translate.
2
+ * e-translate SDK — TypeScript/JavaScript client for the e-translate API.
3
3
  *
4
- * Fonctionne dans Node 18+ (fetch global) et dans le navigateur.
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-sdk";
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 du texte à traduire. */
20
+ /** Format of the text to translate. */
21
21
  export type TranslateFormat = "text" | "html";
22
22
 
23
- /** Méthode HTTP interne. */
23
+ /** Internal HTTP method. */
24
24
  type HttpMethod = "GET" | "POST";
25
25
 
26
- /** Options de construction du client. */
26
+ /** Client construction options. */
27
27
  export interface ETranslateOptions {
28
- /** URL de base du serveur, ex. "https://translation.e-cosplay.fr". */
28
+ /** Server base URL, e.g. "https://translation.e-cosplay.fr". */
29
29
  baseUrl: string;
30
- /** Clé d'API (`etk_...`). Requise pour /translate, /detect, /languages. */
30
+ /** API key (`etk_...`). Required for /translate, /detect, /languages. */
31
31
  apiKey: string;
32
- /** Timeout par requête en millisecondes (défaut : 20000). */
32
+ /** Per-request timeout in milliseconds (default: 20000). */
33
33
  timeoutMs?: number;
34
- /** Implémentation `fetch` personnalisée (Node < 18, tests). Défaut : `globalThis.fetch`. */
34
+ /** Custom `fetch` implementation (Node < 18, tests). Default: `globalThis.fetch`. */
35
35
  fetch?: typeof fetch;
36
- /** En-têtes HTTP supplémentaires envoyés à chaque requête. */
36
+ /** Extra HTTP headers sent on every request. */
37
37
  headers?: Record<string, string>;
38
38
  }
39
39
 
40
- /** Paramètres de traduction. */
40
+ /** Translation parameters. */
41
41
  export interface TranslateParams {
42
- /** Texte (ou tableau de textes) à traduire. */
42
+ /** Text (or array of texts) to translate. */
43
43
  message: string | string[];
44
- /** Langue source (code ISO, ex. "fr") ou "auto" pour la détection automatique. */
44
+ /** Source language (ISO code, e.g. "fr") or "auto" for automatic detection. */
45
45
  from: string;
46
- /** Langue cible (code ISO, ex. "en"). */
46
+ /** Target language (ISO code, e.g. "en"). */
47
47
  to: string;
48
- /** Format du texte (défaut : "text"). */
48
+ /** Text format (default: "text"). */
49
49
  format?: TranslateFormat;
50
50
  }
51
51
 
52
- /** Langue détectée renvoyée par /detect ou en mode "auto". */
52
+ /** Language detected by /detect or in "auto" mode. */
53
53
  export interface DetectedLanguage {
54
- /** Indice de confiance (0–100). */
54
+ /** Confidence score (0–100). */
55
55
  confidence: number;
56
- /** Code ISO de la langue détectée. */
56
+ /** ISO code of the detected language. */
57
57
  language: string;
58
58
  }
59
59
 
60
- /** Résultat d'une traduction. */
60
+ /** Result of a translation. */
61
61
  export interface TranslateResult {
62
- /** Texte traduit (string si `message` était une string, sinon string[]). */
62
+ /** Translated text (string if `message` was a string, otherwise string[]). */
63
63
  translatedText: string | string[];
64
- /** `true` si la réponse provient du cache Redis. */
64
+ /** `true` if the response came from the cache. */
65
65
  cached: boolean;
66
- /** Présent uniquement si `from` valait "auto". */
66
+ /** Present only when `from` was "auto". */
67
67
  detectedLanguage?: DetectedLanguage;
68
68
  }
69
69
 
70
- /** Une langue supportée par le serveur. */
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
- /** Réponse de /health (aucune clé requise). */
77
+ /** Response of /health (no API key required). */
78
78
  export interface HealthResult {
79
79
  status: string;
80
80
  redis: boolean;
81
- /** Disponibilité du moteur de traduction en amont. */
81
+ /** Availability of the upstream translation engine. */
82
82
  engine: boolean;
83
83
  time: string;
84
84
  }
85
85
 
86
86
  /**
87
- * Erreur levée pour toute réponse non-2xx ou tout échec réseau.
88
- * `status` vaut 0 en cas d'échec réseau / timeout.
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
- // Restaure la chaîne de prototype (TS ciblant ES5/ES2015).
99
+ // Restore the prototype chain (TS targeting ES5/ES2015).
100
100
  Object.setPrototypeOf(this, ETranslateError.prototype);
101
101
  }
102
102
  }
103
103
 
104
- /** Client de l'API e-translate. */
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
- * Traduit un texte (ou un tableau de textes).
133
- * Envoie `lang_src` / `lang_dest` / `message` à `POST /translate`.
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
- /** Détecte la langue d'un texte via `POST /detect`. */
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
- /** Liste les langues supportées via `GET /languages`. */
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
- /** État du service via `GET /health` (ne nécessite pas de clé API). */
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} sur ${path}`;
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
- /** Fabrique pratique équivalente à `new ETranslateClient(options)`. */
223
+ /** Convenience factory equivalent to `new ETranslateClient(options)`. */
224
224
  export function createClient(options: ETranslateOptions): ETranslateClient {
225
225
  return new ETranslateClient(options);
226
226
  }