Skip to content

feat(translate): validate source/target language codes#218

Merged
missuo merged 1 commit into
mainfrom
feat/validate-languages
May 22, 2026
Merged

feat(translate): validate source/target language codes#218
missuo merged 1 commit into
mainfrom
feat/validate-languages

Conversation

@missuo

@missuo missuo commented May 22, 2026

Copy link
Copy Markdown
Member

Summary

Previously `TranslateByDeepLX` silently mapped any caller-supplied code through `toOneshotLang()`, falling back to a lowercased pass-through for unknown codes. The oneshot endpoint responds 200 to unknown codes but echoes the source text back untranslated, so callers couldn't tell "translated, identical to source" from "language not supported".

This PR validates source/target codes strictly against the language table the extension bundles in background.js (`y` array for target-capable codes, `A` for the source-only EN/PT aliases) and returns HTTP 400 with a list of supported codes on mismatch.

Validation rules

input result
`target_lang`: empty `400 "target_lang is required"`
`target_lang`: "auto" `400 "target_lang cannot be \"auto\"; pick one of: ..."`
`target_lang`: unknown code `400 "unsupported target_lang \"XX\"; valid codes: ..."`
`source_lang`: empty / "auto" allowed, server autodetects
`source_lang`: unknown code `400 "unsupported source_lang \"ZZ\"; valid codes: ... (or \"auto\")"`
Case-insensitive — "de" and "DE" both resolve OK

Language table updates

Picked up codes the previous map missed:

  • `ES-419` (Latin American Spanish)
  • `HE` (Hebrew)
  • `VI` (Vietnamese)

Fixed the EN / PT source-lang mapping: the extension's `A` array maps both to the generic `langCodeForIta` ("en"/"pt"), not the regional default. As a target they continue to resolve to `en-US` / `pt-BR` for backward compat with callers that historically passed "EN" / "PT".

Full supported set now matches the extension exactly:
`AR, BG, CS, DA, DE, EL, EN, EN-GB, EN-US, ES, ES-419, ET, FI, FR, HE, HU, ID, IT, JA, KO, LT, LV, NB, NL, PL, PT, PT-BR, PT-PT, RO, RU, SK, SL, SV, TR, UK, VI, ZH, ZH-HANS, ZH-HANT`

Test plan

  • 5 valid codes (DE, ZH-HANT, HE, VI, ES-419) → 200 + translated text
  • Invalid target "XX" → 400, error message lists all 38 supported codes
  • Invalid source "ZZ" → 400, error message lists all 38 codes + "auto" hint
  • `target_lang: "auto"` → 400
  • Source autodetect (empty / "auto") + valid target → 200
  • Lowercase input "de" → 200 (case-insensitive)

Compat

  • HTTP shape unchanged on success; only the error path gains 400s where it previously returned 200 with echoed text.
  • `DeepLXTranslationResult` field set unchanged.
  • /v2/translate official-API compat preserved (the official DeepL API also returns 400 on unsupported `target_lang`).

Previously TranslateByDeepLX silently mapped any caller-supplied code
through toOneshotLang(), falling back to a lowercased pass-through for
unknown codes. The oneshot endpoint accepts unknown codes with a 200
but echoes the source text back untranslated, leaving callers to
distinguish "translated, identical to source" from "language not
supported" without a clear signal.

Validate strictly against the language table the extension bundles in
background.js (array `y` for target-capable codes, `A` for the
source-only EN / PT aliases) and return HTTP 400 with a list of
supported codes on mismatch. This also catches:

  - target_lang = ""        → "target_lang is required"
  - target_lang = "auto"    → "target_lang cannot be \"auto\"; pick one of: ..."
  - source_lang = ""/"auto" → allowed, server autodetects
  - case-insensitive       → strings.ToUpper before lookup

Pick up languages the previous map missed:

  + ES-419 (Latin American Spanish)
  + HE     (Hebrew)
  + VI     (Vietnamese)

Fix the EN / PT source-lang mapping: the extension's `A` array maps
both to the generic langCodeForIta ("en"/"pt"), not the regional
default. As a target they continue to resolve to en-US / pt-BR for
backward compat with callers that historically passed "EN" / "PT".

Verified end-to-end:
  - 5 valid codes (DE, ZH-HANT, HE, VI, ES-419) → 200 + translated text
  - Invalid target "XX"  → 400, message lists 38 supported codes
  - Invalid source "ZZ"  → 400, message lists 38 codes + "auto"
  - target_lang "auto"   → 400
  - source autodetect (empty / "auto") + valid target → 200
  - Lowercase input "de" → 200 (case-insensitive)
@missuo missuo merged commit 057387c into main May 22, 2026
3 checks passed
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.

1 participant