UNPKG

@translated/lara

Version:

Official Lara SDK for JavaScript and Node.js

809 lines (638 loc) โ€ข 30.5 kB
# Lara Node.js SDK [![Node Version](https://img.shields.io/badge/node-12+-blue.svg)](https://nodejs.org) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) This SDK empowers you to build your own branded translation AI leveraging our translation fine-tuned language model. All major translation features are accessible, making it easy to integrate and customize for your needs. ## ๐ŸŒ **Features:** - **Text Translation**: Single strings, multiple strings, and complex text blocks - **Document Translation**: Word, PDF, and other document formats with status monitoring - **Image Translation**: Translate whole images or extract and translate text blocks - **Audio Translation**: Translate audio files with status monitoring - **Translation Memory**: Store and reuse translations for consistency - **Glossaries**: Enforce terminology standards across translations - **Styleguides**: Define tone, voice, and writing style rules for translations - **Language Detection**: Automatic source language identification - **Advanced Options**: Translation instructions and more ## ๐Ÿ“š Documentation Lara's SDK full documentation is available at [https://developers.laratranslate.com/](https://developers.laratranslate.com/) ## ๐Ÿš€ Quick Start ### Installation ```bash npm install @translated/lara ``` ### Basic Usage ```javascript const { Credentials, Translator } = require('@translated/lara'); // Set your credentials using environment variables (recommended) const credentials = new Credentials( process.env.LARA_ACCESS_KEY_ID, process.env.LARA_ACCESS_KEY_SECRET ); // Create translator instance const lara = new Translator(credentials); // Simple text translation async function translateText() { try { const result = await lara.translate("Hello, world!", "en-US", "fr-FR"); console.log("Translation: " + result.translation); // Output: Translation: Bonjour, le monde ! } catch (error) { console.error("Translation error:", error.message); } } translateText(); ``` ## ๐Ÿ“– Examples The `examples/` directory contains comprehensive examples for all SDK features. **All examples use environment variables for credentials, so set them first:** ```bash export LARA_ACCESS_KEY_ID="your-access-key-id" export LARA_ACCESS_KEY_SECRET="your-access-key-secret" ``` ### Text Translation - **[text_translation.js](examples/text_translation.js)** - Complete text translation examples - Single string translation - Multiple strings translation - Translation with instructions - TextBlocks translation (mixed translatable/non-translatable content) - Auto-detect source language - Advanced translation options - Get available languages ```bash cd examples node text_translation.js ``` ### Document Translation - **[document_translation.js](examples/document_translation.js)** - Document translation examples - Basic document translation - Advanced options with memories and glossaries - Step-by-step translation with status monitoring ```bash cd examples node document_translation.js ``` ### Image Translation - **[image_translation.js](examples/image_translation.js)** - Image translation examples - Basic image translation - Advanced options with memories and glossaries - Extract and translate text from an image - Edit translations and render them with layout or text-only paragraphs ```bash cd examples node image_translation.js ``` ### Audio Translation - **[audio_translation.js](examples/audio_translation.js)** - Audio translation examples - Basic audio translation - Advanced options with memories and glossaries - Step-by-step audio translation with status monitoring ```bash cd examples node audio_translation.js ``` ### Translation Memory Management - **[memories_management.js](examples/memories_management.js)** - Memory management examples - Create, list, update, delete memories - Add individual translations - Multiple memory operations - TMX file import with progress monitoring - Translation deletion - Translation with TUID and context ```bash cd examples node memories_management.js ``` ### Glossary Management - **[glossaries_management.js](examples/glossaries_management.js)** - Glossary management examples - Create, list, update, delete glossaries - CSV import with status monitoring - Glossary export (sync and async) - Glossary terms count - Import status checking ```bash cd examples node glossaries_management.js ``` ### Styleguide Management - **[styleguide_management.js](examples/styleguide_management.js)** - Styleguide management examples - Create, list, get, update, delete styleguides - Update name, content, or both at once - Handling of non-existent styleguides ```bash cd examples node styleguide_management.js ``` ## ๐Ÿ”ง API Reference ### Core Components ### ๐Ÿ” Authentication The SDK supports authentication via access key and secret: ```javascript const credentials = new Credentials("your-access-key-id", "your-access-key-secret"); const lara = new Translator(credentials); ``` **Environment Variables (Recommended):** ```bash export LARA_ACCESS_KEY_ID="your-access-key-id" export LARA_ACCESS_KEY_SECRET="your-access-key-secret" ``` ```javascript const credentials = new Credentials( process.env.LARA_ACCESS_KEY_ID, process.env.LARA_ACCESS_KEY_SECRET ); ``` ### ๐ŸŒ Translator ```javascript // Create translator with credentials const lara = new Translator(credentials); ``` #### Text Translation ```javascript // Basic translation const result = await lara.translate("Hello", "en-US", "fr-FR"); // Multiple strings const result = await lara.translate(["Hello", "World"], "en-US", "fr-FR"); // TextBlocks (mixed translatable/non-translatable content) const textBlocks = [ { text: "Translatable text", translatable: true }, { text: "<br>", translatable: false }, // Non-translatable HTML { text: "More translatable text", translatable: true } ]; const result = await lara.translate(textBlocks, "en-US", "fr-FR"); // With advanced options const options = { instructions: ["Formal tone"], adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual memory IDs glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual glossary IDs style: "fluid", timeoutInMillis: 10000 }; const result = await lara.translate("Hello", "en-US", "fr-FR", options); ``` #### Reasoning Effort Set `reasoningEffort` to `low`, `medium`, or `high` to control translation reasoning effort. Reasoning must be enabled. Omit the option to use the server default; the API validates the combination. ```typescript const result = await lara.translate("Hello", "en-US", "it-IT", { reasoning: true, reasoningEffort: "high" }); ``` #### Text Translation with Image Context Pass `imageContext` to use an image as visual context for translating text. Enable `reasoning` with `true`: ```javascript const result = await lara.translate("Open", "en-US", "it-IT", { reasoning: true, imageContext: { url: "https://example.com/storefront.png" } }); console.log(result.translation); // The server reports recovery without images under warnings.reasoning. for (const warning of result.warnings?.reasoning?.warnings ?? []) { console.warn(warning.code, warning.message); } ``` You can also supply a single-element array or an inline image. For example, in Node.js: ```javascript const fs = require("fs"); const result = await lara.translate("Open", "en-US", "it-IT", { reasoning: true, imageContext: [{ url: `data:image/png;base64,${fs.readFileSync("storefront.png").toString("base64")}` }] }); ``` The API accepts at most one image: an HTTPS URL or a base64 PNG, JPEG or WebP data URL. Inline images must match their declared MIME type and contain at most 5 MiB of decoded data; the serialized request body is limited to 16 MiB. Omitting `imageContext` or passing `[]` preserves text-only behavior. Validation is performed by the API, which returns 400 for invalid input and 413 for size violations. If the image cannot be used, the server may retry the entire request with reasoning without images. The result then includes an `image_context_unavailable` warning under `warnings.reasoning.warnings`. `warnings.reasoning.applied` is `true` when reasoning succeeds without images, or `false` (with an `error`) when the server falls back to standard translation. #### Language Detection Use detect() to automatically identify the language of one or multiple texts. ```javascript // Single string detection const single = await lara.detect("Bonjour tout le monde"); console.log(single.language); // fr // Multiple strings detection const multiple = await lara.detect(["Hello world", "How are you?"]); console.log(multiple.languages); // "en" ``` You can provide a hint (expected source language) and a passlist (restrict candidates) to improve accuracy. ```javascript // Detection with hint and passlist const detected = await lara.detect( "Es un dรญa soleado", "es", // hint (optional) ["es", "pt", "fr"] // passlist (optional) ); console.log(detected.language); // es ``` #### Quality Estimation Use `qualityEstimation()` to score how well a translation matches its source. Pass a single sentence/translation pair to get a single result, or two parallel arrays to get one result per pair. ```javascript // Single pair const single = await lara.qualityEstimation( "en-US", "it-IT", "Hello, how are you today?", "Ciao, come stai oggi?" ); console.log(single.score); // e.g. 0.768 // Batch const batch = await lara.qualityEstimation( "en-US", "it-IT", ["Good morning.", "The weather is nice."], ["Buongiorno.", "Il tempo รจ bello."] ); console.log(batch.map(r => r.score)); // e.g. [0.751, 0.713] ``` ### ๐Ÿ“– Document Translation #### Simple document translation ```javascript const fs = require('fs'); const fileStream = fs.createReadStream("/path/to/your/document.txt"); // Replace with actual file path const translatedContent = await lara.documents.translate(fileStream, "document.txt", "en-US", "fr-FR"); // With options const options = { adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual memory IDs glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual glossary IDs style: "fluid" }; const translatedContent = await lara.documents.translate(fileStream, "document.txt", "en-US", "fr-FR", options); ``` ### Document translation with status monitoring #### Document upload ```javascript //Optional: upload options const uploadOptions = { adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual memory IDs glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"] // Replace with actual glossary IDs }; const document = await lara.documents.upload(fileStream, "document.txt", "en-US", "fr-FR", uploadOptions); ``` #### Document translation status monitoring ```javascript const status = await lara.documents.status(document.id); ``` #### Download translated document ```javascript const translatedContent = await lara.documents.download(document.id); ``` ### ๐Ÿ–ผ๏ธ Image Translation ```typescript const fs = require("fs"); const { pipeline } = require("stream"); const { promisify } = require("util"); const saveImage = promisify(pipeline); const imagePath = "/path/to/your/image.png"; // Replace with actual file path // Translate image and receive a translated image stream const translatedImageStream = await lara.images.translate(fs.createReadStream(imagePath), "en", "fr", { model: "generative_fast", style: "faithful" }); await saveImage(translatedImageStream, fs.createWriteStream("translated.png")); // Request layout metadata. Open a fresh stream for every request. const textBlocks = await lara.images.translateText(fs.createReadStream(imagePath), "en", "fr", { includeLayout: true }); // Replace the first translation while preserving its geometry and text styling. const editedParagraphs = textBlocks.paragraphs.map((paragraph, index) => index === 0 ? { ...paragraph, translation: "Bonjour le monde !" } : paragraph ); const renderedImage = await lara.images.renderTranslated( fs.createReadStream(imagePath), textBlocks.sourceLanguage, "fr", editedParagraphs, "overlay" ); await saveImage(renderedImage, fs.createWriteStream("edited-overlay.png")); // Generative models can render text-only paragraphs. Omit model for generative_fast. const textOnlyParagraphs = editedParagraphs.map(({ text, translation }) => ({ text, translation })); const generativeImage = await lara.images.renderTranslated( fs.createReadStream(imagePath), null, "fr", textOnlyParagraphs ); await saveImage(generativeImage, fs.createWriteStream("edited-generative.png")); ``` `renderTranslated(file, source, target, paragraphs, model?, noTrace?)` renders supplied translations without translating them again. Pass `null` for `source` to omit the source language. The supported models are `overlay`, `inpainting`, `generative`, and `generative_fast`; omitting `model` uses the API default, `generative_fast`. Set `noTrace` to `true` to disable request tracing. The classic models (`overlay` and `inpainting`) require every paragraph to include `text`, `translation`, and all layout fields: `bbox`, `linesBboxes`, `textInfo`, and `alignment`. Both generative models accept text-only or complete layout paragraphs. Partial layout is invalid; validation errors are reported through the usual `LaraApiError` handling. The TypeScript overloads enforce the model's input requirements: | Model | Paragraph argument | | --- | --- | | `overlay`, `inpainting` | `(ImageParagraphContent & ImageParagraphLayout)[]` | | `generative`, `generative_fast`, or omitted | `ImageParagraphContent[]` (complete layout paragraphs also accepted) | | A variable that could select either model family | `(ImageParagraphContent & ImageParagraphLayout)[]`; narrow the model to a generative value to use text only | TypeScript exports include `ImageTranslationModel`, `ImageParagraphContent`, `ImageLayoutParagraph`, and the shared `ImageParagraphLayout`, `ImageBBox`, and `ImageTextInfo` types. Bounding boxes contain `topLeft`, `topRight`, `bottomRight`, and `bottomLeft` coordinate pairs (`[number, number]`). Text info contains `direction` (`ltr`, `rtl`, or `ttb`), `textColor`, and `backgroundColor`; alignment is `left`, `center`, or `right`. `translateText` infers the paragraph type in `ImageTextResult<Paragraph>` from `includeLayout`: | Options | Paragraph fields | | --- | --- | | `includeLayout` omitted or `false` | `ImageParagraph` | | `includeLayout: true` | `ImageLayoutParagraph`: complete layout metadata is included | `includeLayout: true` guarantees that `bbox`, `linesBboxes`, `textInfo`, and `alignment` are present on every paragraph, so the result can be passed directly to a classic rendering model. `ImageParagraphContent` contains `text` and `translation`. `ImageParagraph` extends it with the optional fields `adaptedToMatches?: NGMemoryMatch[]` and `glossariesMatches?: NGGlossaryMatch[]`. `verbose: true` requests match details from the API, but does not change the return type: match fields remain optional with or without layout. Plain `ImageTextResult` defaults to `ImageParagraph` entries. An `includeLayout` boolean whose value is only known at runtime produces a union of the two paragraph shapes. Keep all available layout metadata when editing translations for classic rendering. The SDK converts these camelCase properties to the API's snake_case JSON fields. ### ๐Ÿ”Š Audio Translation #### Simple audio translation ```javascript const fs = require("fs"); const fileStream = fs.createReadStream("/path/to/your/audio.mp3"); // Replace with actual file path const translatedStream = await lara.audio.translate(fileStream, "audio.mp3", "en-US", "de-DE"); // With options const options = { adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual memory IDs glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"] // Replace with actual glossary IDs }; const translatedStream = await lara.audio.translate(fileStream, "audio.mp3", "en-US", "de-DE", options); ``` ### Audio translation with status monitoring #### Audio upload ```javascript // Optional: upload options const uploadOptions = { adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"], // Replace with actual memory IDs glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"] // Replace with actual glossary IDs }; const audio = await lara.audio.upload(fileStream, "audio.mp3", "en-US", "de-DE", uploadOptions); ``` #### Audio translation status monitoring ```javascript const status = await lara.audio.status(audio.id); ``` #### Download translated audio ```javascript const translatedStream = await lara.audio.download(audio.id); ``` ### ๐Ÿง  Memory Management ```javascript // Create memory const memory = await lara.memories.create("MyMemory"); // Create memory with external ID (MyMemory integration) const memory = await lara.memories.create("Memory from MyMemory", "aabb1122"); // Replace with actual external ID // listPaginated() supports optional name filtering and pagination. Called without options, // it returns the complete list of memories without pagination. Providing search, page, // or size enables pagination. const { items: memories, total: memoryTotal } = await lara.memories.listPaginated(); // Providing page or size enables pagination (page starts at 1; size: 1-200). // The missing parameter defaults to page 1 or size 20. const memoryPage = await lara.memories.listPaginated({ page: 2, size: 50 }); const memoryDefaultSize = await lara.memories.listPaginated({ page: 2 }); // Page 2, 20 per page const memoryFirstPage = await lara.memories.listPaginated({ size: 50 }); // Page 1, 50 per page // Pass search to filter by displayed name (case- and accent-insensitive). // It matches substrings and preserves spaces. // Combine search with page and size to paginate matching results. // If omitted, page defaults to 1 and size to 20. const memorySearch = await lara.memories.listPaginated({ search: "Marketing", page: 2, size: 50 }); // list() is deprecated; use listPaginated() instead. // Important: To update/overwrite a translation unit you must provide a tuid. Calls without a tuid always create a new unit and will not update existing entries. // Add translation to single memory const memoryImport = await lara.memories.addTranslation("mem_1A2b3C4d5E6f7G8h9I0jKl", "en-US", "fr-FR", "Hello", "Bonjour", "greeting_001"); // Add translation to multiple memories const memoryImport = await lara.memories.addTranslation(["mem_1A2b3C4d5E6f7G8h9I0jKl", "mem_2XyZ9AbC8dEf7GhI6jKlMn"], "en-US", "fr-FR", "Hello", "Bonjour", "greeting_002"); // Add with context const memoryImport = await lara.memories.addTranslation( "mem_1A2b3C4d5E6f7G8h9I0jKl", "en-US", "fr-FR", "Hello", "Bonjour", "tuid", "sentenceBefore", "sentenceAfter" ); // TMX import from file const tmxFileStream = fs.createReadStream("/path/to/your/memory.tmx"); // Replace with actual TMX file path const memoryImport = await lara.memories.importTmx("mem_1A2b3C4d5E6f7G8h9I0jKl", tmxFileStream); // TMX import with a callback URL (notified when the import completes) const memoryImport = await lara.memories.importTmx( "mem_1A2b3C4d5E6f7G8h9I0jKl", tmxFileStream, "https://your-server.example.com/lara/import-callback" ); // Async memory export โ€” returns a jobId; the result is delivered to your callback URL when ready const { jobId } = await lara.memories.exportAsync( "mem_1A2b3C4d5E6f7G8h9I0jKl", "https://your-server.example.com/lara/export-callback", "tmx" // optional, defaults to the server-side default ("tmx" | "jtm") ); // Delete translation // Important: if you omit tuid, all entries that match the provided fields will be removed const deleteJob = await lara.memories.deleteTranslation( "mem_1A2b3C4d5E6f7G8h9I0jKl", "en-US", "fr-FR", "Hello", "Bonjour", tuid="greeting_001" ); // Wait for import completion const completedImport = await lara.memories.waitForImport(memoryImport, undefined, 300000); // 5 minutes // Share a memory with the whole account/team (optionally naming the shared copy) const teamShare = await lara.memories.addAccountShare("mem_1A2b3C4d5E6f7G8h9I0jKl", "Shared with the team"); // Rename the account/team share await lara.memories.renameAccountShare("mem_1A2b3C4d5E6f7G8h9I0jKl", "Team memory"); // Revoke the account/team share await lara.memories.revokeAccountShare("mem_1A2b3C4d5E6f7G8h9I0jKl"); // Share a memory with a specific group (optionally naming the shared copy) const groupShare = await lara.memories.addGroupShare("mem_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl", "Shared with the group"); // Rename the group share await lara.memories.renameGroupShare("mem_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing group"); // Revoke the group share await lara.memories.revokeGroupShare("mem_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl"); // List the shares available on a memory (account, group and user shares visible to the caller) const shares = await lara.memories.getShares("mem_1A2b3C4d5E6f7G8h9I0jKl"); if (shares.account) console.log(`Account ${shares.account.name}: ${shares.account.permissionMask}`); for (const group of shares.groups) console.log(`Group ${group.name}: ${group.permissionMask}`); for (const user of shares.users) console.log(`User ${user.name}: ${user.permissionMask}`); ``` ### ๐Ÿ“š Glossary Management ```javascript // Create glossary const glossary = await lara.glossaries.create("MyGlossary"); // listPaginated() supports optional name filtering and pagination. Called without options, // it returns the complete list of glossaries without pagination. Providing search, page, // or size enables pagination. const { items: glossaries, total: glossaryTotal } = await lara.glossaries.listPaginated(); // Providing page or size enables pagination (page starts at 1; size: 1-200). // The missing parameter defaults to page 1 or size 20. const glossaryPage = await lara.glossaries.listPaginated({ page: 2, size: 50 }); const glossaryDefaultSize = await lara.glossaries.listPaginated({ page: 2 }); // Page 2, 20 per page const glossaryFirstPage = await lara.glossaries.listPaginated({ size: 50 }); // Page 1, 50 per page // Pass search to filter by displayed name (case- and accent-insensitive). // It matches substrings and preserves spaces. // Combine search with page and size to paginate matching results. // If omitted, page defaults to 1 and size to 20. const glossarySearch = await lara.glossaries.listPaginated({ search: "Marketing", page: 2, size: 50 }); // list() is deprecated; use listPaginated() instead. // Import a glossary file (use "tbx" for TBX files) const glossaryFileStream = fs.createReadStream("/path/to/your/glossary.csv"); const glossaryImport = await lara.glossaries.importFile( "gls_1A2b3C4d5E6f7G8h9I0jKl", glossaryFileStream, { contentType: "csv/table-uni" } ); // Options are independent; contentType defaults to "csv/table-uni". // await lara.glossaries.importFile(glossary.id, glossaryFileStream, { callbackUrl }); // Check import status const importStatus = await lara.glossaries.getImportStatus(glossaryImport.id); // Wait for import completion const completedImport = await lara.glossaries.waitForImport(glossaryImport, undefined, 300000); // 5 minutes // Export glossary const csvData = await lara.glossaries.export("gls_1A2b3C4d5E6f7G8h9I0jKl", "csv/table-uni", "en-US"); // Async glossary export โ€” returns a jobId; the result is delivered to your callback URL when ready const { jobId } = await lara.glossaries.exportAsync( "gls_1A2b3C4d5E6f7G8h9I0jKl", "https://your-server.example.com/lara/export-callback", "csv/table-uni", "en-US" ); // Get glossary terms count const counts = await lara.glossaries.counts("gls_1A2b3C4d5E6f7G8h9I0jKl"); // Share with the whole account, rename the share, then list visible shares await lara.glossaries.addAccountShare("gls_1A2b3C4d5E6f7G8h9I0jKl", "Team glossary"); await lara.glossaries.renameAccountShare("gls_1A2b3C4d5E6f7G8h9I0jKl", "Company terminology"); const glossaryShares = await lara.glossaries.getShares("gls_1A2b3C4d5E6f7G8h9I0jKl"); // Share with a group, rename the share, and revoke it await lara.glossaries.addGroupShare("gls_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing glossary"); await lara.glossaries.renameGroupShare("gls_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing terminology"); await lara.glossaries.revokeGroupShare("gls_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl"); // Revoke the account share await lara.glossaries.revokeAccountShare("gls_1A2b3C4d5E6f7G8h9I0jKl"); ``` ### ๐Ÿ“˜ Styleguide Management ```javascript // Create styleguide const styleguide = await lara.styleguides.create( "MyStyleguide", "Use a formal tone. Prefer British English spelling. Avoid contractions." ); // listPaginated() supports optional name filtering and pagination. Called without options, // it returns the complete list of styleguides without pagination. Providing search, page, // or size enables pagination. const { items: styleguides, total: styleguideTotal } = await lara.styleguides.listPaginated(); // Providing page or size enables pagination (page starts at 1; size: 1-200). // The missing parameter defaults to page 1 or size 20. const styleguidePage = await lara.styleguides.listPaginated({ page: 2, size: 50 }); const styleguideDefaultSize = await lara.styleguides.listPaginated({ page: 2 }); // Page 2, 20 per page const styleguideFirstPage = await lara.styleguides.listPaginated({ size: 50 }); // Page 1, 50 per page // Pass search to filter by displayed name (case- and accent-insensitive). // It matches substrings and preserves spaces. // Combine search with page and size to paginate matching results. // If omitted, page defaults to 1 and size to 20. const styleguideSearch = await lara.styleguides.listPaginated({ search: "Marketing", page: 2, size: 50 }); // list() is deprecated; use listPaginated() instead. // Get a styleguide by ID (returns null if not found) const retrieved = await lara.styleguides.get("stg_1A2b3C4d5E6f7G8h9I0jKl"); // Update a styleguide โ€” pass undefined for fields you don't want to change // Update only the name const renamed = await lara.styleguides.update("stg_1A2b3C4d5E6f7G8h9I0jKl", "UpdatedName", undefined); // Update only the content const updatedContent = await lara.styleguides.update( "stg_1A2b3C4d5E6f7G8h9I0jKl", undefined, "Use a casual tone. Prefer American English spelling." ); // Update both name and content const updated = await lara.styleguides.update( "stg_1A2b3C4d5E6f7G8h9I0jKl", "FinalName", "Use clear and concise language. Avoid jargon." ); // Share with the whole account, rename the share, then list visible shares await lara.styleguides.addAccountShare("stg_1A2b3C4d5E6f7G8h9I0jKl", "Team styleguide"); await lara.styleguides.renameAccountShare("stg_1A2b3C4d5E6f7G8h9I0jKl", "Company styleguide"); const styleguideShares = await lara.styleguides.getShares("stg_1A2b3C4d5E6f7G8h9I0jKl"); // Share with a group, rename the share, and revoke it await lara.styleguides.addGroupShare("stg_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing styleguide"); await lara.styleguides.renameGroupShare("stg_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl", "Marketing guidelines"); await lara.styleguides.revokeGroupShare("stg_1A2b3C4d5E6f7G8h9I0jKl", "grp_1A2b3C4d5E6f7G8h9I0jKl"); // Revoke the account share await lara.styleguides.revokeAccountShare("stg_1A2b3C4d5E6f7G8h9I0jKl"); // Delete a styleguide await lara.styleguides.delete("stg_1A2b3C4d5E6f7G8h9I0jKl"); ``` ### Translation Options ```javascript const TranslateOptions = { adaptTo: ["mem_1A2b3C4d5E6f7G8h9I0jKl"], // Memory IDs to adapt to glossaries: ["gls_1A2b3C4d5E6f7G8h9I0jKl"], // Glossary IDs to use instructions: ["instruction"], // Translation instructions style: "fluid", // Translation style (fluid, faithful, creative) contentType: "text/plain", // Content type (text/plain, text/html, etc.) timeoutInMillis: 10000, // Request timeout in milliseconds sourceHint: "en", // Hint for source language detection noTrace: false, // Disable request tracing verbose: false, // Enable verbose response }; ``` ### Language Codes The SDK supports full language codes (e.g., `en-US`, `fr-FR`, `es-ES`) as well as simple codes (e.g., `en`, `fr`, `es`): ```javascript // Full language codes (recommended) const result = await lara.translate("Hello", "en-US", "fr-FR"); // Simple language codes const result = await lara.translate("Hello", "en", "fr"); ``` ### ๐ŸŒ Supported Languages The SDK supports all languages available in the Lara API. Use the `getLanguages()` method to get the current list: ```javascript const languages = await lara.getLanguages(); console.log("Supported languages: " + languages.join(', ')); ``` ## โš™๏ธ Configuration ### Error Handling The SDK provides detailed error information: ```javascript try { const result = await lara.translate("Hello", "en-US", "fr-FR"); console.log("Translation: " + result.translation); } catch (error) { if (error.constructor.name === 'LaraApiError') { console.error("API Error [" + error.statusCode + "]: " + error.message); console.error("Error type: " + error.type); } else { console.error("SDK Error: " + error.message); } } ``` ## ๐Ÿ“‹ Requirements - Node.js 12 or higher - npm or yarn - Valid Lara API credentials ## ๐Ÿงช Testing Run the examples to test your setup: ```bash # All examples use environment variables for credentials, so set them first: export LARA_ACCESS_KEY_ID="your-access-key-id" export LARA_ACCESS_KEY_SECRET="your-access-key-secret" ``` ```bash # Run basic text translation example cd examples node text_translation.js ``` ## ๐Ÿ“„ License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. Happy translating! ๐ŸŒโœจ