@translated/lara 1.7.0 → 1.7.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.
@@ -12,10 +12,10 @@ const form_data_1 = __importDefault(require("form-data"));
12
12
  const client_1 = require("./client");
13
13
  /** @internal */
14
14
  class NodeLaraClient extends client_1.LaraClient {
15
- constructor(baseUrl, accessKeyId, accessKeySecret) {
15
+ constructor(baseUrl, accessKeyId, accessKeySecret, keepAlive = true) {
16
16
  super(accessKeyId, accessKeySecret);
17
17
  this.baseUrl = baseUrl;
18
- this.agent = baseUrl.secure ? new node_https_1.default.Agent({ keepAlive: true }) : new node_http_1.default.Agent({ keepAlive: true });
18
+ this.agent = baseUrl.secure ? new node_https_1.default.Agent({ keepAlive }) : new node_http_1.default.Agent({ keepAlive });
19
19
  }
20
20
  async send(path, headers, body) {
21
21
  let requestBody;
@@ -71,15 +71,24 @@ class NodeLaraClient extends client_1.LaraClient {
71
71
  json = JSON.parse(data);
72
72
  }
73
73
  catch (_e) {
74
- reject(new SyntaxError("Invalid JSON response"));
74
+ return reject(new SyntaxError("Invalid JSON response"));
75
75
  }
76
76
  resolve({
77
77
  statusCode: res.statusCode,
78
78
  body: json
79
79
  });
80
80
  });
81
+ // close connection on error
82
+ res.on("error", (err) => {
83
+ req.destroy();
84
+ return reject(err);
85
+ });
86
+ });
87
+ // close connection on error
88
+ req.on("error", (err) => {
89
+ req.destroy();
90
+ return reject(err);
81
91
  });
82
- req.on("error", reject);
83
92
  if (requestBody instanceof form_data_1.default) {
84
93
  requestBody.pipe(req);
85
94
  }
@@ -92,6 +101,137 @@ class NodeLaraClient extends client_1.LaraClient {
92
101
  }
93
102
  });
94
103
  }
104
+ async *sendAndGetStream(path, headers, body) {
105
+ let requestBody;
106
+ if (body) {
107
+ if (headers["Content-Type"] === "multipart/form-data") {
108
+ const formBody = new form_data_1.default();
109
+ for (const [key, value] of Object.entries(body)) {
110
+ if (!value)
111
+ continue;
112
+ if (Array.isArray(value)) {
113
+ for (const v of value)
114
+ formBody.append(key, v);
115
+ }
116
+ else {
117
+ formBody.append(key, value);
118
+ }
119
+ }
120
+ headers = {
121
+ ...headers,
122
+ ...formBody.getHeaders()
123
+ };
124
+ requestBody = formBody;
125
+ }
126
+ else {
127
+ requestBody = JSON.stringify(body, undefined, 0);
128
+ }
129
+ }
130
+ const options = {
131
+ host: this.baseUrl.hostname,
132
+ port: this.baseUrl.port,
133
+ path: path,
134
+ method: "POST",
135
+ headers: headers,
136
+ agent: this.agent
137
+ };
138
+ // Create async iterator from the stream
139
+ const chunks = [];
140
+ let resolveChunk = null;
141
+ let streamEnded = false;
142
+ let streamError = null;
143
+ const req = (this.baseUrl.secure ? node_https_1.default : node_http_1.default).request(options, (res) => {
144
+ let buffer = "";
145
+ res.on("data", (chunk) => {
146
+ buffer += chunk.toString();
147
+ const lines = buffer.split("\n");
148
+ // {a}\n{b}\n{c}\n --> [{a}, {b}, {c}, ""]
149
+ // {a}\n{b}\n{c} --> [{a}, {b}, {c}]
150
+ buffer = lines.pop() || ""; // Keep incomplete line in buffer
151
+ for (const line of lines) {
152
+ if (line.trim()) {
153
+ try {
154
+ const json = JSON.parse(line);
155
+ chunks.push({
156
+ statusCode: json.status || res.statusCode,
157
+ body: json.data || json
158
+ });
159
+ if (resolveChunk) {
160
+ resolveChunk();
161
+ resolveChunk = null;
162
+ }
163
+ }
164
+ catch (_e) {
165
+ // Skip invalid JSON lines
166
+ }
167
+ }
168
+ }
169
+ });
170
+ res.on("end", () => {
171
+ // Process any remaining data in buffer
172
+ if (buffer.trim()) {
173
+ try {
174
+ const json = JSON.parse(buffer);
175
+ chunks.push({
176
+ statusCode: json.status || res.statusCode,
177
+ body: json.data || json
178
+ });
179
+ }
180
+ catch (_e) {
181
+ // Skip invalid JSON
182
+ }
183
+ }
184
+ streamEnded = true;
185
+ if (resolveChunk) {
186
+ resolveChunk();
187
+ resolveChunk = null;
188
+ }
189
+ });
190
+ res.on("error", (err) => {
191
+ req.destroy();
192
+ streamError = err;
193
+ if (resolveChunk) {
194
+ resolveChunk();
195
+ resolveChunk = null;
196
+ }
197
+ });
198
+ });
199
+ req.on("error", (err) => {
200
+ streamError = err;
201
+ if (resolveChunk) {
202
+ resolveChunk();
203
+ resolveChunk = null;
204
+ }
205
+ });
206
+ if (requestBody instanceof form_data_1.default) {
207
+ requestBody.pipe(req);
208
+ }
209
+ else if (requestBody) {
210
+ req.write(requestBody);
211
+ req.end();
212
+ }
213
+ else {
214
+ req.end();
215
+ }
216
+ // Yield chunks as they arrive
217
+ while (true) {
218
+ if (streamError) {
219
+ throw streamError;
220
+ }
221
+ if (chunks.length > 0) {
222
+ yield chunks.shift();
223
+ }
224
+ else if (streamEnded) {
225
+ break;
226
+ }
227
+ else {
228
+ // Wait for next chunk
229
+ await new Promise((resolve) => {
230
+ resolveChunk = resolve;
231
+ });
232
+ }
233
+ }
234
+ }
95
235
  wrapMultiPartFile(file) {
96
236
  if (typeof file === "string")
97
237
  file = node_fs_1.default.createReadStream(file);
@@ -1,4 +1,4 @@
1
- import type { S3UploadFields } from "../../translator/translator";
1
+ import type { S3UploadFields } from "../../documents";
2
2
  import type { MultiPartFile } from "../client";
3
3
  import { S3Client } from "./client";
4
4
  /** @internal */
@@ -1,4 +1,4 @@
1
- import type { S3UploadFields } from "../../translator/translator";
1
+ import type { S3UploadFields } from "../../documents";
2
2
  import type { MultiPartFile } from "../client";
3
3
  /** @internal */
4
4
  export declare abstract class S3Client {
@@ -1,5 +1,5 @@
1
1
  import { Readable } from "node:stream";
2
- import type { S3UploadFields } from "../../translator/translator";
2
+ import type { S3UploadFields } from "../../documents";
3
3
  import type { MultiPartFile } from "../client";
4
4
  import { S3Client } from "./client";
5
5
  /** @internal */
@@ -0,0 +1,68 @@
1
+ import type { Credentials } from "./credentials";
2
+ import { Documents } from "./documents";
3
+ import { Glossaries } from "./glossaries";
4
+ import { Memories } from "./memories";
5
+ import { type LaraClient } from "./net";
6
+ export type TranslatorOptions = {
7
+ serverUrl?: string;
8
+ keepAlive?: boolean;
9
+ };
10
+ export interface NGMemoryMatch {
11
+ memory: string;
12
+ tuid?: string;
13
+ language: [string, string];
14
+ sentence: string;
15
+ translation: string;
16
+ score: number;
17
+ }
18
+ export interface NGGlossaryMatch {
19
+ glossary: string;
20
+ language: [string, string];
21
+ term: string;
22
+ translation: string;
23
+ }
24
+ export interface TextBlock {
25
+ readonly text: string;
26
+ readonly translatable?: boolean;
27
+ }
28
+ export interface TextResult<T extends string | string[] | TextBlock[]> {
29
+ readonly contentType: string;
30
+ readonly sourceLanguage: string;
31
+ readonly translation: T;
32
+ readonly adaptedTo?: string[];
33
+ readonly glossaries?: string[];
34
+ readonly adaptedToMatches?: NGMemoryMatch[] | NGMemoryMatch[][];
35
+ readonly glossariesMatches?: NGGlossaryMatch[] | NGGlossaryMatch[][];
36
+ }
37
+ export type TranslateOptions = {
38
+ sourceHint?: string;
39
+ adaptTo?: string[];
40
+ instructions?: string[];
41
+ glossaries?: string[];
42
+ contentType?: string;
43
+ multiline?: boolean;
44
+ timeoutInMillis?: number;
45
+ priority?: "normal" | "background";
46
+ useCache?: boolean | "overwrite";
47
+ cacheTTLSeconds?: number;
48
+ noTrace?: boolean;
49
+ verbose?: boolean;
50
+ headers?: Record<string, string>;
51
+ style?: TranslationStyle;
52
+ reasoning?: boolean;
53
+ };
54
+ export type TranslationStyle = "faithful" | "fluid" | "creative";
55
+ export interface DetectResult {
56
+ language: string;
57
+ contentType: string;
58
+ }
59
+ export declare class Translator {
60
+ protected readonly client: LaraClient;
61
+ readonly memories: Memories;
62
+ readonly documents: Documents;
63
+ readonly glossaries: Glossaries;
64
+ constructor(credentials: Credentials, options?: TranslatorOptions);
65
+ getLanguages(): Promise<string[]>;
66
+ translate<T extends string | string[] | TextBlock[]>(text: T, source: string | null, target: string, options?: TranslateOptions, callback?: (partialResult: TextResult<T>) => void): Promise<TextResult<T>>;
67
+ detect(text: string | string[], hint?: string, passlist?: string[]): Promise<DetectResult>;
68
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Translator = void 0;
7
+ const documents_1 = require("./documents");
8
+ const glossaries_1 = require("./glossaries");
9
+ const memories_1 = require("./memories");
10
+ const net_1 = __importDefault(require("./net"));
11
+ class Translator {
12
+ constructor(credentials, options) {
13
+ this.client = (0, net_1.default)(credentials.accessKeyId, credentials.accessKeySecret, options === null || options === void 0 ? void 0 : options.serverUrl, options === null || options === void 0 ? void 0 : options.keepAlive);
14
+ this.memories = new memories_1.Memories(this.client);
15
+ this.documents = new documents_1.Documents(this.client);
16
+ this.glossaries = new glossaries_1.Glossaries(this.client);
17
+ }
18
+ async getLanguages() {
19
+ return await this.client.get("/languages");
20
+ }
21
+ async translate(text, source, target, options, callback) {
22
+ const headers = {};
23
+ if (options === null || options === void 0 ? void 0 : options.headers) {
24
+ for (const [name, value] of Object.entries(options.headers)) {
25
+ headers[name] = value;
26
+ }
27
+ }
28
+ if (options === null || options === void 0 ? void 0 : options.noTrace) {
29
+ headers["X-No-Trace"] = "true";
30
+ }
31
+ const response = this.client.postAndGetStream("/translate", {
32
+ q: text,
33
+ source,
34
+ target,
35
+ source_hint: options === null || options === void 0 ? void 0 : options.sourceHint,
36
+ content_type: options === null || options === void 0 ? void 0 : options.contentType,
37
+ multiline: (options === null || options === void 0 ? void 0 : options.multiline) !== false,
38
+ adapt_to: options === null || options === void 0 ? void 0 : options.adaptTo,
39
+ glossaries: options === null || options === void 0 ? void 0 : options.glossaries,
40
+ instructions: options === null || options === void 0 ? void 0 : options.instructions,
41
+ timeout: options === null || options === void 0 ? void 0 : options.timeoutInMillis,
42
+ priority: options === null || options === void 0 ? void 0 : options.priority,
43
+ use_cache: options === null || options === void 0 ? void 0 : options.useCache,
44
+ cache_ttl: options === null || options === void 0 ? void 0 : options.cacheTTLSeconds,
45
+ verbose: options === null || options === void 0 ? void 0 : options.verbose,
46
+ style: options === null || options === void 0 ? void 0 : options.style,
47
+ reasoning: options === null || options === void 0 ? void 0 : options.reasoning
48
+ }, undefined, headers);
49
+ let lastResult;
50
+ for await (const partial of response) {
51
+ if ((options === null || options === void 0 ? void 0 : options.reasoning) && callback)
52
+ callback(partial);
53
+ lastResult = partial;
54
+ }
55
+ if (!lastResult)
56
+ throw new Error("No translation result received.");
57
+ return lastResult;
58
+ }
59
+ async detect(text, hint, passlist) {
60
+ return await this.client.post("/detect", {
61
+ q: text,
62
+ hint,
63
+ passlist
64
+ });
65
+ }
66
+ }
67
+ exports.Translator = Translator;
@@ -0,0 +1 @@
1
+ export declare const version = "1.7.2";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
- exports.version = "1.7.0";
4
+ exports.version = "1.7.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@translated/lara",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "engines": {
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "scripts": {
10
10
  "build": "rm -rf lib/* lib-browser/* && node scripts/generate-sdk-version.js && tsc && webpack",
11
- "version": "node scripts/generate-sdk-version.js && git add src/sdk-version.ts",
11
+ "version": "node scripts/generate-sdk-version.js && git add src/utils/sdk-version.ts",
12
12
  "biome:check": "biome check",
13
13
  "biome:write": "biome check --write"
14
14
  },
@@ -1 +0,0 @@
1
- export declare const version = "1.7.0";
@@ -1,109 +0,0 @@
1
- export interface Memory {
2
- readonly id: string;
3
- readonly createdAt: Date;
4
- readonly updatedAt: Date;
5
- readonly sharedAt: Date;
6
- readonly name: string;
7
- readonly externalId?: string;
8
- readonly secret?: string;
9
- readonly ownerId: string;
10
- readonly collaboratorsCount: number;
11
- }
12
- export interface MemoryImport {
13
- readonly id: string;
14
- readonly begin: number;
15
- readonly end: number;
16
- readonly channel: number;
17
- readonly size: number;
18
- readonly progress: number;
19
- }
20
- export declare enum DocumentStatus {
21
- INITIALIZED = "initialized",// just been created
22
- ANALYZING = "analyzing",// being analyzed for language detection and chars count
23
- PAUSED = "paused",// paused after analysis, needs user confirm
24
- READY = "ready",// ready to be translated
25
- TRANSLATING = "translating",
26
- TRANSLATED = "translated",
27
- ERROR = "error"
28
- }
29
- export interface DocxExtractionParams {
30
- extractComments?: boolean;
31
- acceptRevisions?: boolean;
32
- }
33
- export type DocumentOptions = {
34
- adaptTo?: string[];
35
- glossaries?: string[];
36
- noTrace?: boolean;
37
- style?: TranslationStyle;
38
- };
39
- export type DocumentDownloadOptions = {
40
- outputFormat?: string;
41
- };
42
- export type DocumentUploadOptions = DocumentOptions & {
43
- password?: string;
44
- extractionParams?: DocxExtractionParams;
45
- };
46
- export interface Document {
47
- readonly id: string;
48
- readonly status: DocumentStatus;
49
- readonly source?: string;
50
- readonly target: string;
51
- readonly filename: string;
52
- readonly createdAt: Date;
53
- readonly updatedAt: Date;
54
- readonly options?: DocumentOptions;
55
- readonly translatedChars?: number;
56
- readonly totalChars?: number;
57
- readonly errorReason?: string;
58
- }
59
- export interface TextBlock {
60
- readonly text: string;
61
- readonly translatable?: boolean;
62
- }
63
- export interface NGMemoryMatch {
64
- memory: string;
65
- tuid?: string;
66
- language: [string, string];
67
- sentence: string;
68
- translation: string;
69
- score: number;
70
- }
71
- export interface NGGlossaryMatch {
72
- glossary: string;
73
- language: [string, string];
74
- term: string;
75
- translation: string;
76
- }
77
- export interface TextResult<T extends string | string[] | TextBlock[]> {
78
- readonly contentType: string;
79
- readonly sourceLanguage: string;
80
- readonly translation: T;
81
- readonly adaptedTo?: string[];
82
- readonly glossaries?: string[];
83
- readonly adaptedToMatches?: NGMemoryMatch[] | NGMemoryMatch[][];
84
- readonly glossariesMatches?: NGGlossaryMatch[] | NGGlossaryMatch[][];
85
- }
86
- export interface DetectResult {
87
- language: string;
88
- contentType: string;
89
- }
90
- export interface Glossary {
91
- readonly id: string;
92
- readonly name: string;
93
- readonly ownerId: string;
94
- readonly createdAt: Date;
95
- readonly updatedAt: Date;
96
- }
97
- export interface GlossaryImport {
98
- readonly id: string;
99
- readonly begin: number;
100
- readonly end: number;
101
- readonly channel: number;
102
- readonly size: number;
103
- readonly progress: number;
104
- }
105
- export interface GlossaryCounts {
106
- unidirectional?: Record<string, number>;
107
- multidirectional?: number;
108
- }
109
- export type TranslationStyle = "faithful" | "fluid" | "creative";
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DocumentStatus = void 0;
4
- // biome-ignore format: keep comments aligned
5
- var DocumentStatus;
6
- (function (DocumentStatus) {
7
- DocumentStatus["INITIALIZED"] = "initialized";
8
- DocumentStatus["ANALYZING"] = "analyzing";
9
- DocumentStatus["PAUSED"] = "paused";
10
- DocumentStatus["READY"] = "ready";
11
- DocumentStatus["TRANSLATING"] = "translating";
12
- DocumentStatus["TRANSLATED"] = "translated";
13
- DocumentStatus["ERROR"] = "error";
14
- })(DocumentStatus || (exports.DocumentStatus = DocumentStatus = {}));
@@ -1,81 +0,0 @@
1
- import type { Credentials } from "../credentials";
2
- import { type LaraClient } from "../net";
3
- import type { MultiPartFile } from "../net/client";
4
- import { type DetectResult, type Document, type DocumentDownloadOptions, type DocumentUploadOptions, type Glossary, type GlossaryCounts, type GlossaryImport, type Memory, type MemoryImport, type TextBlock, type TextResult, type TranslationStyle } from "./models";
5
- export type TranslatorOptions = {
6
- serverUrl?: string;
7
- };
8
- export type MemoryImportCallback = (memoryImport: MemoryImport) => void;
9
- export declare class Memories {
10
- private readonly client;
11
- private readonly pollingInterval;
12
- constructor(client: LaraClient);
13
- list(): Promise<Memory[]>;
14
- create(name: string, externalId?: string): Promise<Memory>;
15
- get(id: string): Promise<Memory | null>;
16
- delete(id: string): Promise<Memory>;
17
- update(id: string, name: string): Promise<Memory>;
18
- connect<T extends string | string[]>(ids: T): Promise<T extends string ? Memory : Memory[]>;
19
- importTmx(id: string, tmx: MultiPartFile, gzip?: boolean): Promise<MemoryImport>;
20
- addTranslation(id: string | string[], source: string, target: string, sentence: string, translation: string, tuid?: string, sentenceBefore?: string, sentenceAfter?: string, headers?: Record<string, string>): Promise<MemoryImport>;
21
- deleteTranslation(id: string | string[], source: string, target: string, sentence?: string, translation?: string, tuid?: string, sentenceBefore?: string, sentenceAfter?: string): Promise<MemoryImport>;
22
- getImportStatus(id: string): Promise<MemoryImport>;
23
- waitForImport(mImport: MemoryImport, updateCallback?: MemoryImportCallback, maxWaitTime?: number): Promise<MemoryImport>;
24
- }
25
- export type TranslateOptions = {
26
- sourceHint?: string;
27
- adaptTo?: string[];
28
- instructions?: string[];
29
- glossaries?: string[];
30
- contentType?: string;
31
- multiline?: boolean;
32
- timeoutInMillis?: number;
33
- priority?: "normal" | "background";
34
- useCache?: boolean | "overwrite";
35
- cacheTTLSeconds?: number;
36
- noTrace?: boolean;
37
- verbose?: boolean;
38
- headers?: Record<string, string>;
39
- style?: TranslationStyle;
40
- };
41
- export type DocumentTranslateOptions = DocumentUploadOptions & DocumentDownloadOptions;
42
- export type S3UploadFields = {
43
- acl: string;
44
- bucket: string;
45
- key: string;
46
- };
47
- export declare class Documents {
48
- private readonly client;
49
- private readonly s3Client;
50
- constructor(client: LaraClient);
51
- upload(file: MultiPartFile, filename: string, source: string | null, target: string, options?: DocumentUploadOptions): Promise<Document>;
52
- status(id: string): Promise<Document>;
53
- download(id: string, options?: DocumentDownloadOptions): Promise<Blob | Buffer>;
54
- translate(file: MultiPartFile, filename: string, source: string | null, target: string, options?: DocumentTranslateOptions): Promise<Blob | Buffer>;
55
- }
56
- export type GlossaryImportCallback = (glossaryImport: GlossaryImport) => void;
57
- export declare class Glossaries {
58
- private readonly client;
59
- private readonly pollingInterval;
60
- constructor(client: LaraClient);
61
- list(): Promise<Glossary[]>;
62
- create(name: string): Promise<Glossary>;
63
- get(id: string): Promise<Glossary | null>;
64
- delete(id: string): Promise<Glossary>;
65
- update(id: string, name: string): Promise<Glossary>;
66
- importCsv(id: string, csv: MultiPartFile, gzip?: boolean): Promise<GlossaryImport>;
67
- getImportStatus(id: string): Promise<GlossaryImport>;
68
- waitForImport(gImport: GlossaryImport, updateCallback?: GlossaryImportCallback, maxWaitTime?: number): Promise<GlossaryImport>;
69
- counts(id: string): Promise<GlossaryCounts>;
70
- export(id: string, contentType: "csv/table-uni", source?: string): Promise<string>;
71
- }
72
- export declare class Translator {
73
- protected readonly client: LaraClient;
74
- readonly memories: Memories;
75
- readonly documents: Documents;
76
- readonly glossaries: Glossaries;
77
- constructor(credentials: Credentials, options?: TranslatorOptions);
78
- getLanguages(): Promise<string[]>;
79
- translate<T extends string | string[] | TextBlock[]>(text: T, source: string | null, target: string, options?: TranslateOptions): Promise<TextResult<T>>;
80
- detect(text: string | string[], hint?: string, passlist?: string[]): Promise<DetectResult>;
81
- }