Skip to content

feat(translate): add Lionbridge translation connector - #656

Open
markdaugherty wants to merge 15 commits into
adobe:mainfrom
markdaugherty:lionbridge-connector
Open

feat(translate): add Lionbridge translation connector#656
markdaugherty wants to merge 15 commits into
adobe:mainfrom
markdaugherty:lionbridge-connector

Conversation

@markdaugherty

@markdaugherty markdaugherty commented Aug 11, 2026

Copy link
Copy Markdown
Member

Summary

  • New Lionbridge translation connector (nx/blocks/loc/connectors/lionbridge/)
  • Full isConnected/connect/sendAllLanguages/getStatusAll/saveItems implementation against Lionbridge's Content API v2

Compliance with Lionbridge's dev guidelines

  • Retry 429/503 with exponential backoff, honoring Retry-After
  • jobName/requestName truncated to the 250-byte limit
  • Per org/site/env connector GUID generated and persisted (in .da/translate.json), prefixed onto connectorName
  • Calls approve after a successful download/save (REVIEW_TRANSLATIONTRANSLATION_APPROVED)
  • No cancelTranslation export — guidelines prohibit connector-initiated cancellation

Shared connector cleanup

Extracted duplicated logic across all translation connectors into nx/blocks/loc/utils/:

  • downloadQueue.js — the Queue+poll pattern, previously copy-pasted in every connector's saveItems
  • auth.js — da-etc login/token-cache flow shared by Trados and Lionbridge; both per-connector auth.js files deleted; fixed Trados never sending ?env=; resolves the da-etc origin via the shared DA_ETC export (env-override support via ?da-etc=) instead of a hardcoded URL
  • fetchWithRetry.js — shared retry/backoff, replacing an inline copy; GLaaS/Smartling/Trados updated to use it

Tests

  • Full coverage for the connector (sendAllLanguages/getStatusAll/saveItems/connect/GUID generation/statusFor) at parity with Trados/Smartling
  • test/loc/utils/auth.test.js, test/loc/utils/fetchWithRetry.test.js
  • npm test and lint pass
  • Verified end-to-end against real Lionbridge staging APIs and the real DA Translate app UI

Documentation

Lionbridge was missing from the public docs.da.live connector documentation. Draft updates pending publish:

Dependency

  • Can't authenticate against a real Lionbridge account until da-sites/da-etc#2 merges

ravuthu and others added 2 commits August 10, 2026 11:22
Builds on the initial connector implementation (adobe#651) with fixes found
via live testing against Lionbridge's Content API v2:

- providerId must be sent on job submit, not job creation (the API
  silently drops it on POST /jobs; submit fails without it)
- retrievefile needs Accept: application/octet-stream, not the default
  application/json (403s otherwise); other endpoints are unaffected
- add rate-limit handling (429/503 retry with exponential backoff,
  honoring Retry-After) per Lionbridge's dev guidelines
- truncate jobName/requestName to the 250-byte guideline limit
- generate and persist a per org/site/env connector GUID, prefixed onto
  connectorName per Lionbridge's connector-fingerprinting guideline
- call the approve endpoint after a successful download/save, closing
  out the request in Lionbridge's review workflow
- fix auth.js to resolve the da-etc origin via the shared DA_ETC export
  (with env-override support) instead of a hardcoded URL
- add test coverage for auth.js, connectorGuid.js, and the full
  sendAllLanguages/getStatusAll/saveItems flow (previously only
  statusFor had tests)

Verified end-to-end against real Lionbridge staging APIs and, separately,
through the actual DA Translate app UI against a real test site
(scdemos/lionbridge-demo).
- Add JSDoc to every function in index.js, auth.js, and connectorGuid.js
  that was missing it.
- CONNECTOR_NAME is now "DA Live Localization for Lionbridge" instead of
  the generic "DA Live Localization", to distinguish it from connectors
  for other vendors in Lionbridge's own job/connector listings.
@markdaugherty
markdaugherty marked this pull request as ready for review August 11, 2026 17:58
Mark Daugherty added 2 commits August 11, 2026 15:16
…copy

Extracted while fixing the same class of issue in the Smartling
connector (429s during batch jobs) — rather than maintain two nearly
identical retry/backoff implementations, both now share
nx/blocks/loc/utils/fetchWithRetry.js. Passes an explicit RETRY_CONFIG
(maxRetries: 3, maxDelayMs: 8000, 429/503 only) to preserve this
connector's existing tuning exactly; behavior is unchanged.
Mark Daugherty and others added 5 commits August 24, 2026 11:32
Audited all 5 loc connectors for duplicate code before extracting
anything; two candidates were genuinely duplicated and safe to merge.

- nx/blocks/loc/utils/downloadQueue.js: the Queue + setInterval
  poll-until-every-url-has-status pattern was identical across all 4
  real connectors' saveItems. Each now ends with one call instead of
  ~15 duplicated lines.

- nx/blocks/loc/utils/auth.js: Trados's and Lionbridge's auth.js were
  near-verbatim duplicates of the same da-etc login/token-cache flow.
  Consolidated into a single module exporting getAccessToken/authReady
  keyed by connector name; deleted both per-connector auth.js files
  entirely since they'd shrunk to trivial delegations. Along the way,
  merged LOGIN_ORIGIN onto the DA_ETC-aware definition (giving Trados a
  local-dev override it didn't have) and confirmed against da-etc's own
  routes/ints.js that including ?env= is correct for both connectors,
  not just Lionbridge (Trados previously never sent it).

Left alone: Smartling/GLaaS's auth (fundamentally different flows),
Trados/GLaaS's CORS-proxy-wrapper duplication, and GLaaS's partial
overlap with the shared dnt.js helpers - flagged, not extracted here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mhaack mhaack changed the title fix: lionbridge connector correctness/compliance fixes + test parity fix(translate): lionbridge connector correctness/compliance fixes + test parity Aug 28, 2026
export async function getStatusAll({ service, langs, urls, actions }) {
const { sendMessage, saveState } = actions;

const jobId = langs[0]?.translation?.jobId;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes every language belongs to the first language’s job. Waiting/dependent languages are submitted as separate Lionbridge jobs, so requests from those jobs are never fetched and those languages remain in progress. Please group languages by translation.jobId, fetch requests for each job, and calculate status only for that job’s languages.

// (REVIEW_TRANSLATION -> TRANSLATION_APPROVED). Failure here doesn't
// affect the already-successful download/save.
try {
await approveRequest(service, jobId, requestId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saveFn() can resolve after a failed DA write while setting url.status = "error". This still approves the Lionbridge request, incorrectly signaling successful delivery and potentially closing its review workflow. Please call approveRequest() only after the save reports explicit success (for example, url.status === "success" or a successful return value).

Mark Daugherty and others added 4 commits August 28, 2026 13:52
… follow-up jobs

- getStatusAll now groups langs by translation.jobId and fetches/applies
  status per job, instead of applying a single job's requests to every lang
- Fixes status computation once a waitingFor language is submitted in its
  own follow-up job with a different jobId than the initial batch
- Add a test covering status computed independently per job

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- saveItems now checks url.status === 'success' before calling
  approveRequest, avoiding approval when saveFn failed to persist content
- Add a test covering the skipped-approval case

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@markdaugherty markdaugherty changed the title fix(translate): lionbridge connector correctness/compliance fixes + test parity feat(translate): add Lionbridge translation connector Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants