@translated/lara 1.8.0-beta.4 → 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 +1 -1
- package/lib/net/lara/browser-client.js +14 -34
- package/lib/net/lara/client.d.ts +4 -4
- package/lib/net/lara/client.js +12 -12
- package/lib/net/lara/node-client.d.ts +1 -1
- package/lib/net/lara/node-client.js +39 -34
- 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 +8 -0
- package/lib/translator.js +6 -2
- 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");
|
|
@@ -5,7 +5,7 @@ export declare class BrowserLaraClient extends LaraClient {
|
|
|
5
5
|
private readonly baseUrl;
|
|
6
6
|
private readonly timeout;
|
|
7
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
|
|
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
|
}
|
|
@@ -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,24 +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
|
-
abortController = new AbortController();
|
|
48
|
-
timeoutId = setTimeout(() => {
|
|
49
|
-
abortController.abort();
|
|
50
|
-
}, this.timeout);
|
|
51
|
-
}
|
|
43
|
+
const signal = this.timeout && this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined;
|
|
52
44
|
try {
|
|
53
45
|
const response = await fetch(this.baseUrl + path, {
|
|
54
46
|
headers,
|
|
55
47
|
method,
|
|
56
48
|
body: requestBody,
|
|
57
|
-
signal
|
|
49
|
+
signal
|
|
58
50
|
});
|
|
59
|
-
if (
|
|
60
|
-
|
|
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
|
+
};
|
|
61
57
|
}
|
|
62
58
|
if ((_a = response.headers.get("Content-Type")) === null || _a === void 0 ? void 0 : _a.includes("text/csv")) {
|
|
63
59
|
return {
|
|
@@ -75,9 +71,7 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
75
71
|
};
|
|
76
72
|
}
|
|
77
73
|
catch (err) {
|
|
78
|
-
if (
|
|
79
|
-
clearTimeout(timeoutId);
|
|
80
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
74
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) {
|
|
81
75
|
throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
82
76
|
}
|
|
83
77
|
throw err;
|
|
@@ -106,35 +100,23 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
106
100
|
requestBody = JSON.stringify(body, undefined, 0);
|
|
107
101
|
}
|
|
108
102
|
}
|
|
109
|
-
|
|
110
|
-
let abortController;
|
|
111
|
-
let timeoutId;
|
|
112
|
-
if (this.timeout && this.timeout > 0) {
|
|
113
|
-
abortController = new AbortController();
|
|
114
|
-
timeoutId = setTimeout(() => {
|
|
115
|
-
abortController.abort();
|
|
116
|
-
}, this.timeout);
|
|
117
|
-
}
|
|
103
|
+
const signal = this.timeout && this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined;
|
|
118
104
|
let response;
|
|
119
105
|
try {
|
|
120
106
|
response = await fetch(this.baseUrl + path, {
|
|
121
107
|
headers,
|
|
122
108
|
method,
|
|
123
109
|
body: requestBody,
|
|
124
|
-
signal
|
|
110
|
+
signal
|
|
125
111
|
});
|
|
126
112
|
}
|
|
127
113
|
catch (err) {
|
|
128
|
-
if (
|
|
129
|
-
clearTimeout(timeoutId);
|
|
130
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
114
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) {
|
|
131
115
|
throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
132
116
|
}
|
|
133
117
|
throw err;
|
|
134
118
|
}
|
|
135
119
|
if (!response.body) {
|
|
136
|
-
if (timeoutId)
|
|
137
|
-
clearTimeout(timeoutId);
|
|
138
120
|
throw new Error("Response body is not available for streaming");
|
|
139
121
|
}
|
|
140
122
|
const reader = response.body.getReader();
|
|
@@ -147,7 +129,7 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
147
129
|
readResult = await reader.read();
|
|
148
130
|
}
|
|
149
131
|
catch (err) {
|
|
150
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
132
|
+
if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) {
|
|
151
133
|
throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
152
134
|
}
|
|
153
135
|
throw err;
|
|
@@ -191,8 +173,6 @@ class BrowserLaraClient extends client_1.LaraClient {
|
|
|
191
173
|
}
|
|
192
174
|
}
|
|
193
175
|
finally {
|
|
194
|
-
if (timeoutId)
|
|
195
|
-
clearTimeout(timeoutId);
|
|
196
176
|
reader.releaseLock();
|
|
197
177
|
}
|
|
198
178
|
}
|
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) {
|
|
@@ -7,7 +7,7 @@ export declare class NodeLaraClient extends LaraClient {
|
|
|
7
7
|
private readonly agent;
|
|
8
8
|
private readonly timeout;
|
|
9
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
|
|
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,6 +8,7 @@ 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");
|
|
@@ -19,7 +20,7 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
19
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
|
|
@@ -83,28 +94,25 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
83
94
|
}
|
|
84
95
|
});
|
|
85
96
|
res.on("error", (err) => {
|
|
97
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
98
|
+
if (err instanceof errors_1.TimeoutError)
|
|
99
|
+
return reject(err);
|
|
86
100
|
req.destroy();
|
|
87
|
-
if (err.code === "ECONNRESET" && req.__timeoutTriggered) {
|
|
88
|
-
return reject(new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`));
|
|
89
|
-
}
|
|
90
101
|
return reject(err);
|
|
91
102
|
});
|
|
92
103
|
});
|
|
93
104
|
req.on("error", (err) => {
|
|
94
|
-
|
|
95
|
-
if (err
|
|
96
|
-
return reject(new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`));
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
105
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
106
|
+
if (err instanceof errors_1.TimeoutError)
|
|
99
107
|
return reject(err);
|
|
100
|
-
|
|
108
|
+
req.destroy();
|
|
109
|
+
return reject(err);
|
|
101
110
|
});
|
|
102
111
|
// Set timeout if provided and positive
|
|
103
112
|
if (this.timeout && this.timeout > 0) {
|
|
104
|
-
|
|
105
|
-
req.
|
|
106
|
-
|
|
107
|
-
});
|
|
113
|
+
hardTimeout = setTimeout(() => {
|
|
114
|
+
req.destroy(new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`));
|
|
115
|
+
}, this.timeout);
|
|
108
116
|
}
|
|
109
117
|
if (requestBody instanceof form_data_1.default) {
|
|
110
118
|
requestBody.pipe(req);
|
|
@@ -152,6 +160,7 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
152
160
|
headers: headers,
|
|
153
161
|
agent: this.agent
|
|
154
162
|
};
|
|
163
|
+
let hardTimeout = null;
|
|
155
164
|
// Create async iterator from the stream
|
|
156
165
|
const chunks = [];
|
|
157
166
|
let resolveChunk = null;
|
|
@@ -184,6 +193,7 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
184
193
|
}
|
|
185
194
|
});
|
|
186
195
|
res.on("end", () => {
|
|
196
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
187
197
|
// Process any remaining data in buffer
|
|
188
198
|
if (buffer.trim()) {
|
|
189
199
|
try {
|
|
@@ -205,13 +215,11 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
205
215
|
}
|
|
206
216
|
});
|
|
207
217
|
res.on("error", (err) => {
|
|
218
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
219
|
+
if (err instanceof errors_1.TimeoutError)
|
|
220
|
+
throw err;
|
|
208
221
|
req.destroy();
|
|
209
|
-
|
|
210
|
-
streamError = new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`);
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
streamError = err;
|
|
214
|
-
}
|
|
222
|
+
streamError = err;
|
|
215
223
|
if (resolveChunk) {
|
|
216
224
|
resolveChunk();
|
|
217
225
|
resolveChunk = null;
|
|
@@ -219,12 +227,10 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
219
227
|
});
|
|
220
228
|
});
|
|
221
229
|
req.on("error", (err) => {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
streamError = err;
|
|
227
|
-
}
|
|
230
|
+
hardTimeout && (0, node_timers_1.clearTimeout)(hardTimeout);
|
|
231
|
+
if (err instanceof errors_1.TimeoutError)
|
|
232
|
+
throw err;
|
|
233
|
+
streamError = err;
|
|
228
234
|
if (resolveChunk) {
|
|
229
235
|
resolveChunk();
|
|
230
236
|
resolveChunk = null;
|
|
@@ -232,10 +238,9 @@ class NodeLaraClient extends client_1.LaraClient {
|
|
|
232
238
|
});
|
|
233
239
|
// Set timeout if provided and positive
|
|
234
240
|
if (this.timeout && this.timeout > 0) {
|
|
235
|
-
|
|
236
|
-
req.
|
|
237
|
-
|
|
238
|
-
});
|
|
241
|
+
hardTimeout = setTimeout(() => {
|
|
242
|
+
req.destroy(new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`));
|
|
243
|
+
}, this.timeout);
|
|
239
244
|
}
|
|
240
245
|
if (requestBody instanceof form_data_1.default) {
|
|
241
246
|
requestBody.pipe(req);
|
|
@@ -336,9 +341,9 @@ class NodeClient {
|
|
|
336
341
|
json = JSON.parse(data);
|
|
337
342
|
}
|
|
338
343
|
catch (_e) {
|
|
339
|
-
reject(new SyntaxError("Invalid JSON response"));
|
|
344
|
+
return reject(new SyntaxError("Invalid JSON response"));
|
|
340
345
|
}
|
|
341
|
-
resolve({
|
|
346
|
+
return resolve({
|
|
342
347
|
statusCode: res.statusCode,
|
|
343
348
|
body: json,
|
|
344
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,6 +1,8 @@
|
|
|
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 = {
|
|
@@ -56,12 +58,18 @@ export type TranslationStyle = "faithful" | "fluid" | "creative";
|
|
|
56
58
|
export interface DetectResult {
|
|
57
59
|
language: string;
|
|
58
60
|
contentType: string;
|
|
61
|
+
predictions: {
|
|
62
|
+
language: string;
|
|
63
|
+
confidence: number;
|
|
64
|
+
}[];
|
|
59
65
|
}
|
|
60
66
|
export declare class Translator {
|
|
61
67
|
protected readonly client: LaraClient;
|
|
62
68
|
readonly memories: Memories;
|
|
63
69
|
readonly documents: Documents;
|
|
64
70
|
readonly glossaries: Glossaries;
|
|
71
|
+
readonly audio: AudioTranslator;
|
|
72
|
+
readonly images: ImageTranslator;
|
|
65
73
|
constructor(auth: AccessKey | AuthToken, options?: TranslatorOptions);
|
|
66
74
|
get version(): string;
|
|
67
75
|
getLanguages(): Promise<string[]>;
|
package/lib/translator.js
CHANGED
|
@@ -34,8 +34,10 @@ 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");
|
|
@@ -46,6 +48,8 @@ class Translator {
|
|
|
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.3"},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,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){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&&(a=new AbortController,c=setTimeout(()=>{a.abort()},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&&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(!c.body)throw a&&clearTimeout(a),new Error("Response body is not available for streaming");const u=c.body.getReader(),l=new TextDecoder;let d="";try{for(;;){let t;try{t=await u.read()}catch(t){if(t instanceof Error&&"AbortError"===t.name)throw new o.TimeoutError(`Request timed out after ${this.timeout}ms`);throw t}const{done:e,value:r}=t;if(e){if(d.trim())try{const t=JSON.parse(d);yield{statusCode:t.status||c.status,body:t.data||t,headers:Object.fromEntries(c.headers)}}catch(t){}break}d+=l.decode(r,{stream:!0});const n=d.split("\n");d=n.pop()||"";for(const t of n)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{a&&clearTimeout(a),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.keepAlive,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,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.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})());
|