From 1ad699fcb11624622a63bea7d0434cd0e4f0feed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:18:09 +0000 Subject: [PATCH 1/2] Initial plan From 4a4379c9db85241197f12f630f9201753c207bad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:24:24 +0000 Subject: [PATCH 2/2] feat: add support for Pre-Translation Batch Operations Co-authored-by: andrii-bodnar <29282228+andrii-bodnar@users.noreply.github.com> --- src/translations/index.ts | 16 +++++++++++++++ tests/translations/api.test.ts | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/translations/index.ts b/src/translations/index.ts index 2378c3ff8..932da4fae 100644 --- a/src/translations/index.ts +++ b/src/translations/index.ts @@ -71,6 +71,19 @@ export class Translations extends CrowdinApi { return this.patch(url, request, this.defaultConfig()); } + /** + * @param projectId project identifier + * @param request request body + * @see https://developer.crowdin.com/api/v2/#tag/Translations/operation/api.projects.pre-translations.patchBatch + */ + editPreTranslations( + projectId: number, + request: PatchRequest[], + ): Promise>> { + const url = `${this.url}/projects/${projectId}/pre-translations`; + return this.patch(url, request, this.defaultConfig()); + } + /** * @param projectId project identifier * @param preTranslationId pre translation identifier @@ -389,12 +402,15 @@ export namespace TranslationsModel { skipApprovedTranslations: boolean; translateUntranslatedOnly: boolean; translateWithPerfectMatchOnly: boolean; + priority: Priority; } export type Method = 'tm' | 'mt' | 'ai'; export type AutoApproveOption = 'all' | 'exceptAutoSubstituted' | 'perfectMatchOnly' | 'none'; + export type Priority = 'low' | 'normal' | 'high'; + export type CharTransformation = 'asian' | 'european' | 'arabic' | 'cyrillic'; export interface Build { diff --git a/tests/translations/api.test.ts b/tests/translations/api.test.ts index c141c5a36..98ac5ebd0 100644 --- a/tests/translations/api.test.ts +++ b/tests/translations/api.test.ts @@ -93,6 +93,30 @@ describe('Translations API', () => { identifier: preTranslationId, }, }) + .patch( + `/projects/${projectId}/pre-translations`, + [ + { + op: 'replace', + path: `/${preTranslationId}/status`, + value: sampleStatus, + }, + ], + { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }, + ) + .reply(200, { + data: [ + { + data: { + identifier: preTranslationId, + }, + }, + ], + }) .get(`/projects/${projectId}/pre-translations/${preTranslationId}/report`, undefined, { reqheaders: { Authorization: `Bearer ${api.token}`, @@ -384,6 +408,18 @@ describe('Translations API', () => { expect(preTranslation.data.identifier).toBe(preTranslationId); }); + it('Edit Pre-translations (batch)', async () => { + const preTranslations = await api.editPreTranslations(projectId, [ + { + op: 'replace', + path: `/${preTranslationId}/status`, + value: sampleStatus, + }, + ]); + expect(preTranslations.data.length).toBe(1); + expect(preTranslations.data[0].data.identifier).toBe(preTranslationId); + }); + it('Get Pre-translation Report', async () => { const report = await api.getPreTranslationReport(projectId, preTranslationId); expect(report.data.languages.length).toBe(1);