From e1aa636e91cae3bfb2e9bf30ab19b9cad866548c Mon Sep 17 00:00:00 2001 From: Yevheniy Oliynyk Date: Sun, 4 Sep 2022 15:27:37 +0300 Subject: [PATCH] API updates (#187) * added report settings template API methods * bundles api updates --- package-lock.json | 4 +- package.json | 2 +- src/bundles/index.ts | 1 + src/reports/index.ts | 104 ++++++++++++++++++++++++++++++-- tests/bundles/api.test.ts | 3 + tests/reports/api.test.ts | 121 +++++++++++++++++++++++++++++++++++++- 6 files changed, 227 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 22b066ec2..e739ab05a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@crowdin/crowdin-api-client", - "version": "1.19.0", + "version": "1.19.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@crowdin/crowdin-api-client", - "version": "1.19.0", + "version": "1.19.1", "license": "MIT", "dependencies": { "axios": "0.21.3" diff --git a/package.json b/package.json index ad96dba5e..759eb00cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@crowdin/crowdin-api-client", - "version": "1.19.0", + "version": "1.19.1", "description": "JavaScript library for Crowdin API v2.", "main": "out/index.js", "types": "out/index.d.ts", diff --git a/src/bundles/index.ts b/src/bundles/index.ts index 80fb702ce..012e76083 100644 --- a/src/bundles/index.ts +++ b/src/bundles/index.ts @@ -89,6 +89,7 @@ export namespace BundlesModel { } export interface CreateBundleRequest { + name: string; format: string; sourcePatterns: string[]; ignorePatterns?: string[]; diff --git a/src/reports/index.ts b/src/reports/index.ts index 3ff5e99a9..e3d157375 100644 --- a/src/reports/index.ts +++ b/src/reports/index.ts @@ -1,4 +1,12 @@ -import { CrowdinApi, DownloadLink, ResponseObject, Status } from '../core'; +import { + CrowdinApi, + DownloadLink, + PaginationOptions, + PatchRequest, + ResponseList, + ResponseObject, + Status, +} from '../core'; /** * Reports help to estimate costs, calculate translation costs, and identify the top members. @@ -110,6 +118,70 @@ export class Reports extends CrowdinApi { const url = `${this.url}/projects/${projectId}/reports/${reportId}/download`; return this.get(url, this.defaultConfig()); } + + /** + * @param projectId project identifier + * @param options optional parameters for the request + * @see https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.getMany + */ + listReportSettingsTemplates( + projectId: number, + options?: PaginationOptions, + ): Promise> { + const url = `${this.url}/projects/${projectId}/reports/settings-templates`; + return this.getList(url, options?.limit, options?.offset); + } + + /** + * @param projectId project identifier + * @param request request body + * @see https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.post + */ + addReportSettingsTemplate( + projectId: number, + request: Omit, + ): Promise> { + const url = `${this.url}/projects/${projectId}/reports/settings-templates`; + return this.post(url, request, this.defaultConfig()); + } + + /** + * @param projectId project identifier + * @param reportSettingsTemplateId report settings template identifier + * @see https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.get + */ + getReportSettingsTemplate( + projectId: number, + reportSettingsTemplateId: number, + ): Promise> { + const url = `${this.url}/projects/${projectId}/reports/settings-templates/${reportSettingsTemplateId}`; + return this.get(url, this.defaultConfig()); + } + + /** + * @param projectId project identifier + * @param reportSettingsTemplateId report settings template identifier + * @param request request body + * @see https://developer.crowdin.com/api/v2/#operation/api.projects.reports.settings-templates.patch + */ + editReportSettingsTemplate( + projectId: number, + reportSettingsTemplateId: number, + request: PatchRequest[], + ): Promise> { + const url = `${this.url}/projects/${projectId}/reports/settings-templates/${reportSettingsTemplateId}`; + return this.patch(url, request, this.defaultConfig()); + } + + /** + * @param projectId project identifier + * @param reportSettingsTemplateId report settings template identifier + * @see https://developer.crowdin.com/api/v2/#operation/api.projects.settings-templates.delete + */ + deleteReportSettingsTemplate(projectId: number, reportSettingsTemplateId: number): Promise { + const url = `${this.url}/projects/${projectId}/reports/settings-templates/${reportSettingsTemplateId}`; + return this.delete(url, this.defaultConfig()); + } } export namespace ReportsModel { @@ -135,8 +207,12 @@ export namespace ReportsModel { export interface ReportStatusAttributes { format: Format; reportName: string; - //TODO improve this type with unions and generics according to the documentation - schema: unknown; + schema: + | CostEstimateSchema + | CostEstimateFuzzyModeSchema + | TranslationCostSchema + | TopMembersSchema + | ContributionRawDataSchema; } export interface GroupTranslationCostSchema { @@ -209,6 +285,22 @@ export namespace ReportsModel { dateTo?: string; } + export interface ReportSettings { + id: number; + name: string; + currency: Currency; + unit: Unit; + mode: 'fuzzy' | 'simple'; + config: ReportSettinsConfig; + createdAt: string; + updatedAt: string; + } + + export interface ReportSettinsConfig { + regularRates: RegularRate[]; + individualRates: UsersIndividualRate[]; + } + export type Unit = 'strings' | 'words' | 'chars' | 'chars_with_spaces'; export type Currency = @@ -256,12 +348,16 @@ export namespace ReportsModel { value: number; } + export interface UsersIndividualRate extends IndividualRate { + userIds: number[]; + } + export interface IndividualRate { languageIds: string[]; rates: RegularRate[]; } - export type Mode = 'no_match' | 'tm_match' | 'approval'; + export type Mode = 'no_match' | 'tm_match' | 'approval' | '99-95' | '94-90' | '89-80' | 'perfect' | '100'; export type ContributionMode = 'translations' | 'approvals' | 'votes'; diff --git a/tests/bundles/api.test.ts b/tests/bundles/api.test.ts index dd5cb4751..07eda890a 100644 --- a/tests/bundles/api.test.ts +++ b/tests/bundles/api.test.ts @@ -11,6 +11,7 @@ describe('Bundles API', () => { const projectId = 2; const bundleId = 3; const fileId = 4; + const name = 'test'; const format = 'crowdin-resx'; const exportPattern = 'strings-%two_letter_code%.resx'; @@ -40,6 +41,7 @@ describe('Bundles API', () => { `/projects/${projectId}/bundles`, { format, + name, sourcePatterns: [], exportPattern, }, @@ -125,6 +127,7 @@ describe('Bundles API', () => { const bundle = await api.addBundle(projectId, { exportPattern, format, + name, sourcePatterns: [], }); expect(bundle.data.id).toBe(bundleId); diff --git a/tests/reports/api.test.ts b/tests/reports/api.test.ts index 1ff8cdb00..8e803b938 100644 --- a/tests/reports/api.test.ts +++ b/tests/reports/api.test.ts @@ -23,6 +23,13 @@ describe('Reports API', () => { groupBy: 'language', projectIds: [projectId], }; + const reportSettingsTemplateId = 234; + const currency: ReportsModel.Currency = 'USD'; + const unit: ReportsModel.Unit = 'words'; + const config: ReportsModel.ReportSettinsConfig = { + individualRates: [], + regularRates: [], + }; beforeAll(() => { scope = nock(api.url) @@ -136,7 +143,81 @@ describe('Reports API', () => { data: { url: downloadLink, }, - }); + }) + .get(`/projects/${projectId}/reports/settings-templates`, undefined, { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }) + .reply(200, { + data: [ + { + data: { + id: reportSettingsTemplateId, + }, + }, + ], + pagination: { + offset: 0, + limit: 1, + }, + }) + .post( + `/projects/${projectId}/reports/settings-templates`, + { + name: reportName, + currency, + unit, + mode: 'simple', + config, + }, + { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }, + ) + .reply(200, { + data: { + id: reportSettingsTemplateId, + }, + }) + .get(`/projects/${projectId}/reports/settings-templates/${reportSettingsTemplateId}`, undefined, { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }) + .reply(200, { + data: { + id: reportSettingsTemplateId, + }, + }) + .patch( + `/projects/${projectId}/reports/settings-templates/${reportSettingsTemplateId}`, + [ + { + value: reportName, + op: 'replace', + path: '/name', + }, + ], + { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }, + ) + .reply(200, { + data: { + id: reportSettingsTemplateId, + }, + }) + .delete(`/projects/${projectId}/reports/settings-templates/${reportSettingsTemplateId}`, undefined, { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }) + .reply(200); }); afterAll(() => { @@ -196,4 +277,42 @@ describe('Reports API', () => { const downloadUrl = await api.downloadReport(projectId, reportId); expect(downloadUrl.data.url).toBe(downloadLink); }); + + it('List Report Settings Templates', async () => { + const templates = await api.listReportSettingsTemplates(projectId); + expect(templates.data.length).toBe(1); + expect(templates.data[0].data.id).toBe(reportSettingsTemplateId); + expect(templates.pagination.limit).toBe(1); + }); + + it('Add Report Settings Template', async () => { + const template = await api.addReportSettingsTemplate(projectId, { + config, + currency, + mode: 'simple', + name: reportName, + unit, + }); + expect(template.data.id).toBe(reportSettingsTemplateId); + }); + + it('Get Report Settings Template', async () => { + const template = await api.getReportSettingsTemplate(projectId, reportSettingsTemplateId); + expect(template.data.id).toBe(reportSettingsTemplateId); + }); + + it('Edit Report Settings Template', async () => { + const template = await api.editReportSettingsTemplate(projectId, reportSettingsTemplateId, [ + { + op: 'replace', + path: '/name', + value: reportName, + }, + ]); + expect(template.data.id).toBe(reportSettingsTemplateId); + }); + + it('Delete Report Settings Template', async () => { + await api.deleteReportSettingsTemplate(projectId, reportSettingsTemplateId); + }); });