From 4a2f8b8d4685ebd868e2d2a0e98cf41762197439 Mon Sep 17 00:00:00 2001 From: Kateryna Oblakevych Date: Mon, 26 Oct 2026 19:26:12 -0700 Subject: [PATCH 1/2] feat: update bundles, webhooks, fields, string comments and other APIs to the latest docs Fixes: - OrganizationWebhooksApi.listWebhooks/addWebhook used a relative "/webhooks" URL without the base URL and failed at runtime - webhooks.Event: add file.qa.finished, project.qa.finished, project.built, preTranslation.completed and task.updated - webhook `headers` returned as [] is read as null instead of failing - fields.EntityType: add TERM and CONCEPT - FieldsApi: add getFieldById returning a single field; deprecate getField, whose list return type doesn't match the API New fields and params: - Bundle/AddBundleRequest: sourceLanguageExportPattern, labelMatchRule, excludeLabelMatchRule, languageIds - Language.bcp47Code; Client.webUrl; Vendor.webUrl; StyleGuide/AddStyleGuideRequest.groupId - StringComment: projectId, resolverId, resolver, resolvedAt, fileId, file, isShared, senderOrganization, resolverOrganization; AddStringCommentRequest: fileId, isShared - Issue: user, string - fields Config: minValue/maxValue as numbers (min/max deprecated) - custom_mt credentials for machine translation engines - query params: fileId for listStringComments, denormalizePlaceholders for getCorrection, createdAfter/createdBefore for listUserSecurityLogs Deprecations: BundleExport.eta, AddStringCommentRequest.issueStatus. Javadoc: fixed the notifications and string corrections operation links. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../crowdin/client/bundles/BundlesApi.java | 14 +++++ .../bundles/model/AddBundleRequest.java | 4 ++ .../crowdin/client/bundles/model/Bundle.java | 4 ++ .../client/bundles/model/BundleExport.java | 4 ++ .../client/bundles/model/LabelMatchRule.java | 17 +++++ .../crowdin/client/clients/model/Client.java | 1 + .../com/crowdin/client/fields/FieldsApi.java | 33 ++++++++-- .../crowdin/client/fields/model/Config.java | 63 +++++++++++++++++++ .../client/fields/model/enums/EntityType.java | 4 +- .../crowdin/client/issues/model/Issue.java | 29 +++++++++ .../client/languages/model/Language.java | 1 + .../model/CustomMtTranslateCredentials.java | 12 ++++ .../notifications/NotificationsApi.java | 3 +- .../client/securitylogs/SecurityLogsApi.java | 20 ++++++ .../stringcomments/StringCommentsApi.java | 21 +++++++ .../model/AddStringCommentRequest.java | 12 ++++ .../stringcomments/model/StringComment.java | 38 +++++++++++ .../StringCorrectionsApi.java | 31 ++++++--- .../client/styleguide/StyleGuidesApi.java | 8 +++ .../model/AddStyleGuideRequest.java | 4 ++ .../model/ListStyleGuidesParams.java | 2 + .../client/styleguide/model/StyleGuide.java | 4 ++ .../crowdin/client/vendors/model/Vendor.java | 1 + .../webhooks/OrganizationWebhooksApi.java | 6 +- .../crowdin/client/webhooks/model/Event.java | 4 +- .../webhooks/model/OrganizationWebhook.java | 3 + .../client/webhooks/model/Webhook.java | 3 + .../client/bundles/BundlesApiTest.java | 8 +++ .../client/clients/ClientsApiTest.java | 1 + .../crowdin/client/fields/FieldsApiTest.java | 59 +++++++++++++++++ .../crowdin/client/issues/IssuesApiTest.java | 8 +++ .../client/languages/LanguagesApiTest.java | 2 + .../MachineTranslationEnginesApiTest.java | 14 +++++ .../client/securitylogs/SecurityLogsTest.java | 14 +++++ .../stringcomments/StringCommentsApiTest.java | 57 ++++++++++++++++- .../bundles/StringCorrectionsApiTest.java | 11 ++++ .../client/styleguide/StyleGuidesApiTest.java | 2 + .../client/vendors/VendorsApiTest.java | 1 + .../webhooks/OrganizationWebhooksApiTest.java | 5 +- .../client/webhooks/WebhooksApiTest.java | 31 +++++++++ .../api/bundles/addBundleRequest.json | 9 ++- src/test/resources/api/bundles/bundle.json | 7 +++ .../resources/api/clients/listClients.json | 3 +- .../api/fields/fieldsNumberRequest.json | 19 ++++++ .../api/fields/fieldsNumberResponse.json | 25 ++++++++ src/test/resources/api/issues/issue.json | 15 +++++ .../resources/api/languages/language.json | 1 + .../api/languages/listLanguages.json | 1 + .../addMtCustom.json | 7 +++ .../stringcomments/addFileCommentRequest.json | 7 +++ .../stringcomments/fileCommentResponse.json | 31 +++++++++ .../listFileCommentsResponse.json | 34 ++++++++++ .../stringcomments/stringCommentResponse.json | 18 ++++++ .../api/styleguide/addStyleGuideRequest.json | 1 + .../resources/api/styleguide/styleGuide.json | 1 + .../resources/api/vendors/listVendors.json | 3 +- .../webhooks/addWebhookRequestNewEvents.json | 12 ++++ .../api/webhooks/webhookNewEvents.json | 23 +++++++ 58 files changed, 749 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/crowdin/client/bundles/model/LabelMatchRule.java create mode 100644 src/main/java/com/crowdin/client/machinetranslationengines/model/CustomMtTranslateCredentials.java create mode 100644 src/test/resources/api/fields/fieldsNumberRequest.json create mode 100644 src/test/resources/api/fields/fieldsNumberResponse.json create mode 100644 src/test/resources/api/machinetranslationengines/addMtCustom.json create mode 100644 src/test/resources/api/stringcomments/addFileCommentRequest.json create mode 100644 src/test/resources/api/stringcomments/fileCommentResponse.json create mode 100644 src/test/resources/api/stringcomments/listFileCommentsResponse.json create mode 100644 src/test/resources/api/webhooks/addWebhookRequestNewEvents.json create mode 100644 src/test/resources/api/webhooks/webhookNewEvents.json diff --git a/src/main/java/com/crowdin/client/bundles/BundlesApi.java b/src/main/java/com/crowdin/client/bundles/BundlesApi.java index 5a0f8879e..213e036b5 100644 --- a/src/main/java/com/crowdin/client/bundles/BundlesApi.java +++ b/src/main/java/com/crowdin/client/bundles/BundlesApi.java @@ -44,6 +44,15 @@ public ResponseList listBundles(Long projectId) throws HttpException, Ht return listBundles(projectId, new Pagination()); } + /** + * @param projectId project identifier + * @param options pagination options (limit, offset) + * @return list of bundles + * @see + */ public ResponseList listBundles(Long projectId, Pagination options) throws HttpException, HttpBadRequestException { Map> queryParams = HttpRequestConfig.buildUrlParams( "limit", Optional.ofNullable(options.getLimit()), @@ -133,6 +142,11 @@ public ResponseList listBundleFiles(Long projectId, Long bun * @param bundleId bundle identifier * @param limit maximum number of items to retrieve (default 25) * @param offset starting offset in the collection (default 0) + * @return list of bundle branches + * @see */ public ResponseList listBundleBranches(Long projectId, Long bundleId, Integer limit, Integer offset) throws HttpException, HttpBadRequestException { Map> queryParams = HttpRequestConfig.buildUrlParams( diff --git a/src/main/java/com/crowdin/client/bundles/model/AddBundleRequest.java b/src/main/java/com/crowdin/client/bundles/model/AddBundleRequest.java index 8f8e607c6..9cfbfc5d6 100644 --- a/src/main/java/com/crowdin/client/bundles/model/AddBundleRequest.java +++ b/src/main/java/com/crowdin/client/bundles/model/AddBundleRequest.java @@ -13,7 +13,11 @@ public class AddBundleRequest { private String exportPattern; private Boolean isMultilingual; private Boolean includeProjectSourceLanguage; + private String sourceLanguageExportPattern; private Boolean includeInContextPseudoLanguage; private List labelIds; private List excludeLabelIds; + private LabelMatchRule labelMatchRule; + private LabelMatchRule excludeLabelMatchRule; + private List languageIds; } diff --git a/src/main/java/com/crowdin/client/bundles/model/Bundle.java b/src/main/java/com/crowdin/client/bundles/model/Bundle.java index 980b06841..93396d257 100644 --- a/src/main/java/com/crowdin/client/bundles/model/Bundle.java +++ b/src/main/java/com/crowdin/client/bundles/model/Bundle.java @@ -17,8 +17,12 @@ public class Bundle { private boolean isMultilingual; private Boolean includeProjectSourceLanguage; private Boolean includeInContextPseudoLanguage; + private String sourceLanguageExportPattern; + private LabelMatchRule labelMatchRule; + private LabelMatchRule excludeLabelMatchRule; private List labelIds; private List excludeLabelIds; + private List languageIds; private String webUrl; private Date createdAt; private Date updatedAt; diff --git a/src/main/java/com/crowdin/client/bundles/model/BundleExport.java b/src/main/java/com/crowdin/client/bundles/model/BundleExport.java index 45b6ff587..053463a6e 100644 --- a/src/main/java/com/crowdin/client/bundles/model/BundleExport.java +++ b/src/main/java/com/crowdin/client/bundles/model/BundleExport.java @@ -15,6 +15,10 @@ public class BundleExport { private Date updatedAt; private Date startedAt; private Date finishedAt; + /** + * @deprecated deprecated in the API, may be removed in the future + */ + @Deprecated private String eta; } \ No newline at end of file diff --git a/src/main/java/com/crowdin/client/bundles/model/LabelMatchRule.java b/src/main/java/com/crowdin/client/bundles/model/LabelMatchRule.java new file mode 100644 index 000000000..4dafcad65 --- /dev/null +++ b/src/main/java/com/crowdin/client/bundles/model/LabelMatchRule.java @@ -0,0 +1,17 @@ +package com.crowdin.client.bundles.model; + +import com.crowdin.client.core.model.EnumConverter; + +public enum LabelMatchRule implements EnumConverter { + + ALL, ANY; + + public static LabelMatchRule from(String value) { + return LabelMatchRule.valueOf(value.toUpperCase()); + } + + @Override + public Object to(LabelMatchRule v) { + return v.name().toLowerCase(); + } +} diff --git a/src/main/java/com/crowdin/client/clients/model/Client.java b/src/main/java/com/crowdin/client/clients/model/Client.java index 2b6dc69e1..1a372a010 100644 --- a/src/main/java/com/crowdin/client/clients/model/Client.java +++ b/src/main/java/com/crowdin/client/clients/model/Client.java @@ -9,4 +9,5 @@ public class Client { private String name; private String description; private Status status; + private String webUrl; } diff --git a/src/main/java/com/crowdin/client/fields/FieldsApi.java b/src/main/java/com/crowdin/client/fields/FieldsApi.java index f6f71ef21..77d7cb738 100644 --- a/src/main/java/com/crowdin/client/fields/FieldsApi.java +++ b/src/main/java/com/crowdin/client/fields/FieldsApi.java @@ -30,9 +30,9 @@ public FieldsApi(Credentials credentials, ClientConfig clientConfig) { * @param search Search fields by slug or name * @param limit maximum number of items to retrieve (default 25) * @param offset starting offset in the collection (default 0) - * @return list of distributions + * @return list of fields * @see */ public ResponseList listFields(String entity, String search, Integer limit, Integer offset) throws HttpException, HttpBadRequestException { @@ -44,6 +44,13 @@ public ResponseList listFields(String entity, String search, Integer limi return listFields(params); } + /** + * @param params query parameters (entity, search, type, limit, offset) + * @return list of fields + * @see + */ public ResponseList listFields(ListFieldsParams params) throws HttpException, HttpBadRequestException { Map> queryParams = HttpRequestConfig.buildUrlParams( "entity", Optional.ofNullable(params.getEntity()), @@ -60,7 +67,7 @@ public ResponseList listFields(ListFieldsParams params) throws HttpExcept * @param request object {@link com.crowdin.client.fields.model.FieldRequest} * @return Field object * @see */ public ResponseObject addField(FieldRequest request) throws HttpException, HttpBadRequestException { @@ -72,18 +79,32 @@ public ResponseObject addField(FieldRequest request) throws HttpException * @param fieldId field identifier * @return field object according to id * @see + * @deprecated the API returns a single field object, not a collection; use {@link #getFieldById(Long)} instead */ + @Deprecated public ResponseList getField(Long fieldId) throws HttpException, HttpBadRequestException { FieldResponseObjectList responseObject = this.httpClient.get(this.url + "/fields/" + fieldId, new HttpRequestConfig(), FieldResponseObjectList.class); return FieldResponseObjectList.to(responseObject); } + /** + * @param fieldId field identifier + * @return field object according to id + * @see + */ + public ResponseObject getFieldById(Long fieldId) throws HttpException, HttpBadRequestException { + FieldResponseObject responseObject = this.httpClient.get(this.url + "/fields/" + fieldId, new HttpRequestConfig(), FieldResponseObject.class); + return ResponseObject.of(responseObject.getData()); + } + /** * @param fieldId field identifier * @see */ public void deleteField(Long fieldId) throws HttpException, HttpBadRequestException { @@ -95,7 +116,7 @@ public void deleteField(Long fieldId) throws HttpException, HttpBadRequestExcept * @param request object * @return field object * @see */ public ResponseObject editField(Long fieldId, List request) throws HttpException, HttpBadRequestException { diff --git a/src/main/java/com/crowdin/client/fields/model/Config.java b/src/main/java/com/crowdin/client/fields/model/Config.java index 0c87ffaaa..dce6f6acc 100644 --- a/src/main/java/com/crowdin/client/fields/model/Config.java +++ b/src/main/java/com/crowdin/client/fields/model/Config.java @@ -1,5 +1,7 @@ package com.crowdin.client.fields.model; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import java.util.List; @@ -8,10 +10,71 @@ public class Config { private List