Skip to content

Commit d7449fb

Browse files
authored
feat: new import translations api (#606)
* feat: new import translations api * fix
1 parent ded9604 commit d7449fb

File tree

2 files changed

+239
-4
lines changed

2 files changed

+239
-4
lines changed

src/translations/index.ts

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ export class Translations extends CrowdinApi {
172172
}
173173

174174
/**
175+
* @deprecated
176+
*
175177
* @param projectId project identifier
176178
* @param languageId language identifier
177179
* @param request request body
@@ -186,6 +188,9 @@ export class Translations extends CrowdinApi {
186188
return this.post(url, request, this.defaultConfig());
187189
}
188190

191+
/**
192+
* @deprecated
193+
*/
189194
uploadTranslationStrings(
190195
projectId: number,
191196
languageId: string,
@@ -237,6 +242,61 @@ export class Translations extends CrowdinApi {
237242
const url = `${this.url}/projects/${projectId}/translations/exports`;
238243
return this.post(url, request, this.defaultConfig());
239244
}
245+
246+
/**
247+
* @param projectId project identifier
248+
* @param request request body
249+
* @see https://support.crowdin.com/developer/api/v2/#tag/Translations/operation/api.projects.translations.imports
250+
*/
251+
importTranslations(
252+
projectId: number,
253+
request: TranslationsModel.ImportTranslationsRequest | TranslationsModel.ImportTranslationsStringsRequest,
254+
): Promise<
255+
ResponseObject<
256+
Status<
257+
| TranslationsModel.ImportTranslationsStatusAttributes
258+
| TranslationsModel.ImportTranslationsStringsStatusAttributes
259+
>
260+
>
261+
> {
262+
const url = `${this.url}/projects/${projectId}/translations/imports`;
263+
return this.post(url, request, this.defaultConfig());
264+
}
265+
266+
/**
267+
* @param projectId project identifier
268+
* @param importId import identifier
269+
* @see https://support.crowdin.com/developer/api/v2/#tag/Translations/operation/api.projects.translations.imports.get
270+
*/
271+
importTranslationsStatus(
272+
projectId: number,
273+
importId: string,
274+
): Promise<
275+
ResponseObject<
276+
Status<
277+
| TranslationsModel.ImportTranslationsStatusAttributes
278+
| TranslationsModel.ImportTranslationsStringsStatusAttributes
279+
>
280+
>
281+
> {
282+
const url = `${this.url}/projects/${projectId}/translations/imports/${importId}`;
283+
return this.get(url, this.defaultConfig());
284+
}
285+
286+
/**
287+
* @param projectId project identifier
288+
* @param importId import identifier
289+
* @see https://support.crowdin.com/developer/api/v2/#tag/Translations/operation/api.projects.translations.imports.report.get
290+
*/
291+
importTranslationsReport(
292+
projectId: number,
293+
importId: string,
294+
): Promise<
295+
ResponseObject<TranslationsModel.ImportTranslationsReport | TranslationsModel.ImportTranslationsStringsReport>
296+
> {
297+
const url = `${this.url}/projects/${projectId}/translations/imports/${importId}/report`;
298+
return this.get(url, this.defaultConfig());
299+
}
240300
}
241301

242302
export namespace TranslationsModel {
@@ -447,7 +507,7 @@ export namespace TranslationsModel {
447507
}
448508

449509
export interface TargetLanguageFile {
450-
id: string;
510+
id: number;
451511
statistics: TargetLanguageFileStatistics;
452512
}
453513

@@ -459,4 +519,101 @@ export namespace TranslationsModel {
459519
export interface SkippedInfo {
460520
[key: string]: any;
461521
}
522+
523+
/* Import Translations START */
524+
525+
export interface ImportTranslationsRequest {
526+
storageId: number;
527+
languageIds?: string[];
528+
fileId?: number;
529+
importEqSuggestions?: boolean;
530+
autoApproveImported?: boolean;
531+
translateHidden?: boolean;
532+
addToTm?: boolean;
533+
}
534+
535+
export interface ImportTranslationsStringsRequest {
536+
storageId: number;
537+
languageIds?: string[];
538+
branchId: number;
539+
importEqSuggestions?: boolean;
540+
autoApproveImported?: boolean;
541+
translateHidden?: boolean;
542+
addToTm?: boolean;
543+
importOptions?: {
544+
scheme?: {
545+
none?: number;
546+
identifier?: number;
547+
sourceOrTranslation?: number;
548+
translation?: number;
549+
[languageCode: string]: number | undefined;
550+
};
551+
};
552+
}
553+
554+
export interface ImportTranslationsStatusAttributes {
555+
storageId: number;
556+
fileId: number;
557+
importEqSuggestions: boolean;
558+
autoApproveImported: boolean;
559+
translateHidden: boolean;
560+
addToTm: boolean;
561+
languageIds: string[];
562+
}
563+
564+
export interface ImportTranslationsStringsStatusAttributes {
565+
storageId: number;
566+
branchId: number;
567+
importEqSuggestions: boolean;
568+
autoApproveImported: boolean;
569+
translateHidden: boolean;
570+
addToTm: boolean;
571+
languageIds: string[];
572+
}
573+
574+
export interface ImportTranslationsReport {
575+
languages: {
576+
id: string;
577+
files: {
578+
id: number;
579+
statistics: {
580+
phrases: number;
581+
words: number;
582+
};
583+
}[];
584+
skipped: {
585+
translationEqSource: number;
586+
hiddenStrings: number;
587+
qaCheck: number;
588+
};
589+
skippedQaCheckCategories: {
590+
size: number;
591+
duplicate: number;
592+
};
593+
}[];
594+
}
595+
596+
export interface ImportTranslationsStringsReport {
597+
languages: {
598+
id: string;
599+
branches: {
600+
id: number;
601+
statistics: {
602+
phrases: number;
603+
words: number;
604+
};
605+
}[];
606+
skipped: {
607+
translationEqSource: number;
608+
hiddenStrings: number;
609+
qaCheck: number;
610+
};
611+
skippedQaCheckCategories: {
612+
size: number;
613+
duplicate: number;
614+
};
615+
}[];
616+
}
617+
618+
/* Import Translations END */
462619
}

tests/translations/api.test.ts

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as nock from 'nock';
2-
import { Credentials, Translations } from '../../src';
2+
import { Credentials, Translations, TranslationsModel } from '../../src';
33

44
describe('Translations API', () => {
55
let scope: nock.Scope;
@@ -22,6 +22,7 @@ describe('Translations API', () => {
2222
const sampleLabelIds = [101, 102];
2323
const sampleExcludeLabelIds = [103, 104];
2424
const sampleStatus = 'canceled';
25+
const importId = '123';
2526

2627
const limit = 25;
2728

@@ -104,7 +105,7 @@ describe('Translations API', () => {
104105
id: languageId,
105106
files: [
106107
{
107-
id: fileId.toString(),
108+
id: fileId,
108109
statistics: {
109110
phrases: 10,
110111
words: 25,
@@ -264,6 +265,58 @@ describe('Translations API', () => {
264265
url: url,
265266
},
266267
})
268+
.post(
269+
`/projects/${projectId}/translations/imports`,
270+
{
271+
storageId: storageId,
272+
languageIds: [languageId],
273+
fileId: fileId,
274+
},
275+
{
276+
reqheaders: {
277+
Authorization: `Bearer ${api.token}`,
278+
},
279+
},
280+
)
281+
.reply(200, {
282+
data: {
283+
identifier: importId,
284+
},
285+
})
286+
.get(`/projects/${projectId}/translations/imports/${importId}`, undefined, {
287+
reqheaders: {
288+
Authorization: `Bearer ${api.token}`,
289+
},
290+
})
291+
.reply(200, {
292+
data: {
293+
identifier: importId,
294+
},
295+
})
296+
.get(`/projects/${projectId}/translations/imports/${importId}/report`, undefined, {
297+
reqheaders: {
298+
Authorization: `Bearer ${api.token}`,
299+
},
300+
})
301+
.reply(200, {
302+
data: {
303+
languages: [
304+
{
305+
id: languageId,
306+
files: [
307+
{
308+
id: fileId,
309+
statistics: {
310+
phrases: 10,
311+
words: 25,
312+
},
313+
},
314+
],
315+
skipped: {},
316+
},
317+
],
318+
},
319+
})
267320
.post(
268321
`/projects/${projectId}/pre-translations`,
269322
{
@@ -336,7 +389,7 @@ describe('Translations API', () => {
336389
expect(report.data.languages.length).toBe(1);
337390
expect(report.data.languages[0].id).toBe(languageId);
338391
expect(report.data.languages[0].files.length).toBe(1);
339-
expect(report.data.languages[0].files[0].id).toBe(fileId.toString());
392+
expect(report.data.languages[0].files[0].id).toBe(fileId);
340393
expect(report.data.languages[0].files[0].statistics.phrases).toBe(10);
341394
expect(report.data.languages[0].files[0].statistics.words).toBe(25);
342395
expect(report.data.preTranslateType).toBe('ai');
@@ -410,4 +463,29 @@ describe('Translations API', () => {
410463
});
411464
expect(res.data.url).toBe(url);
412465
});
466+
467+
it('Import Translations', async () => {
468+
const res = await api.importTranslations(projectId, {
469+
storageId: storageId,
470+
languageIds: [languageId],
471+
fileId: fileId,
472+
});
473+
expect(res.data.identifier).toBe(importId);
474+
});
475+
476+
it('Check Import Translations Status', async () => {
477+
const status = await api.importTranslationsStatus(projectId, importId);
478+
expect(status.data.identifier).toBe(importId);
479+
});
480+
481+
it('Get Import Translations Report', async () => {
482+
const report = await api.importTranslationsReport(projectId, importId);
483+
const data = report.data as TranslationsModel.ImportTranslationsReport;
484+
expect(data.languages.length).toBe(1);
485+
expect(data.languages[0].id).toBe(languageId);
486+
expect(data.languages[0].files.length).toBe(1);
487+
expect(data.languages[0].files[0].id).toBe(fileId);
488+
expect(data.languages[0].files[0].statistics.phrases).toBe(10);
489+
expect(data.languages[0].files[0].statistics.words).toBe(25);
490+
});
413491
});

0 commit comments

Comments
 (0)