@translated/lara 1.8.0-beta.3 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/lib/audioTranslator.d.ts +44 -0
- package/lib/audioTranslator.js +62 -0
- package/lib/documents.d.ts +0 -5
- package/lib/glossaries.d.ts +11 -1
- package/lib/glossaries.js +24 -2
- package/lib/imageTranslator.d.ts +32 -0
- package/lib/imageTranslator.js +37 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.js +6 -1
- package/lib/net/lara/browser-client.d.ts +2 -2
- package/lib/net/lara/browser-client.js +25 -35
- package/lib/net/lara/client.d.ts +4 -4
- package/lib/net/lara/client.js +12 -12
- package/lib/net/lara/index.browser.d.ts +1 -1
- package/lib/net/lara/index.browser.js +2 -2
- package/lib/net/lara/index.d.ts +1 -1
- package/lib/net/lara/index.js +2 -2
- package/lib/net/lara/node-client.d.ts +2 -2
- package/lib/net/lara/node-client.js +53 -27
- package/lib/net/s3/browser-client.d.ts +1 -2
- package/lib/net/s3/client.d.ts +5 -1
- package/lib/net/s3/node-client.d.ts +1 -2
- package/lib/translator.d.ts +9 -0
- package/lib/translator.js +7 -3
- package/lib/utils/sdk-version.d.ts +1 -1
- package/lib/utils/sdk-version.js +1 -1
- package/lib_browser/lara.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ All major translation features are accessible, making it easy to integrate and c
|
|
|
10
10
|
## 🌍 **Features:**
|
|
11
11
|
- **Text Translation**: Single strings, multiple strings, and complex text blocks
|
|
12
12
|
- **Document Translation**: Word, PDF, and other document formats with status monitoring
|
|
13
|
+
- **Image Translation**: Translate whole images or extract and translate text blocks
|
|
13
14
|
- **Translation Memory**: Store and reuse translations for consistency
|
|
14
15
|
- **Glossaries**: Enforce terminology standards across translations
|
|
15
16
|
- **Language Detection**: Automatic source language identification
|
|
@@ -91,6 +92,17 @@ cd examples
|
|
|
91
92
|
node document_translation.js
|
|
92
93
|
```
|
|
93
94
|
|
|
95
|
+
### Image Translation
|
|
96
|
+
- **[image_translation.js](examples/image_translation.js)** - Image translation examples
|
|
97
|
+
- Basic image translation
|
|
98
|
+
- Advanced options with memories and glossaries
|
|
99
|
+
- Extract and translate text from an image
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
cd examples
|
|
103
|
+
node image_translation.js
|
|
104
|
+
```
|
|
105
|
+
|
|
94
106
|
### Translation Memory Management
|
|
95
107
|
- **[memories_management.js](examples/memories_management.js)** - Memory management examples
|
|
96
108
|
- Create, list, update, delete memories
|
|
@@ -245,6 +257,26 @@ const status = await lara.documents.status(document.id);
|
|
|
245
257
|
const translatedContent = await lara.documents.download(document.id);
|
|
246
258
|
```
|
|
247
259
|
|
|
260
|
+
### 🖼️ Image Translation
|
|
261
|
+
|
|
262
|
+
```javascript
|
|
263
|
+
const fs = require("fs");
|
|
264
|
+
|
|
265
|
+
const imageStream = fs.createReadStream("/path/to/your/image.png"); // Replace with actual file path
|
|
266
|
+
|
|
267
|
+
// Translate image and receive a translated image stream
|
|
268
|
+
const translatedImageStream = await lara.images.translate(imageStream, "en", "fr", {
|
|
269
|
+
textRemoval: "inpainting",
|
|
270
|
+
style: "faithful"
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Extract and translate text blocks from an image
|
|
274
|
+
const textBlocks = await lara.images.translateText(imageStream, "en", "fr", {
|
|
275
|
+
adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"],
|
|
276
|
+
glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"],
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
248
280
|
### 🧠 Memory Management
|
|
249
281
|
|
|
250
282
|
```javascript
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { LaraClient } from "./net/lara";
|
|
2
|
+
import type { MultiPartFile } from "./net/lara/client";
|
|
3
|
+
import type { LaraStream } from "./net/s3/laraStream";
|
|
4
|
+
import type { TranslationStyle } from "./translator";
|
|
5
|
+
export declare enum AudioStatus {
|
|
6
|
+
INITIALIZED = "initialized",// just been created
|
|
7
|
+
ANALYZING = "analyzing",// being analyzed for language detection and chars count
|
|
8
|
+
PAUSED = "paused",// paused after analysis, needs user confirm
|
|
9
|
+
READY = "ready",// ready to be translated
|
|
10
|
+
TRANSLATING = "translating",
|
|
11
|
+
TRANSLATED = "translated",
|
|
12
|
+
ERROR = "error"
|
|
13
|
+
}
|
|
14
|
+
export type AudioOptions = {
|
|
15
|
+
adaptTo?: string[];
|
|
16
|
+
glossaries?: string[];
|
|
17
|
+
noTrace?: boolean;
|
|
18
|
+
style?: TranslationStyle;
|
|
19
|
+
};
|
|
20
|
+
export type AudioUploadOptions = AudioOptions & {
|
|
21
|
+
contentLength?: number;
|
|
22
|
+
};
|
|
23
|
+
export interface Audio {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly status: AudioStatus;
|
|
26
|
+
readonly translatedSeconds?: number;
|
|
27
|
+
readonly totalSeconds?: number;
|
|
28
|
+
readonly source?: string;
|
|
29
|
+
readonly target: string;
|
|
30
|
+
readonly filename: string;
|
|
31
|
+
readonly createdAt: Date;
|
|
32
|
+
readonly updatedAt: Date;
|
|
33
|
+
readonly options?: AudioOptions;
|
|
34
|
+
readonly errorReason?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class AudioTranslator {
|
|
37
|
+
private readonly client;
|
|
38
|
+
private readonly s3Client;
|
|
39
|
+
constructor(client: LaraClient);
|
|
40
|
+
upload(file: MultiPartFile, filename: string, source: string | null, target: string, options?: AudioUploadOptions): Promise<Audio>;
|
|
41
|
+
status(id: string): Promise<Audio>;
|
|
42
|
+
download(id: string): Promise<LaraStream>;
|
|
43
|
+
translate(file: MultiPartFile, filename: string, source: string | null, target: string, options?: AudioUploadOptions): Promise<LaraStream>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
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.AudioTranslator = exports.AudioStatus = void 0;
|
|
7
|
+
const errors_1 = require("./errors");
|
|
8
|
+
const s3_1 = __importDefault(require("./net/s3"));
|
|
9
|
+
// biome-ignore format: keep comments aligned
|
|
10
|
+
var AudioStatus;
|
|
11
|
+
(function (AudioStatus) {
|
|
12
|
+
AudioStatus["INITIALIZED"] = "initialized";
|
|
13
|
+
AudioStatus["ANALYZING"] = "analyzing";
|
|
14
|
+
AudioStatus["PAUSED"] = "paused";
|
|
15
|
+
AudioStatus["READY"] = "ready";
|
|
16
|
+
AudioStatus["TRANSLATING"] = "translating";
|
|
17
|
+
AudioStatus["TRANSLATED"] = "translated";
|
|
18
|
+
AudioStatus["ERROR"] = "error";
|
|
19
|
+
})(AudioStatus || (exports.AudioStatus = AudioStatus = {}));
|
|
20
|
+
class AudioTranslator {
|
|
21
|
+
constructor(client) {
|
|
22
|
+
this.client = client;
|
|
23
|
+
this.s3Client = (0, s3_1.default)();
|
|
24
|
+
}
|
|
25
|
+
async upload(file, filename, source, target, options) {
|
|
26
|
+
const { url, fields } = await this.client.get(`/v2/audio/upload-url`, { filename });
|
|
27
|
+
await this.s3Client.upload(url, fields, file, options === null || options === void 0 ? void 0 : options.contentLength);
|
|
28
|
+
const headers = (options === null || options === void 0 ? void 0 : options.noTrace) ? { "X-No-Trace": "true" } : {};
|
|
29
|
+
return this.client.post(`/v2/audio/translate`, {
|
|
30
|
+
source,
|
|
31
|
+
target,
|
|
32
|
+
s3key: fields.key,
|
|
33
|
+
adapt_to: options === null || options === void 0 ? void 0 : options.adaptTo,
|
|
34
|
+
glossaries: options === null || options === void 0 ? void 0 : options.glossaries,
|
|
35
|
+
style: options === null || options === void 0 ? void 0 : options.style
|
|
36
|
+
}, undefined, headers);
|
|
37
|
+
}
|
|
38
|
+
async status(id) {
|
|
39
|
+
return await this.client.get(`/v2/audio/${id}`);
|
|
40
|
+
}
|
|
41
|
+
async download(id) {
|
|
42
|
+
const { url } = await this.client.get(`/v2/audio/${id}/download-url`);
|
|
43
|
+
return (await this.s3Client.downloadStream(url));
|
|
44
|
+
}
|
|
45
|
+
async translate(file, filename, source, target, options) {
|
|
46
|
+
const { id } = await this.upload(file, filename, source, target, options);
|
|
47
|
+
const pollingInterval = 2000;
|
|
48
|
+
const maxWaitTime = 1000 * 60 * 15; // 15 minutes
|
|
49
|
+
const start = Date.now();
|
|
50
|
+
while (Date.now() - start < maxWaitTime) {
|
|
51
|
+
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
52
|
+
const { status, errorReason } = await this.status(id);
|
|
53
|
+
if (status === AudioStatus.TRANSLATED)
|
|
54
|
+
return await this.download(id);
|
|
55
|
+
if (status === AudioStatus.ERROR) {
|
|
56
|
+
throw new errors_1.LaraApiError(500, "AudioError", errorReason);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
throw new errors_1.TimeoutError();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.AudioTranslator = AudioTranslator;
|
package/lib/documents.d.ts
CHANGED
|
@@ -2,11 +2,6 @@ import type { LaraClient } from "./net/lara";
|
|
|
2
2
|
import type { MultiPartFile } from "./net/lara/client";
|
|
3
3
|
import type { LaraStream } from "./net/s3/laraStream";
|
|
4
4
|
import type { TranslationStyle } from "./translator";
|
|
5
|
-
export type S3UploadFields = {
|
|
6
|
-
acl: string;
|
|
7
|
-
bucket: string;
|
|
8
|
-
key: string;
|
|
9
|
-
};
|
|
10
5
|
export declare enum DocumentStatus {
|
|
11
6
|
INITIALIZED = "initialized",// just been created
|
|
12
7
|
ANALYZING = "analyzing",// being analyzed for language detection and chars count
|
package/lib/glossaries.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export interface GlossaryCounts {
|
|
|
19
19
|
unidirectional?: Record<string, number>;
|
|
20
20
|
multidirectional?: number;
|
|
21
21
|
}
|
|
22
|
+
export type GlossaryFileFormat = "csv/table-uni" | "csv/table-multi";
|
|
22
23
|
export type GlossaryImportCallback = (glossaryImport: GlossaryImport) => void;
|
|
23
24
|
export declare class Glossaries {
|
|
24
25
|
private readonly client;
|
|
@@ -30,8 +31,17 @@ export declare class Glossaries {
|
|
|
30
31
|
delete(id: string): Promise<Glossary>;
|
|
31
32
|
update(id: string, name: string): Promise<Glossary>;
|
|
32
33
|
importCsv(id: string, csv: MultiPartFile, gzip?: boolean): Promise<GlossaryImport>;
|
|
34
|
+
importCsv(id: string, csv: MultiPartFile, contentType: GlossaryFileFormat, gzip?: boolean): Promise<GlossaryImport>;
|
|
33
35
|
getImportStatus(id: string): Promise<GlossaryImport>;
|
|
34
36
|
waitForImport(gImport: GlossaryImport, updateCallback?: GlossaryImportCallback, maxWaitTime?: number): Promise<GlossaryImport>;
|
|
35
37
|
counts(id: string): Promise<GlossaryCounts>;
|
|
36
|
-
export(id: string, contentType:
|
|
38
|
+
export(id: string, contentType: GlossaryFileFormat, source?: string): Promise<string>;
|
|
39
|
+
addOrReplaceEntry(id: string, terms: {
|
|
40
|
+
language: string;
|
|
41
|
+
value: string;
|
|
42
|
+
}[], guid?: string): Promise<GlossaryImport>;
|
|
43
|
+
deleteEntry(id: string, term?: {
|
|
44
|
+
language: string;
|
|
45
|
+
value: string;
|
|
46
|
+
}, guid?: string): Promise<GlossaryImport>;
|
|
37
47
|
}
|
package/lib/glossaries.js
CHANGED
|
@@ -30,9 +30,22 @@ class Glossaries {
|
|
|
30
30
|
async update(id, name) {
|
|
31
31
|
return await this.client.put(`/v2/glossaries/${id}`, { name });
|
|
32
32
|
}
|
|
33
|
-
async importCsv(id, csv,
|
|
33
|
+
async importCsv(id, csv, gzipOrContentType, maybeGzip) {
|
|
34
|
+
// Default values when no content type or gzip flag is provided
|
|
35
|
+
let gzip = false;
|
|
36
|
+
let contentType = "csv/table-uni";
|
|
37
|
+
if (typeof gzipOrContentType === "boolean") {
|
|
38
|
+
// First overload: (id, csv, gzip)
|
|
39
|
+
gzip = gzipOrContentType;
|
|
40
|
+
}
|
|
41
|
+
else if (typeof gzipOrContentType === "string") {
|
|
42
|
+
// Second overload: (id, csv, contentType, gzip)
|
|
43
|
+
contentType = gzipOrContentType;
|
|
44
|
+
gzip = maybeGzip !== null && maybeGzip !== void 0 ? maybeGzip : false;
|
|
45
|
+
}
|
|
34
46
|
return await this.client.post(`/v2/glossaries/${id}/import`, {
|
|
35
|
-
compression: gzip ? "gzip" : undefined
|
|
47
|
+
compression: gzip ? "gzip" : undefined,
|
|
48
|
+
content_type: contentType
|
|
36
49
|
}, {
|
|
37
50
|
csv
|
|
38
51
|
});
|
|
@@ -61,5 +74,14 @@ class Glossaries {
|
|
|
61
74
|
source
|
|
62
75
|
});
|
|
63
76
|
}
|
|
77
|
+
async addOrReplaceEntry(id, terms, guid) {
|
|
78
|
+
return await this.client.put(`/v2/glossaries/${id}/content`, { terms, guid });
|
|
79
|
+
}
|
|
80
|
+
async deleteEntry(id, term, guid) {
|
|
81
|
+
return await this.client.delete(`/v2/glossaries/${id}/content`, undefined, {
|
|
82
|
+
term,
|
|
83
|
+
guid
|
|
84
|
+
});
|
|
85
|
+
}
|
|
64
86
|
}
|
|
65
87
|
exports.Glossaries = Glossaries;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { LaraClient } from "./net/lara";
|
|
2
|
+
import type { MultiPartFile } from "./net/lara/client";
|
|
3
|
+
import type { LaraStream } from "./net/s3/laraStream";
|
|
4
|
+
import type { NGGlossaryMatch, NGMemoryMatch, TranslationStyle } from "./translator";
|
|
5
|
+
export type ImageParagraph = {
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly translation: string;
|
|
8
|
+
readonly adaptedToMatches?: NGMemoryMatch[];
|
|
9
|
+
readonly glossariesMatches?: NGGlossaryMatch[];
|
|
10
|
+
};
|
|
11
|
+
export type ImageTextResult = {
|
|
12
|
+
readonly sourceLanguage: string;
|
|
13
|
+
readonly adaptedTo?: string[];
|
|
14
|
+
readonly glossaries?: string[];
|
|
15
|
+
readonly paragraphs: ImageParagraph[];
|
|
16
|
+
};
|
|
17
|
+
export type ImageTextTranslationOptions = {
|
|
18
|
+
adaptTo?: string[];
|
|
19
|
+
glossaries?: string[];
|
|
20
|
+
style?: TranslationStyle;
|
|
21
|
+
noTrace?: boolean;
|
|
22
|
+
verbose?: boolean;
|
|
23
|
+
};
|
|
24
|
+
export type ImageTranslationOptions = Omit<ImageTextTranslationOptions & {
|
|
25
|
+
textRemoval?: "overlay" | "inpainting";
|
|
26
|
+
}, "verbose">;
|
|
27
|
+
export declare class ImageTranslator {
|
|
28
|
+
private readonly client;
|
|
29
|
+
constructor(client: LaraClient);
|
|
30
|
+
translate(file: MultiPartFile, source: string | null, target: string, options?: ImageTranslationOptions): Promise<LaraStream>;
|
|
31
|
+
translateText(file: MultiPartFile, source: string | null, target: string, options?: ImageTextTranslationOptions): Promise<ImageTextResult>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ImageTranslator = void 0;
|
|
4
|
+
class ImageTranslator {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
async translate(file, source, target, options) {
|
|
9
|
+
const headers = (options === null || options === void 0 ? void 0 : options.noTrace) ? { "X-No-Trace": "true" } : {};
|
|
10
|
+
headers["Content-Type"] = "multipart/form-data";
|
|
11
|
+
return this.client.post(`/v2/images/translate`, {
|
|
12
|
+
source,
|
|
13
|
+
target,
|
|
14
|
+
adapt_to: JSON.stringify(options === null || options === void 0 ? void 0 : options.adaptTo),
|
|
15
|
+
glossaries: JSON.stringify(options === null || options === void 0 ? void 0 : options.glossaries),
|
|
16
|
+
style: options === null || options === void 0 ? void 0 : options.style,
|
|
17
|
+
text_removal: options === null || options === void 0 ? void 0 : options.textRemoval
|
|
18
|
+
}, {
|
|
19
|
+
image: file
|
|
20
|
+
}, headers, true);
|
|
21
|
+
}
|
|
22
|
+
async translateText(file, source, target, options) {
|
|
23
|
+
const headers = (options === null || options === void 0 ? void 0 : options.noTrace) ? { "X-No-Trace": "true" } : {};
|
|
24
|
+
headers["Content-Type"] = "multipart/form-data";
|
|
25
|
+
return this.client.post(`/v2/images/translate-text`, {
|
|
26
|
+
source,
|
|
27
|
+
target,
|
|
28
|
+
adapt_to: JSON.stringify(options === null || options === void 0 ? void 0 : options.adaptTo),
|
|
29
|
+
glossaries: JSON.stringify(options === null || options === void 0 ? void 0 : options.glossaries),
|
|
30
|
+
style: options === null || options === void 0 ? void 0 : options.style,
|
|
31
|
+
verbose: JSON.stringify(options === null || options === void 0 ? void 0 : options.verbose)
|
|
32
|
+
}, {
|
|
33
|
+
image: file
|
|
34
|
+
}, headers);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.ImageTranslator = ImageTranslator;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
export { Audio, AudioStatus, AudioTranslator, AudioUploadOptions } from "./audioTranslator";
|
|
1
2
|
export { AccessKey, AuthToken, Credentials } from "./credentials";
|
|
2
3
|
export { Document, DocumentDownloadOptions, DocumentStatus, Documents, DocumentTranslateOptions, DocumentUploadOptions } from "./documents";
|
|
3
4
|
export { LaraApiError, LaraError, TimeoutError } from "./errors";
|
|
4
|
-
export { Glossaries, GlossaryImport, GlossaryImportCallback } from "./glossaries";
|
|
5
|
+
export { Glossaries, GlossaryFileFormat, GlossaryImport, GlossaryImportCallback } from "./glossaries";
|
|
6
|
+
export { ImageParagraph, ImageTextResult, ImageTextTranslationOptions, ImageTranslationOptions, ImageTranslator } from "./imageTranslator";
|
|
5
7
|
export { Memories, Memory, MemoryImport, MemoryImportCallback } from "./memories";
|
|
6
8
|
export { MultiPartFile } from "./net/lara/client";
|
|
7
9
|
export type { LaraStream } from "./net/s3/laraStream";
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.version = exports.Translator = exports.Memories = exports.Glossaries = exports.TimeoutError = exports.LaraError = exports.LaraApiError = exports.Documents = exports.DocumentStatus = exports.Credentials = exports.AuthToken = exports.AccessKey = void 0;
|
|
3
|
+
exports.version = exports.Translator = exports.Memories = exports.ImageTranslator = exports.Glossaries = exports.TimeoutError = exports.LaraError = exports.LaraApiError = exports.Documents = exports.DocumentStatus = exports.Credentials = exports.AuthToken = exports.AccessKey = exports.AudioTranslator = exports.AudioStatus = void 0;
|
|
4
|
+
var audioTranslator_1 = require("./audioTranslator");
|
|
5
|
+
Object.defineProperty(exports, "AudioStatus", { enumerable: true, get: function () { return audioTranslator_1.AudioStatus; } });
|
|
6
|
+
Object.defineProperty(exports, "AudioTranslator", { enumerable: true, get: function () { return audioTranslator_1.AudioTranslator; } });
|
|
4
7
|
var credentials_1 = require("./credentials");
|
|
5
8
|
Object.defineProperty(exports, "AccessKey", { enumerable: true, get: function () { return credentials_1.AccessKey; } });
|
|
6
9
|
Object.defineProperty(exports, "AuthToken", { enumerable: true, get: function () { return credentials_1.AuthToken; } });
|
|
@@ -14,6 +17,8 @@ Object.defineProperty(exports, "LaraError", { enumerable: true, get: function ()
|
|
|
14
17
|
Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_1.TimeoutError; } });
|
|
15
18
|
var glossaries_1 = require("./glossaries");
|
|
16
19
|
Object.defineProperty(exports, "Glossaries", { enumerable: true, get: function () { return glossaries_1.Glossaries; } });
|
|
20
|
+
var imageTranslator_1 = require("./imageTranslator");
|
|
21
|
+
Object.defineProperty(exports, "ImageTranslator", { enumerable: true, get: function () { return imageTranslator_1.ImageTranslator; } });
|
|
17
22
|
var memories_1 = require("./memories");
|
|
18
23
|
Object.defineProperty(exports, "Memories", { enumerable: true, get: function () { return memories_1.Memories; } });
|
|
19
24
|
var translator_1 = require("./translator");
|
|
@@ -4,8 +4,8 @@ import { type BaseURL, type ClientResponse, LaraClient, type MultiPartFile } fro
|
|
|
4
4
|
export declare class BrowserLaraClient extends LaraClient {
|
|
5
5
|
private readonly baseUrl;
|
|
6
6
|
private readonly timeout;
|
|
7
|
-
constructor(baseUrl: BaseURL, auth: AccessKey | AuthToken, timeout?: number);
|
|
8
|
-
protected send(method: string, path: string, headers: Record<string, string>, body?: Record<string, any
|
|
7
|
+
constructor(baseUrl: BaseURL, auth: AccessKey | AuthToken, keepAlive: boolean, timeout?: number);
|
|
8
|
+
protected send(method: string, path: string, headers: Record<string, string>, body?: Record<string, any>, streamResponse?: boolean): Promise<ClientResponse>;
|
|
9
9
|
protected sendAndGetStream(method: string, path: string, headers: Record<string, string>, body?: Record<string, any>): AsyncGenerator<ClientResponse>;
|
|
10
10
|
protected wrapMultiPartFile(file: MultiPartFile): File;
|
|
11
11
|
}
|
|
@@ -8,7 +8,7 @@ function hasDefaultPort(port, secure) {
|
|
|
8
8
|
}
|
|
9
9
|
/** @internal */
|
|
10
10
|
class BrowserLaraClient extends client_1.LaraClient {
|
|
11
|
-
constructor(baseUrl, auth, timeout) {
|
|
11
|
+
constructor(baseUrl, auth, keepAlive, timeout) {
|
|
12
12
|
super(auth);
|
|
13
13
|
let url = `${baseUrl.secure ? "https" : "http"}://${baseUrl.hostname}`;
|
|
14
14
|
if (!hasDefaultPort(baseUrl.port, baseUrl.secure))
|
|
@@ -16,7 +16,7 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
16
16
|
this.baseUrl = url;
|
|
17
17
|
this.timeout = timeout;
|
|
18
18
|
}
|
|
19
|
-
async send(method, path, headers, body) {
|
|
19
|
+
async send(method, path, headers, body, streamResponse) {
|
|
20
20
|
var _a;
|
|
21
21
|
let requestBody;
|
|
22
22
|
if (body) {
|
|
@@ -40,27 +40,20 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
40
40
|
requestBody = JSON.stringify(body, undefined, 0);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
let abortController;
|
|
45
|
-
let timeoutId;
|
|
46
|
-
if (this.timeout && this.timeout > 0) {
|
|
47
|
-
console.log("Setting up timeout:", this.timeout);
|
|
48
|
-
abortController = new AbortController();
|
|
49
|
-
timeoutId = setTimeout(() => {
|
|
50
|
-
abortController.abort();
|
|
51
|
-
console.log('abort called due to timeout');
|
|
52
|
-
}, this.timeout);
|
|
53
|
-
}
|
|
43
|
+
const signal = this.timeout && this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined;
|
|
54
44
|
try {
|
|
55
45
|
const response = await fetch(this.baseUrl + path, {
|
|
56
46
|
headers,
|
|
57
47
|
method,
|
|
58
48
|
body: requestBody,
|
|
59
|
-
signal
|
|
49
|
+
signal
|
|
60
50
|
});
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
if (streamResponse && response.status >= 200 && response.status < 300) {
|
|
52
|
+
return {
|
|
53
|
+
statusCode: response.status,
|
|
54
|
+
body: response.body,
|
|
55
|
+
headers: Object.fromEntries(response.headers)
|
|
56
|
+
};
|
|
64
57
|
}
|
|
65
58
|
if ((_a = response.headers.get("Content-Type")) === null || _a === void 0 ? void 0 : _a.includes("text/csv")) {
|
|
66
59
|
return {
|
|
@@ -78,9 +71,7 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
78
71
|
};
|
|
79
72
|
}
|
|
80
73
|
catch (err) {
|
|
81
|
-
if (
|
|
82
|
-
clearTimeout(timeoutId);
|
|
83
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
74
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) {
|
|
84
75
|
throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
85
76
|
}
|
|
86
77
|
throw err;
|
|
@@ -109,32 +100,22 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
109
100
|
requestBody = JSON.stringify(body, undefined, 0);
|
|
110
101
|
}
|
|
111
102
|
}
|
|
112
|
-
|
|
113
|
-
let abortController;
|
|
114
|
-
let timeoutId;
|
|
115
|
-
if (this.timeout && this.timeout > 0) {
|
|
116
|
-
abortController = new AbortController();
|
|
117
|
-
timeoutId = setTimeout(() => abortController.abort(), this.timeout);
|
|
118
|
-
}
|
|
103
|
+
const signal = this.timeout && this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined;
|
|
119
104
|
let response;
|
|
120
105
|
try {
|
|
121
106
|
response = await fetch(this.baseUrl + path, {
|
|
122
107
|
headers,
|
|
123
108
|
method,
|
|
124
109
|
body: requestBody,
|
|
125
|
-
signal
|
|
110
|
+
signal
|
|
126
111
|
});
|
|
127
112
|
}
|
|
128
113
|
catch (err) {
|
|
129
|
-
if (
|
|
130
|
-
clearTimeout(timeoutId);
|
|
131
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
114
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) {
|
|
132
115
|
throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
133
116
|
}
|
|
134
117
|
throw err;
|
|
135
118
|
}
|
|
136
|
-
if (timeoutId)
|
|
137
|
-
clearTimeout(timeoutId);
|
|
138
119
|
if (!response.body) {
|
|
139
120
|
throw new Error("Response body is not available for streaming");
|
|
140
121
|
}
|
|
@@ -143,13 +124,22 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
143
124
|
let buffer = "";
|
|
144
125
|
try {
|
|
145
126
|
while (true) {
|
|
146
|
-
|
|
127
|
+
let readResult;
|
|
128
|
+
try {
|
|
129
|
+
readResult = await reader.read();
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) {
|
|
133
|
+
throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
134
|
+
}
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
const { done, value } = readResult;
|
|
147
138
|
if (done) {
|
|
148
139
|
// Process any remaining data in buffer
|
|
149
140
|
if (buffer.trim()) {
|
|
150
141
|
try {
|
|
151
142
|
const json = JSON.parse(buffer);
|
|
152
|
-
console.log(json);
|
|
153
143
|
yield {
|
|
154
144
|
statusCode: json.status || response.status,
|
|
155
145
|
body: json.data || json,
|
package/lib/net/lara/client.d.ts
CHANGED
|
@@ -29,11 +29,11 @@ export declare abstract class LaraClient {
|
|
|
29
29
|
setExtraHeader(name: string, value: string): void;
|
|
30
30
|
get<T>(path: string, queryParams?: Record<string, any>, headers?: Record<string, string>): Promise<T>;
|
|
31
31
|
delete<T>(path: string, queryParams?: Record<string, any>, body?: Record<string, any>, headers?: Record<string, string>): Promise<T>;
|
|
32
|
-
post<T>(path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string
|
|
32
|
+
post<T>(path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string>, streamResponse?: boolean): Promise<T>;
|
|
33
33
|
postAndGetStream<T>(path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string>): AsyncGenerator<T>;
|
|
34
34
|
put<T>(path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string>): Promise<T>;
|
|
35
|
-
protected request<T>(method: HttpMethod, path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string
|
|
36
|
-
protected requestStream<T>(method: HttpMethod, path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string
|
|
35
|
+
protected request<T>(method: HttpMethod, path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string>, retryCount?: number, streamResponse?: boolean): Promise<T>;
|
|
36
|
+
protected requestStream<T>(method: HttpMethod, path: string, body?: Record<string, any>, files?: Record<string, MultiPartFile>, headers?: Record<string, string>, retryCount?: number): AsyncGenerator<T>;
|
|
37
37
|
private ensureAuthenticated;
|
|
38
38
|
private performAuthentication;
|
|
39
39
|
private refreshTokens;
|
|
@@ -46,7 +46,7 @@ export declare abstract class LaraClient {
|
|
|
46
46
|
private handleAuthResponse;
|
|
47
47
|
private createApiError;
|
|
48
48
|
private sign;
|
|
49
|
-
protected abstract send(method: HttpMethod, path: string, headers: Record<string, string>, body?: Record<string, any
|
|
49
|
+
protected abstract send(method: HttpMethod, path: string, headers: Record<string, string>, body?: Record<string, any>, stream?: boolean): Promise<ClientResponse>;
|
|
50
50
|
protected abstract sendAndGetStream(method: HttpMethod, path: string, headers: Record<string, string>, body?: Record<string, any>): AsyncGenerator<ClientResponse>;
|
|
51
51
|
protected abstract wrapMultiPartFile(file: MultiPartFile): any;
|
|
52
52
|
}
|
package/lib/net/lara/client.js
CHANGED
|
@@ -36,8 +36,8 @@ class LaraClient {
|
|
|
36
36
|
delete(path, queryParams, body, headers) {
|
|
37
37
|
return this.request("DELETE", this.buildPathWithQuery(path, queryParams), body, undefined, headers);
|
|
38
38
|
}
|
|
39
|
-
post(path, body, files, headers) {
|
|
40
|
-
return this.request("POST", path, body, files, headers);
|
|
39
|
+
post(path, body, files, headers, streamResponse) {
|
|
40
|
+
return this.request("POST", path, body, files, headers, undefined, streamResponse);
|
|
41
41
|
}
|
|
42
42
|
async *postAndGetStream(path, body, files, headers) {
|
|
43
43
|
for await (const chunk of this.requestStream("POST", path, body, files, headers)) {
|
|
@@ -50,25 +50,25 @@ class LaraClient {
|
|
|
50
50
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
51
51
|
// Request Handling
|
|
52
52
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
53
|
-
async request(method, path, body, files, headers) {
|
|
53
|
+
async request(method, path, body, files, headers, retryCount = 0, streamResponse) {
|
|
54
54
|
await this.ensureAuthenticated();
|
|
55
55
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
56
56
|
const requestHeaders = await this.buildRequestHeaders(body, files, headers);
|
|
57
57
|
const requestBody = this.buildRequestBody(body, files);
|
|
58
58
|
requestHeaders.Authorization = `Bearer ${this.token}`;
|
|
59
|
-
const response = await this.send(method, normalizedPath, requestHeaders, requestBody);
|
|
59
|
+
const response = await this.send(method, normalizedPath, requestHeaders, requestBody, streamResponse);
|
|
60
60
|
if (this.isSuccessResponse(response)) {
|
|
61
|
-
return (0, parse_content_1.parseContent)(response.body);
|
|
61
|
+
return streamResponse ? response.body : (0, parse_content_1.parseContent)(response.body);
|
|
62
62
|
}
|
|
63
63
|
// Handle 401 - token expired, refresh and retry once
|
|
64
|
-
if (response.statusCode === 401) {
|
|
64
|
+
if (response.statusCode === 401 && retryCount < 1) {
|
|
65
65
|
this.token = undefined;
|
|
66
66
|
await this.refreshTokens();
|
|
67
|
-
return this.request(method, path, body, files, headers);
|
|
67
|
+
return this.request(method, path, body, files, headers, retryCount + 1, streamResponse);
|
|
68
68
|
}
|
|
69
69
|
throw this.createApiError(response);
|
|
70
70
|
}
|
|
71
|
-
async *requestStream(method, path, body, files, headers) {
|
|
71
|
+
async *requestStream(method, path, body, files, headers, retryCount = 0) {
|
|
72
72
|
await this.ensureAuthenticated();
|
|
73
73
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
74
74
|
const requestHeaders = await this.buildRequestHeaders(body, files, headers);
|
|
@@ -76,17 +76,17 @@ class LaraClient {
|
|
|
76
76
|
requestHeaders.Authorization = `Bearer ${this.token}`;
|
|
77
77
|
for await (const chunk of this.sendAndGetStream(method, normalizedPath, requestHeaders, requestBody)) {
|
|
78
78
|
// Handle 401 - token expired, refresh and retry once
|
|
79
|
-
if (chunk.statusCode === 401) {
|
|
79
|
+
if (chunk.statusCode === 401 && retryCount < 1) {
|
|
80
80
|
this.token = undefined;
|
|
81
81
|
await this.refreshTokens();
|
|
82
|
-
yield* this.requestStream(method, path, body, files, headers);
|
|
82
|
+
yield* this.requestStream(method, path, body, files, headers, retryCount + 1);
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
85
|
// Handle other errors
|
|
86
86
|
if (!this.isSuccessResponse(chunk)) {
|
|
87
87
|
throw this.createApiError(chunk);
|
|
88
88
|
}
|
|
89
|
-
yield (0, parse_content_1.parseContent)(chunk.body);
|
|
89
|
+
yield (0, parse_content_1.parseContent)(chunk.body.content || chunk.body);
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -224,7 +224,7 @@ class LaraClient {
|
|
|
224
224
|
}
|
|
225
225
|
createApiError(response) {
|
|
226
226
|
var _a;
|
|
227
|
-
const error = ((_a = response.body) === null || _a === void 0 ? void 0 : _a.error) || {};
|
|
227
|
+
const error = ((_a = response.body) === null || _a === void 0 ? void 0 : _a.error) || response.body || {};
|
|
228
228
|
return new errors_1.LaraApiError(response.statusCode, error.type || "UnknownError", error.message || "An unknown error occurred");
|
|
229
229
|
}
|
|
230
230
|
async sign(method, path, headers) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AccessKey, AuthToken } from "../../credentials";
|
|
2
2
|
import type { LaraClient } from "./client";
|
|
3
3
|
export { LaraClient } from "./client";
|
|
4
|
-
export default function create(auth: AccessKey | AuthToken, baseUrl?: string, timeout?: number): LaraClient;
|
|
4
|
+
export default function create(auth: AccessKey | AuthToken, baseUrl?: string, keepAlive?: boolean, timeout?: number): LaraClient;
|
|
5
5
|
export { BrowserClient as HttpClient } from "./browser-client";
|
|
@@ -6,7 +6,7 @@ const defaultBaseUrl_1 = require("../../utils/defaultBaseUrl");
|
|
|
6
6
|
const browser_client_1 = require("./browser-client");
|
|
7
7
|
var client_1 = require("./client");
|
|
8
8
|
Object.defineProperty(exports, "LaraClient", { enumerable: true, get: function () { return client_1.LaraClient; } });
|
|
9
|
-
function create(auth, baseUrl, timeout) {
|
|
9
|
+
function create(auth, baseUrl, keepAlive, timeout) {
|
|
10
10
|
const url = new URL(baseUrl || defaultBaseUrl_1.DEFAULT_BASE_URL);
|
|
11
11
|
if (url.protocol !== "https:" && url.protocol !== "http:")
|
|
12
12
|
throw new TypeError(`Invalid URL (protocol): ${url.protocol}`);
|
|
@@ -15,7 +15,7 @@ function create(auth, baseUrl, timeout) {
|
|
|
15
15
|
hostname: url.hostname,
|
|
16
16
|
port: url.port ? parseInt(url.port, 10) : url.protocol === "https:" ? 443 : 80
|
|
17
17
|
};
|
|
18
|
-
return new browser_client_1.BrowserLaraClient(parsedURL, auth, timeout);
|
|
18
|
+
return new browser_client_1.BrowserLaraClient(parsedURL, auth, keepAlive !== null && keepAlive !== void 0 ? keepAlive : true, timeout);
|
|
19
19
|
}
|
|
20
20
|
var browser_client_2 = require("./browser-client");
|
|
21
21
|
Object.defineProperty(exports, "HttpClient", { enumerable: true, get: function () { return browser_client_2.BrowserClient; } });
|
package/lib/net/lara/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AccessKey, AuthToken } from "../../credentials";
|
|
2
2
|
import type { LaraClient } from "./client";
|
|
3
3
|
export { LaraClient } from "./client";
|
|
4
|
-
export default function create(auth: AccessKey | AuthToken, baseUrl?: string, timeout?: number): LaraClient;
|
|
4
|
+
export default function create(auth: AccessKey | AuthToken, baseUrl?: string, keepAlive?: boolean, timeout?: number): LaraClient;
|
|
5
5
|
export { NodeClient as HttpClient } from "./node-client";
|
package/lib/net/lara/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const defaultBaseUrl_1 = require("../../utils/defaultBaseUrl");
|
|
|
6
6
|
const node_client_1 = require("./node-client");
|
|
7
7
|
var client_1 = require("./client");
|
|
8
8
|
Object.defineProperty(exports, "LaraClient", { enumerable: true, get: function () { return client_1.LaraClient; } });
|
|
9
|
-
function create(auth, baseUrl, timeout) {
|
|
9
|
+
function create(auth, baseUrl, keepAlive, timeout) {
|
|
10
10
|
const url = new URL(baseUrl || defaultBaseUrl_1.DEFAULT_BASE_URL);
|
|
11
11
|
if (url.protocol !== "https:" && url.protocol !== "http:")
|
|
12
12
|
throw new TypeError(`Invalid URL (protocol): ${url.protocol}`);
|
|
@@ -15,7 +15,7 @@ function create(auth, baseUrl, timeout) {
|
|
|
15
15
|
hostname: url.hostname,
|
|
16
16
|
port: url.port ? parseInt(url.port, 10) : url.protocol === "https:" ? 443 : 80
|
|
17
17
|
};
|
|
18
|
-
return new node_client_1.NodeLaraClient(parsedURL, auth, timeout);
|
|
18
|
+
return new node_client_1.NodeLaraClient(parsedURL, auth, keepAlive !== null && keepAlive !== void 0 ? keepAlive : true, timeout);
|
|
19
19
|
}
|
|
20
20
|
var node_client_2 = require("./node-client");
|
|
21
21
|
Object.defineProperty(exports, "HttpClient", { enumerable: true, get: function () { return node_client_2.NodeClient; } });
|
|
@@ -6,8 +6,8 @@ export declare class NodeLaraClient extends LaraClient {
|
|
|
6
6
|
private readonly baseUrl;
|
|
7
7
|
private readonly agent;
|
|
8
8
|
private readonly timeout;
|
|
9
|
-
constructor(baseUrl: BaseURL, auth: AccessKey | AuthToken, timeout?: number);
|
|
10
|
-
protected send(method: string, path: string, headers: Record<string, string>, body?: Record<string, any
|
|
9
|
+
constructor(baseUrl: BaseURL, auth: AccessKey | AuthToken, keepAlive: boolean, timeout?: number);
|
|
10
|
+
protected send(method: string, path: string, headers: Record<string, string>, body?: Record<string, any>, streamResponse?: boolean): Promise<ClientResponse>;
|
|
11
11
|
protected sendAndGetStream(method: string, path: string, headers: Record<string, string>, body?: Record<string, any>): AsyncGenerator<ClientResponse>;
|
|
12
12
|
protected wrapMultiPartFile(file: MultiPartFile): Readable;
|
|
13
13
|
}
|
|
@@ -8,18 +8,19 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
8
8
|
const node_http_1 = __importDefault(require("node:http"));
|
|
9
9
|
const node_https_1 = __importDefault(require("node:https"));
|
|
10
10
|
const node_stream_1 = require("node:stream");
|
|
11
|
+
const node_timers_1 = require("node:timers");
|
|
11
12
|
const form_data_1 = __importDefault(require("form-data"));
|
|
12
13
|
const errors_1 = require("../../errors");
|
|
13
14
|
const client_1 = require("./client");
|
|
14
15
|
/** @internal */
|
|
15
16
|
class NodeLaraClient extends client_1.LaraClient {
|
|
16
|
-
constructor(baseUrl, auth, timeout) {
|
|
17
|
+
constructor(baseUrl, auth, keepAlive, timeout) {
|
|
17
18
|
super(auth);
|
|
18
19
|
this.baseUrl = baseUrl;
|
|
19
|
-
this.agent = baseUrl.secure ? new node_https_1.default.Agent({ keepAlive
|
|
20
|
+
this.agent = baseUrl.secure ? new node_https_1.default.Agent({ keepAlive }) : new node_http_1.default.Agent({ keepAlive });
|
|
20
21
|
this.timeout = timeout;
|
|
21
22
|
}
|
|
22
|
-
async send(method, path, headers, body) {
|
|
23
|
+
async send(method, path, headers, body, streamResponse) {
|
|
23
24
|
let requestBody;
|
|
24
25
|
if (body) {
|
|
25
26
|
if (headers["Content-Type"] === "multipart/form-data") {
|
|
@@ -54,21 +55,31 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
54
55
|
headers: headers,
|
|
55
56
|
agent: this.agent
|
|
56
57
|
};
|
|
58
|
+
let hardTimeout = null;
|
|
57
59
|
const req = (this.baseUrl.secure ? node_https_1.default : node_http_1.default).request(options, (res) => {
|
|
58
60
|
let data = "";
|
|
61
|
+
if (streamResponse && res.statusCode >= 200 && res.statusCode < 300) {
|
|
62
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
63
|
+
return resolve({
|
|
64
|
+
statusCode: res.statusCode,
|
|
65
|
+
body: res,
|
|
66
|
+
headers: res.headers
|
|
67
|
+
});
|
|
68
|
+
}
|
|
59
69
|
// biome-ignore lint/suspicious/noAssignInExpressions: store response data
|
|
60
70
|
res.on("data", (chunk) => (data += chunk));
|
|
61
71
|
res.on("end", () => {
|
|
62
72
|
var _a;
|
|
73
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
63
74
|
let json;
|
|
64
75
|
if ((_a = res.headers["content-type"]) === null || _a === void 0 ? void 0 : _a.includes("application/json")) {
|
|
65
76
|
try {
|
|
66
77
|
json = JSON.parse(data);
|
|
67
78
|
}
|
|
68
79
|
catch (_e) {
|
|
69
|
-
reject(new SyntaxError("Invalid JSON response"));
|
|
80
|
+
return reject(new SyntaxError("Invalid JSON response"));
|
|
70
81
|
}
|
|
71
|
-
resolve({
|
|
82
|
+
return resolve({
|
|
72
83
|
statusCode: res.statusCode,
|
|
73
84
|
body: json,
|
|
74
85
|
headers: res.headers
|
|
@@ -82,21 +93,26 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
82
93
|
});
|
|
83
94
|
}
|
|
84
95
|
});
|
|
96
|
+
res.on("error", (err) => {
|
|
97
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
98
|
+
if (err instanceof errors_1.TimeoutError)
|
|
99
|
+
return reject(err);
|
|
100
|
+
req.destroy();
|
|
101
|
+
return reject(err);
|
|
102
|
+
});
|
|
85
103
|
});
|
|
86
104
|
req.on("error", (err) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
105
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
106
|
+
if (err instanceof errors_1.TimeoutError)
|
|
107
|
+
return reject(err);
|
|
108
|
+
req.destroy();
|
|
109
|
+
return reject(err);
|
|
93
110
|
});
|
|
94
111
|
// Set timeout if provided and positive
|
|
95
112
|
if (this.timeout && this.timeout > 0) {
|
|
96
|
-
|
|
97
|
-
req.
|
|
98
|
-
|
|
99
|
-
});
|
|
113
|
+
hardTimeout = setTimeout(() => {
|
|
114
|
+
req.destroy(new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`));
|
|
115
|
+
}, this.timeout);
|
|
100
116
|
}
|
|
101
117
|
if (requestBody instanceof form_data_1.default) {
|
|
102
118
|
requestBody.pipe(req);
|
|
@@ -144,6 +160,7 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
144
160
|
headers: headers,
|
|
145
161
|
agent: this.agent
|
|
146
162
|
};
|
|
163
|
+
let hardTimeout = null;
|
|
147
164
|
// Create async iterator from the stream
|
|
148
165
|
const chunks = [];
|
|
149
166
|
let resolveChunk = null;
|
|
@@ -176,6 +193,7 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
176
193
|
}
|
|
177
194
|
});
|
|
178
195
|
res.on("end", () => {
|
|
196
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
179
197
|
// Process any remaining data in buffer
|
|
180
198
|
if (buffer.trim()) {
|
|
181
199
|
try {
|
|
@@ -196,14 +214,23 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
196
214
|
resolveChunk = null;
|
|
197
215
|
}
|
|
198
216
|
});
|
|
217
|
+
res.on("error", (err) => {
|
|
218
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
219
|
+
if (err instanceof errors_1.TimeoutError)
|
|
220
|
+
throw err;
|
|
221
|
+
req.destroy();
|
|
222
|
+
streamError = err;
|
|
223
|
+
if (resolveChunk) {
|
|
224
|
+
resolveChunk();
|
|
225
|
+
resolveChunk = null;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
199
228
|
});
|
|
200
229
|
req.on("error", (err) => {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
streamError = err;
|
|
206
|
-
}
|
|
230
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
231
|
+
if (err instanceof errors_1.TimeoutError)
|
|
232
|
+
throw err;
|
|
233
|
+
streamError = err;
|
|
207
234
|
if (resolveChunk) {
|
|
208
235
|
resolveChunk();
|
|
209
236
|
resolveChunk = null;
|
|
@@ -211,10 +238,9 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
211
238
|
});
|
|
212
239
|
// Set timeout if provided and positive
|
|
213
240
|
if (this.timeout && this.timeout > 0) {
|
|
214
|
-
|
|
215
|
-
req.
|
|
216
|
-
|
|
217
|
-
});
|
|
241
|
+
hardTimeout = setTimeout(() => {
|
|
242
|
+
req.destroy(new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`));
|
|
243
|
+
}, this.timeout);
|
|
218
244
|
}
|
|
219
245
|
if (requestBody instanceof form_data_1.default) {
|
|
220
246
|
requestBody.pipe(req);
|
|
@@ -315,9 +341,9 @@ class NodeClient {
|
|
|
315
341
|
json = JSON.parse(data);
|
|
316
342
|
}
|
|
317
343
|
catch (_e) {
|
|
318
|
-
reject(new SyntaxError("Invalid JSON response"));
|
|
344
|
+
return reject(new SyntaxError("Invalid JSON response"));
|
|
319
345
|
}
|
|
320
|
-
resolve({
|
|
346
|
+
return resolve({
|
|
321
347
|
statusCode: res.statusCode,
|
|
322
348
|
body: json,
|
|
323
349
|
headers: res.headers
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { S3UploadFields } from "../../documents";
|
|
2
1
|
import type { MultiPartFile } from "../lara/client";
|
|
3
|
-
import { S3Client } from "./client";
|
|
2
|
+
import { S3Client, type S3UploadFields } from "./client";
|
|
4
3
|
import type { LaraStream } from "./laraStream.browser";
|
|
5
4
|
/** @internal */
|
|
6
5
|
export declare class BrowserS3Client extends S3Client {
|
package/lib/net/s3/client.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type { S3UploadFields } from "../../documents";
|
|
2
1
|
import type { MultiPartFile } from "../lara/client";
|
|
2
|
+
export type S3UploadFields = {
|
|
3
|
+
acl: string;
|
|
4
|
+
bucket: string;
|
|
5
|
+
key: string;
|
|
6
|
+
};
|
|
3
7
|
/** @internal */
|
|
4
8
|
export declare abstract class S3Client {
|
|
5
9
|
upload(url: string, fields: S3UploadFields, file: MultiPartFile, length?: number): Promise<void>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Readable } from "node:stream";
|
|
2
|
-
import type { S3UploadFields } from "../../documents";
|
|
3
2
|
import type { MultiPartFile } from "../lara/client";
|
|
4
|
-
import { S3Client } from "./client";
|
|
3
|
+
import { S3Client, type S3UploadFields } from "./client";
|
|
5
4
|
import type { LaraStream } from "./laraStream";
|
|
6
5
|
/** @internal */
|
|
7
6
|
export declare class NodeS3Client extends S3Client {
|
package/lib/translator.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { AudioTranslator } from "./audioTranslator";
|
|
1
2
|
import type { AccessKey, AuthToken } from "./credentials";
|
|
2
3
|
import { Documents } from "./documents";
|
|
3
4
|
import { Glossaries } from "./glossaries";
|
|
5
|
+
import { ImageTranslator } from "./imageTranslator";
|
|
4
6
|
import { Memories } from "./memories";
|
|
5
7
|
import { type LaraClient } from "./net/lara";
|
|
6
8
|
export type TranslatorOptions = {
|
|
7
9
|
serverUrl?: string;
|
|
8
10
|
connectionTimeoutMs?: number;
|
|
11
|
+
keepAlive?: boolean;
|
|
9
12
|
};
|
|
10
13
|
export interface NGMemoryMatch {
|
|
11
14
|
memory: string;
|
|
@@ -55,12 +58,18 @@ export type TranslationStyle = "faithful" | "fluid" | "creative";
|
|
|
55
58
|
export interface DetectResult {
|
|
56
59
|
language: string;
|
|
57
60
|
contentType: string;
|
|
61
|
+
predictions: {
|
|
62
|
+
language: string;
|
|
63
|
+
confidence: number;
|
|
64
|
+
}[];
|
|
58
65
|
}
|
|
59
66
|
export declare class Translator {
|
|
60
67
|
protected readonly client: LaraClient;
|
|
61
68
|
readonly memories: Memories;
|
|
62
69
|
readonly documents: Documents;
|
|
63
70
|
readonly glossaries: Glossaries;
|
|
71
|
+
readonly audio: AudioTranslator;
|
|
72
|
+
readonly images: ImageTranslator;
|
|
64
73
|
constructor(auth: AccessKey | AuthToken, options?: TranslatorOptions);
|
|
65
74
|
get version(): string;
|
|
66
75
|
getLanguages(): Promise<string[]>;
|
package/lib/translator.js
CHANGED
|
@@ -34,18 +34,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Translator = void 0;
|
|
37
|
+
const audioTranslator_1 = require("./audioTranslator");
|
|
37
38
|
const documents_1 = require("./documents");
|
|
38
39
|
const glossaries_1 = require("./glossaries");
|
|
40
|
+
const imageTranslator_1 = require("./imageTranslator");
|
|
39
41
|
const memories_1 = require("./memories");
|
|
40
42
|
const lara_1 = __importStar(require("./net/lara"));
|
|
41
43
|
const defaultBaseUrl_1 = require("./utils/defaultBaseUrl");
|
|
42
44
|
const sdk_version_1 = require("./utils/sdk-version");
|
|
43
45
|
class Translator {
|
|
44
46
|
constructor(auth, options) {
|
|
45
|
-
this.client = (0, lara_1.default)(auth, options === null || options === void 0 ? void 0 : options.serverUrl, options === null || options === void 0 ? void 0 : options.connectionTimeoutMs);
|
|
47
|
+
this.client = (0, lara_1.default)(auth, options === null || options === void 0 ? void 0 : options.serverUrl, options === null || options === void 0 ? void 0 : options.keepAlive, options === null || options === void 0 ? void 0 : options.connectionTimeoutMs);
|
|
46
48
|
this.memories = new memories_1.Memories(this.client);
|
|
47
49
|
this.documents = new documents_1.Documents(this.client);
|
|
48
50
|
this.glossaries = new glossaries_1.Glossaries(this.client);
|
|
51
|
+
this.audio = new audioTranslator_1.AudioTranslator(this.client);
|
|
52
|
+
this.images = new imageTranslator_1.ImageTranslator(this.client);
|
|
49
53
|
}
|
|
50
54
|
get version() {
|
|
51
55
|
return sdk_version_1.version;
|
|
@@ -63,7 +67,7 @@ class Translator {
|
|
|
63
67
|
if (options === null || options === void 0 ? void 0 : options.noTrace) {
|
|
64
68
|
headers["X-No-Trace"] = "true";
|
|
65
69
|
}
|
|
66
|
-
const response = this.client.postAndGetStream("/
|
|
70
|
+
const response = this.client.postAndGetStream("/translate", {
|
|
67
71
|
q: text,
|
|
68
72
|
source,
|
|
69
73
|
target,
|
|
@@ -83,7 +87,7 @@ class Translator {
|
|
|
83
87
|
}, undefined, headers);
|
|
84
88
|
let lastResult;
|
|
85
89
|
for await (const partial of response) {
|
|
86
|
-
if (callback)
|
|
90
|
+
if ((options === null || options === void 0 ? void 0 : options.reasoning) && callback)
|
|
87
91
|
callback(partial);
|
|
88
92
|
lastResult = partial;
|
|
89
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.8.0
|
|
1
|
+
export declare const version = "1.8.0";
|
package/lib/utils/sdk-version.js
CHANGED
package/lib_browser/lara.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Lara=e():t.Lara=e()}(this,()=>(()=>{"use strict";var t={50:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.Documents=e.DocumentStatus=void 0;const n=r(725),s=o(r(821)),i=o(r(841));var a;!function(t){t.INITIALIZED="initialized",t.ANALYZING="analyzing",t.PAUSED="paused",t.READY="ready",t.TRANSLATING="translating",t.TRANSLATED="translated",t.ERROR="error"}(a||(e.DocumentStatus=a={})),e.Documents=class{constructor(t){this.client=t,this.s3Client=(0,s.default)()}async upload(t,e,r,o,n){const{url:s,fields:a}=await this.client.get("/v2/documents/upload-url",{filename:e});await this.s3Client.upload(s,a,t,null==n?void 0:n.contentLength);const c=(null==n?void 0:n.noTrace)?{"X-No-Trace":"true"}:{};return this.client.post("/v2/documents",{source:r,target:o,s3key:a.key,adapt_to:null==n?void 0:n.adaptTo,glossaries:null==n?void 0:n.glossaries,style:null==n?void 0:n.style,password:null==n?void 0:n.password,extraction_params:(null==n?void 0:n.extractionParams)?(0,i.default)(n.extractionParams):void 0},void 0,c)}async status(t){return await this.client.get(`/v2/documents/${t}`)}async download(t,e){const{url:r}=await this.client.get(`/v2/documents/${t}/download-url`,{output_format:null==e?void 0:e.outputFormat});return await this.s3Client.download(r)}async downloadStream(t,e){const{url:r}=await this.client.get(`/v2/documents/${t}/download-url`,{output_format:null==e?void 0:e.outputFormat});return await this.s3Client.downloadStream(r)}async translate(t,e,r,o,s){const i={adaptTo:null==s?void 0:s.adaptTo,glossaries:null==s?void 0:s.glossaries,noTrace:null==s?void 0:s.noTrace,style:null==s?void 0:s.style,password:null==s?void 0:s.password,extractionParams:null==s?void 0:s.extractionParams,contentLength:null==s?void 0:s.contentLength},{id:c}=await this.upload(t,e,r,o,i),u=(null==s?void 0:s.outputFormat)?{outputFormat:s.outputFormat}:void 0,l=Date.now();for(;Date.now()-l<9e5;){await new Promise(t=>setTimeout(t,2e3));const{status:t,errorReason:e}=await this.status(c);if(t===a.TRANSLATED)return await this.download(c,u);if(t===a.ERROR)throw new n.LaraApiError(500,"DocumentError",e)}throw new n.TimeoutError}async translateStream(t,e,r,o,s){const i={adaptTo:null==s?void 0:s.adaptTo,glossaries:null==s?void 0:s.glossaries,noTrace:null==s?void 0:s.noTrace,style:null==s?void 0:s.style,password:null==s?void 0:s.password,extractionParams:null==s?void 0:s.extractionParams,contentLength:null==s?void 0:s.contentLength},{id:c}=await this.upload(t,e,r,o,i),u=(null==s?void 0:s.outputFormat)?{outputFormat:s.outputFormat}:void 0,l=Date.now();for(;Date.now()-l<9e5;){await new Promise(t=>setTimeout(t,2e3));const{status:t,errorReason:e}=await this.status(c);if(t===a.TRANSLATED)return await this.downloadStream(c,u);if(t===a.ERROR)throw new n.LaraApiError(500,"DocumentError",e)}throw new n.TimeoutError}}},221:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_BASE_URL=void 0,e.DEFAULT_BASE_URL="https://api.laratranslate.com"},311:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.version=void 0,e.version="1.8.0-beta.2"},326:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){return void 0===n&&(n=new o.BrowserCrypto),n};const o=r(780);let n},343:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserS3Client=void 0;const o=r(364);class n extends o.S3Client{async _upload(t,e,r){const o=new FormData;for(const[t,r]of Object.entries(e))o.append(t,r);o.append("file",r),await fetch(t,{method:"POST",body:o})}async download(t){return(await fetch(t)).blob()}async downloadStream(t){const e=await fetch(t);if(!e.body)throw new Error("Response body is null");return e.body}wrapMultiPartFile(t){if(t instanceof File)return t;throw new TypeError(`Invalid file input in the browser. Expected an instance of File but received ${typeof t}.`)}}e.BrowserS3Client=n},364:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.S3Client=void 0,e.S3Client=class{async upload(t,e,r,o){return this._upload(t,e,this.wrapMultiPartFile(r),o)}}},412:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.LaraClient=void 0;const n=r(414),s=o(r(326)),i=r(725),a=r(741),c=r(311);e.LaraClient=class{constructor(t){if(this.crypto=(0,s.default)(),this.extraHeaders={},t instanceof n.AccessKey)this.accessKey=t;else{if(!(t instanceof n.AuthToken))throw new Error("Invalid authentication method provided");this.authToken=t}}setExtraHeader(t,e){this.extraHeaders[t]=e}get(t,e,r){return this.request("GET",this.buildPathWithQuery(t,e),void 0,void 0,r)}delete(t,e,r,o){return this.request("DELETE",this.buildPathWithQuery(t,e),r,void 0,o)}post(t,e,r,o){return this.request("POST",t,e,r,o)}async*postAndGetStream(t,e,r,o){for await(const n of this.requestStream("POST",t,e,r,o))yield n}put(t,e,r,o){return this.request("PUT",t,e,r,o)}async request(t,e,r,o,n){await this.ensureAuthenticated();const s=e.startsWith("/")?e:`/${e}`,i=await this.buildRequestHeaders(r,o,n),c=this.buildRequestBody(r,o);i.Authorization=`Bearer ${this.token}`;const u=await this.send(t,s,i,c);if(this.isSuccessResponse(u))return(0,a.parseContent)(u.body);if(401===u.statusCode)return this.token=void 0,await this.refreshTokens(),this.request(t,e,r,o,n);throw this.createApiError(u)}async*requestStream(t,e,r,o,n){await this.ensureAuthenticated();const s=e.startsWith("/")?e:`/${e}`,i=await this.buildRequestHeaders(r,o,n),c=this.buildRequestBody(r,o);i.Authorization=`Bearer ${this.token}`;for await(const u of this.sendAndGetStream(t,s,i,c)){if(401===u.statusCode)return this.token=void 0,await this.refreshTokens(),void(yield*this.requestStream(t,e,r,o,n));if(!this.isSuccessResponse(u))throw this.createApiError(u);yield(0,a.parseContent)(u.body)}}async ensureAuthenticated(){if(!this.token){if(this.authenticationPromise)return this.authenticationPromise;this.authenticationPromise=this.performAuthentication();try{await this.authenticationPromise}catch(t){if(this.authenticationPromise=void 0,t instanceof i.LaraApiError&&(401===t.statusCode||403===t.statusCode))throw t;try{this.authenticationPromise=this.performAuthentication(),await this.authenticationPromise}catch(t){throw this.authenticationPromise=void 0,t instanceof i.LaraApiError?t:new i.LaraApiError(500,"AuthenticationError",t.message)}}}}async performAuthentication(){if(this.refreshToken)return this.refreshTokens();if(this.authToken)return this.token=this.authToken.token,this.refreshToken=this.authToken.refreshToken,void(this.authToken=void 0);if(this.accessKey)return this.authenticateWithAccessKey();throw new Error("No authentication method provided")}async refreshTokens(){const t={Authorization:`Bearer ${this.refreshToken}`,"X-Lara-Date":(new Date).toUTCString()},e=await this.send("POST","/v2/auth/refresh",t);this.handleAuthResponse(e)}async authenticateWithAccessKey(){if(!this.accessKey)throw new Error("No access key provided");const t={id:this.accessKey.id},e=await this.crypto.digestBase64(JSON.stringify(t)),r={"Content-Type":"application/json","X-Lara-Date":(new Date).toUTCString(),"Content-MD5":e};r.Authorization=`Lara:${await this.sign("POST","/v2/auth",r)}`;const o=await this.send("POST","/v2/auth",r,t);this.handleAuthResponse(o)}buildPathWithQuery(t,e){const r=this.filterNullish(e);return r?`${t}?${new URLSearchParams(r).toString()}`:t}async buildRequestHeaders(t,e,r){const o={"X-Lara-Date":(new Date).toUTCString(),"X-Lara-SDK-Name":"lara-node","X-Lara-SDK-Version":c.version,...this.extraHeaders,...r},n=this.filterNullish(t);if(e)o["Content-Type"]="multipart/form-data";else if(n){o["Content-Type"]="application/json";const t=JSON.stringify(n,void 0,0);o["Content-Length"]=(new TextEncoder).encode(t).length.toString()}return o}buildRequestBody(t,e){const r=this.filterNullish(t);if(e){const t={};for(const[r,o]of Object.entries(e))t[r]=this.wrapMultiPartFile(o);return{...t,...r}}return r}filterNullish(t){if(!t)return;const e=Object.fromEntries(Object.entries(t).filter(([t,e])=>null!=e));return Object.keys(e).length>0?e:void 0}isSuccessResponse(t){return t.statusCode>=200&&t.statusCode<300}handleAuthResponse(t){if(this.isSuccessResponse(t))return this.token=t.body.token,void(this.refreshToken=t.headers["x-lara-refresh-token"]);throw this.createApiError(t)}createApiError(t){var e;const r=(null===(e=t.body)||void 0===e?void 0:e.error)||{};return new i.LaraApiError(t.statusCode,r.type||"UnknownError",r.message||"An unknown error occurred")}async sign(t,e,r){if(!this.accessKey)throw new Error("Access key not provided for signing");const o=r["X-Lara-Date"].trim(),n=(r["Content-MD5"]||"").trim(),s=(r["Content-Type"]||"").trim(),i=`${(r["X-HTTP-Method-Override"]||t).trim().toUpperCase()}\n${e}\n${n}\n${s}\n${o}`;return this.crypto.hmac(this.accessKey.secret,i)}}},414:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AuthToken=e.Credentials=e.AccessKey=void 0;class r{constructor(t,e){this.id=t,this.secret=e}}e.AccessKey=r,e.Credentials=class extends r{get accessKeyId(){return this.id}get accessKeySecret(){return this.secret}},e.AuthToken=class{constructor(t,e){this.token=t,this.refreshToken=e}}},514:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Glossaries=void 0;const o=r(725);e.Glossaries=class{constructor(t){this.client=t,this.pollingInterval=2e3}async list(){return await this.client.get("/v2/glossaries")}async create(t){return await this.client.post("/v2/glossaries",{name:t})}async get(t){try{return await this.client.get(`/v2/glossaries/${t}`)}catch(t){if(t instanceof o.LaraApiError&&404===t.statusCode)return null;throw t}}async delete(t){return await this.client.delete(`/v2/glossaries/${t}`)}async update(t,e){return await this.client.put(`/v2/glossaries/${t}`,{name:e})}async importCsv(t,e,r=!1){return await this.client.post(`/v2/glossaries/${t}/import`,{compression:r?"gzip":void 0},{csv:e})}async getImportStatus(t){return await this.client.get(`/v2/glossaries/imports/${t}`)}async waitForImport(t,e,r){const n=Date.now();for(;t.progress<1;){if(r&&Date.now()-n>r)throw new o.TimeoutError;await new Promise(t=>setTimeout(t,this.pollingInterval)),t=await this.getImportStatus(t.id),e&&e(t)}return t}async counts(t){return await this.client.get(`/v2/glossaries/${t}/counts`)}async export(t,e,r){return await this.client.get(`/v2/glossaries/${t}/export`,{content_type:e,source:r})}}},629:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Memories=void 0;const o=r(725);e.Memories=class{constructor(t){this.client=t,this.pollingInterval=2e3}async list(){return await this.client.get("/v2/memories")}async create(t,e){return await this.client.post("/v2/memories",{name:t,external_id:e})}async get(t){try{return await this.client.get(`/v2/memories/${t}`)}catch(t){if(t instanceof o.LaraApiError&&404===t.statusCode)return null;throw t}}async delete(t){return await this.client.delete(`/v2/memories/${t}`)}async update(t,e){return await this.client.put(`/v2/memories/${t}`,{name:e})}async connect(t){const e=await this.client.post("/v2/memories/connect",{ids:Array.isArray(t)?t:[t]});return Array.isArray(t)?e:e[0]}async importTmx(t,e,r=!1){return await this.client.post(`/v2/memories/${t}/import`,{compression:r?"gzip":void 0},{tmx:e})}async addTranslation(t,e,r,o,n,s,i,a,c){const u={source:e,target:r,sentence:o,translation:n,tuid:s,sentence_before:i,sentence_after:a};return Array.isArray(t)?(u.ids=t,await this.client.put("/v2/memories/content",u,void 0,c)):await this.client.put(`/v2/memories/${t}/content`,u,void 0,c)}async deleteTranslation(t,e,r,o,n,s,i,a){const c={source:e,target:r,sentence:o,translation:n,tuid:s,sentence_before:i,sentence_after:a};return Array.isArray(t)?(c.ids=t,await this.client.delete("/v2/memories/content",void 0,c)):await this.client.delete(`/v2/memories/${t}/content`,void 0,c)}async getImportStatus(t){return await this.client.get(`/v2/memories/imports/${t}`)}async waitForImport(t,e,r){const n=Date.now();for(;t.progress<1;){if(r&&Date.now()-n>r)throw new o.TimeoutError;await new Promise(t=>setTimeout(t,this.pollingInterval)),t=await this.getImportStatus(t.id),e&&e(t)}return t}}},631:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserClient=e.BrowserLaraClient=void 0;const o=r(725),n=r(412);class s extends n.LaraClient{constructor(t,e,r){super(e);let o=`${t.secure?"https":"http"}://${t.hostname}`;var n,s;n=t.port,s=t.secure,80===n&&!s||443===n&&s||(o+=`:${t.port}`),this.baseUrl=o,this.timeout=r}async send(t,e,r,n){var s;let i,a,c;if(n)if("multipart/form-data"===r["Content-Type"]){delete r["Content-Type"];const t=new FormData;for(const[e,r]of Object.entries(n))if(r)if(Array.isArray(r))for(const o of r)t.append(e,o);else t.append(e,r);i=t}else i=JSON.stringify(n,void 0,0);this.timeout&&this.timeout>0&&(console.log("Setting up timeout:",this.timeout),a=new AbortController,c=setTimeout(()=>{a.abort(),console.log("abort called due to timeout")},this.timeout));try{const o=await fetch(this.baseUrl+e,{headers:r,method:t,body:i,signal:null==a?void 0:a.signal});return c&&(console.log("Clear timeout"),clearTimeout(c)),(null===(s=o.headers.get("Content-Type"))||void 0===s?void 0:s.includes("text/csv"))?{statusCode:o.status,body:{content:await o.text()},headers:Object.fromEntries(o.headers)}:{statusCode:o.status,body:await o.json(),headers:Object.fromEntries(o.headers)}}catch(t){if(c&&clearTimeout(c),t instanceof Error&&"AbortError"===t.name)throw new o.TimeoutError(`Request timed out after ${this.timeout}ms`);throw t}}async*sendAndGetStream(t,e,r,n){let s,i,a,c;if(n)if("multipart/form-data"===r["Content-Type"]){delete r["Content-Type"];const t=new FormData;for(const[e,r]of Object.entries(n))if(r)if(Array.isArray(r))for(const o of r)t.append(e,o);else t.append(e,r);s=t}else s=JSON.stringify(n,void 0,0);this.timeout&&this.timeout>0&&(i=new AbortController,a=setTimeout(()=>i.abort(),this.timeout));try{c=await fetch(this.baseUrl+e,{headers:r,method:t,body:s,signal:null==i?void 0:i.signal})}catch(t){if(a&&clearTimeout(a),t instanceof Error&&"AbortError"===t.name)throw new o.TimeoutError(`Request timed out after ${this.timeout}ms`);throw t}if(a&&clearTimeout(a),!c.body)throw new Error("Response body is not available for streaming");const u=c.body.getReader(),l=new TextDecoder;let d="";try{for(;;){const{done:t,value:e}=await u.read();if(t){if(d.trim())try{const t=JSON.parse(d);console.log(t),yield{statusCode:t.status||c.status,body:t.data||t,headers:Object.fromEntries(c.headers)}}catch(t){}break}d+=l.decode(e,{stream:!0});const r=d.split("\n");d=r.pop()||"";for(const t of r)if(t.trim())try{const e=JSON.parse(t);yield{statusCode:e.status||c.status,body:e.data||e,headers:Object.fromEntries(c.headers)}}catch(t){}}}finally{u.releaseLock()}}wrapMultiPartFile(t){if(t instanceof File)return t;throw new TypeError(`Invalid file input in the browser. Expected an instance of File but received ${typeof t}.`)}}e.BrowserLaraClient=s;class i{static async get(t,e){return i.send("GET",t,e)}static async send(t,e,r,o){var n;let s;if(o)if(r&&"multipart/form-data"===r["Content-Type"]){delete r["Content-Type"];const t=new FormData;for(const[e,r]of Object.entries(o))if(r)if(Array.isArray(r))for(const o of r)t.append(e,o);else t.append(e,r);s=t}else s=JSON.stringify(o,void 0,0);const i=await fetch(e,{headers:r,method:t,body:s});return{statusCode:i.status,headers:Object.fromEntries(i.headers),body:(null===(n=i.headers.get("Content-Type"))||void 0===n?void 0:n.includes("application/json"))?await i.json():await i.text()}}}e.BrowserClient=i},660:function(t,e,r){var o,n=this&&this.__createBinding||(Object.create?function(t,e,r,o){void 0===o&&(o=r);var n=Object.getOwnPropertyDescriptor(e,r);n&&!("get"in n?!e.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,o,n)}:function(t,e,r,o){void 0===o&&(o=r),t[o]=e[r]}),s=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),i=this&&this.__importStar||(o=function(t){return o=Object.getOwnPropertyNames||function(t){var e=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[e.length]=r);return e},o(t)},function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r=o(t),i=0;i<r.length;i++)"default"!==r[i]&&n(e,t,r[i]);return s(e,t),e});Object.defineProperty(e,"__esModule",{value:!0}),e.Translator=void 0;const a=r(50),c=r(514),u=r(629),l=i(r(837)),d=r(221),h=r(311);e.Translator=class{constructor(t,e){this.client=(0,l.default)(t,null==e?void 0:e.serverUrl,null==e?void 0:e.connectionTimeoutMs),this.memories=new u.Memories(this.client),this.documents=new a.Documents(this.client),this.glossaries=new c.Glossaries(this.client)}get version(){return h.version}async getLanguages(){return await this.client.get("/v2/languages")}async translate(t,e,r,o,n){const s={};if(null==o?void 0:o.headers)for(const[t,e]of Object.entries(o.headers))s[t]=e;(null==o?void 0:o.noTrace)&&(s["X-No-Trace"]="true");const i=this.client.postAndGetStream("/v2/translate",{q:t,source:e,target:r,source_hint:null==o?void 0:o.sourceHint,content_type:null==o?void 0:o.contentType,multiline:!1!==(null==o?void 0:o.multiline),adapt_to:null==o?void 0:o.adaptTo,glossaries:null==o?void 0:o.glossaries,instructions:null==o?void 0:o.instructions,timeout:null==o?void 0:o.timeoutInMillis,priority:null==o?void 0:o.priority,use_cache:null==o?void 0:o.useCache,cache_ttl:null==o?void 0:o.cacheTTLSeconds,verbose:null==o?void 0:o.verbose,style:null==o?void 0:o.style,reasoning:null==o?void 0:o.reasoning},void 0,s);let a;for await(const t of i)n&&n(t),a=t;if(!a)throw new Error("No translation result received.");return a}async detect(t,e,r){return await this.client.post("/v2/detect",{q:t,hint:e,passlist:r})}static async getLoginUrl(t){t||(t=d.DEFAULT_BASE_URL);const{body:e}=await l.HttpClient.get(`${t.replace(/\/+$/,"")}/v2/auth/login-page`);return e}}},725:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LaraApiError=e.TimeoutError=e.LaraError=void 0;class r extends Error{}e.LaraError=r,e.TimeoutError=class extends r{},e.LaraApiError=class extends r{constructor(t,e,r,o){super(r),this.statusCode=t,this.type=e,this.message=r,this.idTransaction=o}}},741:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.parseContent=function t(e){if(null==e)return e;if(Array.isArray(e))return e.map(t);if("string"==typeof e)return e.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.[0-9]{3}Z$/)?new Date(e):e;if("object"==typeof e){const r={};for(const[o,n]of Object.entries(e))r[o.replace(/_([a-z])/g,(t,e)=>e.toUpperCase())]=t(n);return r}return e}},780:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserCrypto=void 0,e.BrowserCrypto=class{constructor(){this.subtle=window.crypto.subtle}async digestBase64(t){const e=new TextEncoder,r=(await this.subtle.digest("sha-256",e.encode(t))).slice(0,16);return btoa(String.fromCharCode(...new Uint8Array(r)))}async hmac(t,e){const r=new TextEncoder;r.encode(e);const o=await this.subtle.importKey("raw",r.encode(t),{name:"hmac",hash:{name:"sha-256"}},!1,["sign"]),n=await this.subtle.sign("hmac",o,r.encode(e));return btoa(String.fromCharCode(...new Uint8Array(n)))}}},821:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){return new o.BrowserS3Client};const o=r(343)},837:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.HttpClient=e.LaraClient=void 0,e.default=function(t,e,r){const s=new URL(e||o.DEFAULT_BASE_URL);if("https:"!==s.protocol&&"http:"!==s.protocol)throw new TypeError(`Invalid URL (protocol): ${s.protocol}`);const i={secure:"https:"===s.protocol,hostname:s.hostname,port:s.port?parseInt(s.port,10):"https:"===s.protocol?443:80};return new n.BrowserLaraClient(i,t,r)};const o=r(221),n=r(631);var s=r(412);Object.defineProperty(e,"LaraClient",{enumerable:!0,get:function(){return s.LaraClient}});var i=r(631);Object.defineProperty(e,"HttpClient",{enumerable:!0,get:function(){return i.BrowserClient}})},841:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0});const r=t=>{if("string"==typeof t)return t;if(Array.isArray(t))return t.map(r);if("object"==typeof t&&null!==t){const e={};for(const[o,n]of Object.entries(t))e[o.replace(/([A-Z])/g,"_$1").toLowerCase()]=r(n);return e}return t};e.default=r}},e={};function r(o){var n=e[o];if(void 0!==n)return n.exports;var s=e[o]={exports:{}};return t[o].call(s.exports,s,s.exports,r),s.exports}var o={};return(()=>{var t=o;Object.defineProperty(t,"__esModule",{value:!0}),t.version=t.Translator=t.Memories=t.Glossaries=t.TimeoutError=t.LaraError=t.LaraApiError=t.Documents=t.DocumentStatus=t.Credentials=t.AuthToken=t.AccessKey=void 0;var e=r(414);Object.defineProperty(t,"AccessKey",{enumerable:!0,get:function(){return e.AccessKey}}),Object.defineProperty(t,"AuthToken",{enumerable:!0,get:function(){return e.AuthToken}}),Object.defineProperty(t,"Credentials",{enumerable:!0,get:function(){return e.Credentials}});var n=r(50);Object.defineProperty(t,"DocumentStatus",{enumerable:!0,get:function(){return n.DocumentStatus}}),Object.defineProperty(t,"Documents",{enumerable:!0,get:function(){return n.Documents}});var s=r(725);Object.defineProperty(t,"LaraApiError",{enumerable:!0,get:function(){return s.LaraApiError}}),Object.defineProperty(t,"LaraError",{enumerable:!0,get:function(){return s.LaraError}}),Object.defineProperty(t,"TimeoutError",{enumerable:!0,get:function(){return s.TimeoutError}});var i=r(514);Object.defineProperty(t,"Glossaries",{enumerable:!0,get:function(){return i.Glossaries}});var a=r(629);Object.defineProperty(t,"Memories",{enumerable:!0,get:function(){return a.Memories}});var c=r(660);Object.defineProperty(t,"Translator",{enumerable:!0,get:function(){return c.Translator}});var u=r(311);Object.defineProperty(t,"version",{enumerable:!0,get:function(){return u.version}})})(),o})());
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Lara=e():t.Lara=e()}(this,()=>(()=>{"use strict";var t={50:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.Documents=e.DocumentStatus=void 0;const n=r(725),s=o(r(821)),i=o(r(841));var a;!function(t){t.INITIALIZED="initialized",t.ANALYZING="analyzing",t.PAUSED="paused",t.READY="ready",t.TRANSLATING="translating",t.TRANSLATED="translated",t.ERROR="error"}(a||(e.DocumentStatus=a={})),e.Documents=class{constructor(t){this.client=t,this.s3Client=(0,s.default)()}async upload(t,e,r,o,n){const{url:s,fields:a}=await this.client.get("/v2/documents/upload-url",{filename:e});await this.s3Client.upload(s,a,t,null==n?void 0:n.contentLength);const u=(null==n?void 0:n.noTrace)?{"X-No-Trace":"true"}:{};return this.client.post("/v2/documents",{source:r,target:o,s3key:a.key,adapt_to:null==n?void 0:n.adaptTo,glossaries:null==n?void 0:n.glossaries,style:null==n?void 0:n.style,password:null==n?void 0:n.password,extraction_params:(null==n?void 0:n.extractionParams)?(0,i.default)(n.extractionParams):void 0},void 0,u)}async status(t){return await this.client.get(`/v2/documents/${t}`)}async download(t,e){const{url:r}=await this.client.get(`/v2/documents/${t}/download-url`,{output_format:null==e?void 0:e.outputFormat});return await this.s3Client.download(r)}async downloadStream(t,e){const{url:r}=await this.client.get(`/v2/documents/${t}/download-url`,{output_format:null==e?void 0:e.outputFormat});return await this.s3Client.downloadStream(r)}async translate(t,e,r,o,s){const i={adaptTo:null==s?void 0:s.adaptTo,glossaries:null==s?void 0:s.glossaries,noTrace:null==s?void 0:s.noTrace,style:null==s?void 0:s.style,password:null==s?void 0:s.password,extractionParams:null==s?void 0:s.extractionParams,contentLength:null==s?void 0:s.contentLength},{id:u}=await this.upload(t,e,r,o,i),l=(null==s?void 0:s.outputFormat)?{outputFormat:s.outputFormat}:void 0,c=Date.now();for(;Date.now()-c<9e5;){await new Promise(t=>setTimeout(t,2e3));const{status:t,errorReason:e}=await this.status(u);if(t===a.TRANSLATED)return await this.download(u,l);if(t===a.ERROR)throw new n.LaraApiError(500,"DocumentError",e)}throw new n.TimeoutError}async translateStream(t,e,r,o,s){const i={adaptTo:null==s?void 0:s.adaptTo,glossaries:null==s?void 0:s.glossaries,noTrace:null==s?void 0:s.noTrace,style:null==s?void 0:s.style,password:null==s?void 0:s.password,extractionParams:null==s?void 0:s.extractionParams,contentLength:null==s?void 0:s.contentLength},{id:u}=await this.upload(t,e,r,o,i),l=(null==s?void 0:s.outputFormat)?{outputFormat:s.outputFormat}:void 0,c=Date.now();for(;Date.now()-c<9e5;){await new Promise(t=>setTimeout(t,2e3));const{status:t,errorReason:e}=await this.status(u);if(t===a.TRANSLATED)return await this.downloadStream(u,l);if(t===a.ERROR)throw new n.LaraApiError(500,"DocumentError",e)}throw new n.TimeoutError}}},221:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_BASE_URL=void 0,e.DEFAULT_BASE_URL="https://api.laratranslate.com"},311:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.version=void 0,e.version="1.8.0"},326:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){return void 0===n&&(n=new o.BrowserCrypto),n};const o=r(780);let n},328:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.AudioTranslator=e.AudioStatus=void 0;const n=r(725),s=o(r(821));var i;!function(t){t.INITIALIZED="initialized",t.ANALYZING="analyzing",t.PAUSED="paused",t.READY="ready",t.TRANSLATING="translating",t.TRANSLATED="translated",t.ERROR="error"}(i||(e.AudioStatus=i={})),e.AudioTranslator=class{constructor(t){this.client=t,this.s3Client=(0,s.default)()}async upload(t,e,r,o,n){const{url:s,fields:i}=await this.client.get("/v2/audio/upload-url",{filename:e});await this.s3Client.upload(s,i,t,null==n?void 0:n.contentLength);const a=(null==n?void 0:n.noTrace)?{"X-No-Trace":"true"}:{};return this.client.post("/v2/audio/translate",{source:r,target:o,s3key:i.key,adapt_to:null==n?void 0:n.adaptTo,glossaries:null==n?void 0:n.glossaries,style:null==n?void 0:n.style},void 0,a)}async status(t){return await this.client.get(`/v2/audio/${t}`)}async download(t){const{url:e}=await this.client.get(`/v2/audio/${t}/download-url`);return await this.s3Client.downloadStream(e)}async translate(t,e,r,o,s){const{id:a}=await this.upload(t,e,r,o,s),u=Date.now();for(;Date.now()-u<9e5;){await new Promise(t=>setTimeout(t,2e3));const{status:t,errorReason:e}=await this.status(a);if(t===i.TRANSLATED)return await this.download(a);if(t===i.ERROR)throw new n.LaraApiError(500,"AudioError",e)}throw new n.TimeoutError}}},343:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserS3Client=void 0;const o=r(364);class n extends o.S3Client{async _upload(t,e,r){const o=new FormData;for(const[t,r]of Object.entries(e))o.append(t,r);o.append("file",r),await fetch(t,{method:"POST",body:o})}async download(t){return(await fetch(t)).blob()}async downloadStream(t){const e=await fetch(t);if(!e.body)throw new Error("Response body is null");return e.body}wrapMultiPartFile(t){if(t instanceof File)return t;throw new TypeError(`Invalid file input in the browser. Expected an instance of File but received ${typeof t}.`)}}e.BrowserS3Client=n},364:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.S3Client=void 0,e.S3Client=class{async upload(t,e,r,o){return this._upload(t,e,this.wrapMultiPartFile(r),o)}}},412:function(t,e,r){var o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.LaraClient=void 0;const n=r(414),s=o(r(326)),i=r(725),a=r(741),u=r(311);e.LaraClient=class{constructor(t){if(this.crypto=(0,s.default)(),this.extraHeaders={},t instanceof n.AccessKey)this.accessKey=t;else{if(!(t instanceof n.AuthToken))throw new Error("Invalid authentication method provided");this.authToken=t}}setExtraHeader(t,e){this.extraHeaders[t]=e}get(t,e,r){return this.request("GET",this.buildPathWithQuery(t,e),void 0,void 0,r)}delete(t,e,r,o){return this.request("DELETE",this.buildPathWithQuery(t,e),r,void 0,o)}post(t,e,r,o,n){return this.request("POST",t,e,r,o,void 0,n)}async*postAndGetStream(t,e,r,o){for await(const n of this.requestStream("POST",t,e,r,o))yield n}put(t,e,r,o){return this.request("PUT",t,e,r,o)}async request(t,e,r,o,n,s=0,i){await this.ensureAuthenticated();const u=e.startsWith("/")?e:`/${e}`,l=await this.buildRequestHeaders(r,o,n),c=this.buildRequestBody(r,o);l.Authorization=`Bearer ${this.token}`;const d=await this.send(t,u,l,c,i);if(this.isSuccessResponse(d))return i?d.body:(0,a.parseContent)(d.body);if(401===d.statusCode&&s<1)return this.token=void 0,await this.refreshTokens(),this.request(t,e,r,o,n,s+1,i);throw this.createApiError(d)}async*requestStream(t,e,r,o,n,s=0){await this.ensureAuthenticated();const i=e.startsWith("/")?e:`/${e}`,u=await this.buildRequestHeaders(r,o,n),l=this.buildRequestBody(r,o);u.Authorization=`Bearer ${this.token}`;for await(const c of this.sendAndGetStream(t,i,u,l)){if(401===c.statusCode&&s<1)return this.token=void 0,await this.refreshTokens(),void(yield*this.requestStream(t,e,r,o,n,s+1));if(!this.isSuccessResponse(c))throw this.createApiError(c);yield(0,a.parseContent)(c.body.content||c.body)}}async ensureAuthenticated(){if(!this.token){if(this.authenticationPromise)return this.authenticationPromise;this.authenticationPromise=this.performAuthentication();try{await this.authenticationPromise}catch(t){if(this.authenticationPromise=void 0,t instanceof i.LaraApiError&&(401===t.statusCode||403===t.statusCode))throw t;try{this.authenticationPromise=this.performAuthentication(),await this.authenticationPromise}catch(t){throw this.authenticationPromise=void 0,t instanceof i.LaraApiError?t:new i.LaraApiError(500,"AuthenticationError",t.message)}}}}async performAuthentication(){if(this.refreshToken)return this.refreshTokens();if(this.authToken)return this.token=this.authToken.token,this.refreshToken=this.authToken.refreshToken,void(this.authToken=void 0);if(this.accessKey)return this.authenticateWithAccessKey();throw new Error("No authentication method provided")}async refreshTokens(){const t={Authorization:`Bearer ${this.refreshToken}`,"X-Lara-Date":(new Date).toUTCString()},e=await this.send("POST","/v2/auth/refresh",t);this.handleAuthResponse(e)}async authenticateWithAccessKey(){if(!this.accessKey)throw new Error("No access key provided");const t={id:this.accessKey.id},e=await this.crypto.digestBase64(JSON.stringify(t)),r={"Content-Type":"application/json","X-Lara-Date":(new Date).toUTCString(),"Content-MD5":e};r.Authorization=`Lara:${await this.sign("POST","/v2/auth",r)}`;const o=await this.send("POST","/v2/auth",r,t);this.handleAuthResponse(o)}buildPathWithQuery(t,e){const r=this.filterNullish(e);return r?`${t}?${new URLSearchParams(r).toString()}`:t}async buildRequestHeaders(t,e,r){const o={"X-Lara-Date":(new Date).toUTCString(),"X-Lara-SDK-Name":"lara-node","X-Lara-SDK-Version":u.version,...this.extraHeaders,...r},n=this.filterNullish(t);if(e)o["Content-Type"]="multipart/form-data";else if(n){o["Content-Type"]="application/json";const t=JSON.stringify(n,void 0,0);o["Content-Length"]=(new TextEncoder).encode(t).length.toString()}return o}buildRequestBody(t,e){const r=this.filterNullish(t);if(e){const t={};for(const[r,o]of Object.entries(e))t[r]=this.wrapMultiPartFile(o);return{...t,...r}}return r}filterNullish(t){if(!t)return;const e=Object.fromEntries(Object.entries(t).filter(([t,e])=>null!=e));return Object.keys(e).length>0?e:void 0}isSuccessResponse(t){return t.statusCode>=200&&t.statusCode<300}handleAuthResponse(t){if(this.isSuccessResponse(t))return this.token=t.body.token,void(this.refreshToken=t.headers["x-lara-refresh-token"]);throw this.createApiError(t)}createApiError(t){var e;const r=(null===(e=t.body)||void 0===e?void 0:e.error)||t.body||{};return new i.LaraApiError(t.statusCode,r.type||"UnknownError",r.message||"An unknown error occurred")}async sign(t,e,r){if(!this.accessKey)throw new Error("Access key not provided for signing");const o=r["X-Lara-Date"].trim(),n=(r["Content-MD5"]||"").trim(),s=(r["Content-Type"]||"").trim(),i=`${(r["X-HTTP-Method-Override"]||t).trim().toUpperCase()}\n${e}\n${n}\n${s}\n${o}`;return this.crypto.hmac(this.accessKey.secret,i)}}},414:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AuthToken=e.Credentials=e.AccessKey=void 0;class r{constructor(t,e){this.id=t,this.secret=e}}e.AccessKey=r,e.Credentials=class extends r{get accessKeyId(){return this.id}get accessKeySecret(){return this.secret}},e.AuthToken=class{constructor(t,e){this.token=t,this.refreshToken=e}}},514:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Glossaries=void 0;const o=r(725);e.Glossaries=class{constructor(t){this.client=t,this.pollingInterval=2e3}async list(){return await this.client.get("/v2/glossaries")}async create(t){return await this.client.post("/v2/glossaries",{name:t})}async get(t){try{return await this.client.get(`/v2/glossaries/${t}`)}catch(t){if(t instanceof o.LaraApiError&&404===t.statusCode)return null;throw t}}async delete(t){return await this.client.delete(`/v2/glossaries/${t}`)}async update(t,e){return await this.client.put(`/v2/glossaries/${t}`,{name:e})}async importCsv(t,e,r,o){let n=!1,s="csv/table-uni";return"boolean"==typeof r?n=r:"string"==typeof r&&(s=r,n=null!=o&&o),await this.client.post(`/v2/glossaries/${t}/import`,{compression:n?"gzip":void 0,content_type:s},{csv:e})}async getImportStatus(t){return await this.client.get(`/v2/glossaries/imports/${t}`)}async waitForImport(t,e,r){const n=Date.now();for(;t.progress<1;){if(r&&Date.now()-n>r)throw new o.TimeoutError;await new Promise(t=>setTimeout(t,this.pollingInterval)),t=await this.getImportStatus(t.id),e&&e(t)}return t}async counts(t){return await this.client.get(`/v2/glossaries/${t}/counts`)}async export(t,e,r){return await this.client.get(`/v2/glossaries/${t}/export`,{content_type:e,source:r})}async addOrReplaceEntry(t,e,r){return await this.client.put(`/v2/glossaries/${t}/content`,{terms:e,guid:r})}async deleteEntry(t,e,r){return await this.client.delete(`/v2/glossaries/${t}/content`,void 0,{term:e,guid:r})}}},629:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Memories=void 0;const o=r(725);e.Memories=class{constructor(t){this.client=t,this.pollingInterval=2e3}async list(){return await this.client.get("/v2/memories")}async create(t,e){return await this.client.post("/v2/memories",{name:t,external_id:e})}async get(t){try{return await this.client.get(`/v2/memories/${t}`)}catch(t){if(t instanceof o.LaraApiError&&404===t.statusCode)return null;throw t}}async delete(t){return await this.client.delete(`/v2/memories/${t}`)}async update(t,e){return await this.client.put(`/v2/memories/${t}`,{name:e})}async connect(t){const e=await this.client.post("/v2/memories/connect",{ids:Array.isArray(t)?t:[t]});return Array.isArray(t)?e:e[0]}async importTmx(t,e,r=!1){return await this.client.post(`/v2/memories/${t}/import`,{compression:r?"gzip":void 0},{tmx:e})}async addTranslation(t,e,r,o,n,s,i,a,u){const l={source:e,target:r,sentence:o,translation:n,tuid:s,sentence_before:i,sentence_after:a};return Array.isArray(t)?(l.ids=t,await this.client.put("/v2/memories/content",l,void 0,u)):await this.client.put(`/v2/memories/${t}/content`,l,void 0,u)}async deleteTranslation(t,e,r,o,n,s,i,a){const u={source:e,target:r,sentence:o,translation:n,tuid:s,sentence_before:i,sentence_after:a};return Array.isArray(t)?(u.ids=t,await this.client.delete("/v2/memories/content",void 0,u)):await this.client.delete(`/v2/memories/${t}/content`,void 0,u)}async getImportStatus(t){return await this.client.get(`/v2/memories/imports/${t}`)}async waitForImport(t,e,r){const n=Date.now();for(;t.progress<1;){if(r&&Date.now()-n>r)throw new o.TimeoutError;await new Promise(t=>setTimeout(t,this.pollingInterval)),t=await this.getImportStatus(t.id),e&&e(t)}return t}}},631:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserClient=e.BrowserLaraClient=void 0;const o=r(725),n=r(412);class s extends n.LaraClient{constructor(t,e,r,o){super(e);let n=`${t.secure?"https":"http"}://${t.hostname}`;var s,i;s=t.port,i=t.secure,80===s&&!i||443===s&&i||(n+=`:${t.port}`),this.baseUrl=n,this.timeout=o}async send(t,e,r,n,s){var i;let a;if(n)if("multipart/form-data"===r["Content-Type"]){delete r["Content-Type"];const t=new FormData;for(const[e,r]of Object.entries(n))if(r)if(Array.isArray(r))for(const o of r)t.append(e,o);else t.append(e,r);a=t}else a=JSON.stringify(n,void 0,0);const u=this.timeout&&this.timeout>0?AbortSignal.timeout(this.timeout):void 0;try{const o=await fetch(this.baseUrl+e,{headers:r,method:t,body:a,signal:u});return s&&o.status>=200&&o.status<300?{statusCode:o.status,body:o.body,headers:Object.fromEntries(o.headers)}:(null===(i=o.headers.get("Content-Type"))||void 0===i?void 0:i.includes("text/csv"))?{statusCode:o.status,body:{content:await o.text()},headers:Object.fromEntries(o.headers)}:{statusCode:o.status,body:await o.json(),headers:Object.fromEntries(o.headers)}}catch(t){if(t instanceof Error&&("AbortError"===t.name||"TimeoutError"===t.name))throw new o.TimeoutError(`Request timed out after ${this.timeout}ms`);throw t}}async*sendAndGetStream(t,e,r,n){let s;if(n)if("multipart/form-data"===r["Content-Type"]){delete r["Content-Type"];const t=new FormData;for(const[e,r]of Object.entries(n))if(r)if(Array.isArray(r))for(const o of r)t.append(e,o);else t.append(e,r);s=t}else s=JSON.stringify(n,void 0,0);const i=this.timeout&&this.timeout>0?AbortSignal.timeout(this.timeout):void 0;let a;try{a=await fetch(this.baseUrl+e,{headers:r,method:t,body:s,signal:i})}catch(t){if(t instanceof Error&&("AbortError"===t.name||"TimeoutError"===t.name))throw new o.TimeoutError(`Request timed out after ${this.timeout}ms`);throw t}if(!a.body)throw new Error("Response body is not available for streaming");const u=a.body.getReader(),l=new TextDecoder;let c="";try{for(;;){let t;try{t=await u.read()}catch(t){if(t instanceof Error&&("AbortError"===t.name||"TimeoutError"===t.name))throw new o.TimeoutError(`Request timed out after ${this.timeout}ms`);throw t}const{done:e,value:r}=t;if(e){if(c.trim())try{const t=JSON.parse(c);yield{statusCode:t.status||a.status,body:t.data||t,headers:Object.fromEntries(a.headers)}}catch(t){}break}c+=l.decode(r,{stream:!0});const n=c.split("\n");c=n.pop()||"";for(const t of n)if(t.trim())try{const e=JSON.parse(t);yield{statusCode:e.status||a.status,body:e.data||e,headers:Object.fromEntries(a.headers)}}catch(t){}}}finally{u.releaseLock()}}wrapMultiPartFile(t){if(t instanceof File)return t;throw new TypeError(`Invalid file input in the browser. Expected an instance of File but received ${typeof t}.`)}}e.BrowserLaraClient=s;class i{static async get(t,e){return i.send("GET",t,e)}static async send(t,e,r,o){var n;let s;if(o)if(r&&"multipart/form-data"===r["Content-Type"]){delete r["Content-Type"];const t=new FormData;for(const[e,r]of Object.entries(o))if(r)if(Array.isArray(r))for(const o of r)t.append(e,o);else t.append(e,r);s=t}else s=JSON.stringify(o,void 0,0);const i=await fetch(e,{headers:r,method:t,body:s});return{statusCode:i.status,headers:Object.fromEntries(i.headers),body:(null===(n=i.headers.get("Content-Type"))||void 0===n?void 0:n.includes("application/json"))?await i.json():await i.text()}}}e.BrowserClient=i},660:function(t,e,r){var o,n=this&&this.__createBinding||(Object.create?function(t,e,r,o){void 0===o&&(o=r);var n=Object.getOwnPropertyDescriptor(e,r);n&&!("get"in n?!e.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,o,n)}:function(t,e,r,o){void 0===o&&(o=r),t[o]=e[r]}),s=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),i=this&&this.__importStar||(o=function(t){return o=Object.getOwnPropertyNames||function(t){var e=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[e.length]=r);return e},o(t)},function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r=o(t),i=0;i<r.length;i++)"default"!==r[i]&&n(e,t,r[i]);return s(e,t),e});Object.defineProperty(e,"__esModule",{value:!0}),e.Translator=void 0;const a=r(328),u=r(50),l=r(514),c=r(731),d=r(629),h=i(r(837)),p=r(221),f=r(311);e.Translator=class{constructor(t,e){this.client=(0,h.default)(t,null==e?void 0:e.serverUrl,null==e?void 0:e.keepAlive,null==e?void 0:e.connectionTimeoutMs),this.memories=new d.Memories(this.client),this.documents=new u.Documents(this.client),this.glossaries=new l.Glossaries(this.client),this.audio=new a.AudioTranslator(this.client),this.images=new c.ImageTranslator(this.client)}get version(){return f.version}async getLanguages(){return await this.client.get("/v2/languages")}async translate(t,e,r,o,n){const s={};if(null==o?void 0:o.headers)for(const[t,e]of Object.entries(o.headers))s[t]=e;(null==o?void 0:o.noTrace)&&(s["X-No-Trace"]="true");const i=this.client.postAndGetStream("/translate",{q:t,source:e,target:r,source_hint:null==o?void 0:o.sourceHint,content_type:null==o?void 0:o.contentType,multiline:!1!==(null==o?void 0:o.multiline),adapt_to:null==o?void 0:o.adaptTo,glossaries:null==o?void 0:o.glossaries,instructions:null==o?void 0:o.instructions,timeout:null==o?void 0:o.timeoutInMillis,priority:null==o?void 0:o.priority,use_cache:null==o?void 0:o.useCache,cache_ttl:null==o?void 0:o.cacheTTLSeconds,verbose:null==o?void 0:o.verbose,style:null==o?void 0:o.style,reasoning:null==o?void 0:o.reasoning},void 0,s);let a;for await(const t of i)(null==o?void 0:o.reasoning)&&n&&n(t),a=t;if(!a)throw new Error("No translation result received.");return a}async detect(t,e,r){return await this.client.post("/v2/detect",{q:t,hint:e,passlist:r})}static async getLoginUrl(t){t||(t=p.DEFAULT_BASE_URL);const{body:e}=await h.HttpClient.get(`${t.replace(/\/+$/,"")}/v2/auth/login-page`);return e}}},725:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.LaraApiError=e.TimeoutError=e.LaraError=void 0;class r extends Error{}e.LaraError=r,e.TimeoutError=class extends r{},e.LaraApiError=class extends r{constructor(t,e,r,o){super(r),this.statusCode=t,this.type=e,this.message=r,this.idTransaction=o}}},731:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.ImageTranslator=void 0,e.ImageTranslator=class{constructor(t){this.client=t}async translate(t,e,r,o){const n=(null==o?void 0:o.noTrace)?{"X-No-Trace":"true"}:{};return n["Content-Type"]="multipart/form-data",this.client.post("/v2/images/translate",{source:e,target:r,adapt_to:JSON.stringify(null==o?void 0:o.adaptTo),glossaries:JSON.stringify(null==o?void 0:o.glossaries),style:null==o?void 0:o.style,text_removal:null==o?void 0:o.textRemoval},{image:t},n,!0)}async translateText(t,e,r,o){const n=(null==o?void 0:o.noTrace)?{"X-No-Trace":"true"}:{};return n["Content-Type"]="multipart/form-data",this.client.post("/v2/images/translate-text",{source:e,target:r,adapt_to:JSON.stringify(null==o?void 0:o.adaptTo),glossaries:JSON.stringify(null==o?void 0:o.glossaries),style:null==o?void 0:o.style,verbose:JSON.stringify(null==o?void 0:o.verbose)},{image:t},n)}}},741:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.parseContent=function t(e){if(null==e)return e;if(Array.isArray(e))return e.map(t);if("string"==typeof e)return e.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.[0-9]{3}Z$/)?new Date(e):e;if("object"==typeof e){const r={};for(const[o,n]of Object.entries(e))r[o.replace(/_([a-z])/g,(t,e)=>e.toUpperCase())]=t(n);return r}return e}},780:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserCrypto=void 0,e.BrowserCrypto=class{constructor(){this.subtle=window.crypto.subtle}async digestBase64(t){const e=new TextEncoder,r=(await this.subtle.digest("sha-256",e.encode(t))).slice(0,16);return btoa(String.fromCharCode(...new Uint8Array(r)))}async hmac(t,e){const r=new TextEncoder;r.encode(e);const o=await this.subtle.importKey("raw",r.encode(t),{name:"hmac",hash:{name:"sha-256"}},!1,["sign"]),n=await this.subtle.sign("hmac",o,r.encode(e));return btoa(String.fromCharCode(...new Uint8Array(n)))}}},821:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){return new o.BrowserS3Client};const o=r(343)},837:(t,e,r)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.HttpClient=e.LaraClient=void 0,e.default=function(t,e,r,s){const i=new URL(e||o.DEFAULT_BASE_URL);if("https:"!==i.protocol&&"http:"!==i.protocol)throw new TypeError(`Invalid URL (protocol): ${i.protocol}`);const a={secure:"https:"===i.protocol,hostname:i.hostname,port:i.port?parseInt(i.port,10):"https:"===i.protocol?443:80};return new n.BrowserLaraClient(a,t,null==r||r,s)};const o=r(221),n=r(631);var s=r(412);Object.defineProperty(e,"LaraClient",{enumerable:!0,get:function(){return s.LaraClient}});var i=r(631);Object.defineProperty(e,"HttpClient",{enumerable:!0,get:function(){return i.BrowserClient}})},841:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0});const r=t=>{if("string"==typeof t)return t;if(Array.isArray(t))return t.map(r);if("object"==typeof t&&null!==t){const e={};for(const[o,n]of Object.entries(t))e[o.replace(/([A-Z])/g,"_$1").toLowerCase()]=r(n);return e}return t};e.default=r}},e={};function r(o){var n=e[o];if(void 0!==n)return n.exports;var s=e[o]={exports:{}};return t[o].call(s.exports,s,s.exports,r),s.exports}var o={};return(()=>{var t=o;Object.defineProperty(t,"__esModule",{value:!0}),t.version=t.Translator=t.Memories=t.ImageTranslator=t.Glossaries=t.TimeoutError=t.LaraError=t.LaraApiError=t.Documents=t.DocumentStatus=t.Credentials=t.AuthToken=t.AccessKey=t.AudioTranslator=t.AudioStatus=void 0;var e=r(328);Object.defineProperty(t,"AudioStatus",{enumerable:!0,get:function(){return e.AudioStatus}}),Object.defineProperty(t,"AudioTranslator",{enumerable:!0,get:function(){return e.AudioTranslator}});var n=r(414);Object.defineProperty(t,"AccessKey",{enumerable:!0,get:function(){return n.AccessKey}}),Object.defineProperty(t,"AuthToken",{enumerable:!0,get:function(){return n.AuthToken}}),Object.defineProperty(t,"Credentials",{enumerable:!0,get:function(){return n.Credentials}});var s=r(50);Object.defineProperty(t,"DocumentStatus",{enumerable:!0,get:function(){return s.DocumentStatus}}),Object.defineProperty(t,"Documents",{enumerable:!0,get:function(){return s.Documents}});var i=r(725);Object.defineProperty(t,"LaraApiError",{enumerable:!0,get:function(){return i.LaraApiError}}),Object.defineProperty(t,"LaraError",{enumerable:!0,get:function(){return i.LaraError}}),Object.defineProperty(t,"TimeoutError",{enumerable:!0,get:function(){return i.TimeoutError}});var a=r(514);Object.defineProperty(t,"Glossaries",{enumerable:!0,get:function(){return a.Glossaries}});var u=r(731);Object.defineProperty(t,"ImageTranslator",{enumerable:!0,get:function(){return u.ImageTranslator}});var l=r(629);Object.defineProperty(t,"Memories",{enumerable:!0,get:function(){return l.Memories}});var c=r(660);Object.defineProperty(t,"Translator",{enumerable:!0,get:function(){return c.Translator}});var d=r(311);Object.defineProperty(t,"version",{enumerable:!0,get:function(){return d.version}})})(),o})());
|