From a435c8975aef03c089290c389f78fae1fe9ce36b 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:36 +0000 Subject: [PATCH 1/2] Initial plan From ddf86d7dd40f423f6f1ced57ceb0c2f202d7be37 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:57 +0000 Subject: [PATCH 2/2] feat: add support for string comment attachments Co-authored-by: andrii-bodnar <29282228+andrii-bodnar@users.noreply.github.com> --- src/stringComments/index.ts | 32 ++++++++++++++++++++++++++++++++ tests/stringComments/api.test.ts | 18 ++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/stringComments/index.ts b/src/stringComments/index.ts index d1642e2b7..be0ff6c43 100644 --- a/src/stringComments/index.ts +++ b/src/stringComments/index.ts @@ -122,6 +122,21 @@ export class StringComments extends CrowdinApi { const url = `${this.url}/projects/${projectId}/comments`; return this.patch(url, request, this.defaultConfig()); } + + /** + * @param projectId project identifier + * @param stringCommentId string comment identifier + * @param attachmentId attachment identifier + * @see https://developer.crowdin.com/api/v2/#operation/api.projects.comments.attachments.delete + */ + deleteStringCommentAttachment( + projectId: number, + stringCommentId: number, + attachmentId: number, + ): Promise> { + const url = `${this.url}/projects/${projectId}/comments/${stringCommentId}/attachments/${attachmentId}`; + return this.delete(url, this.defaultConfig()); + } } export namespace StringCommentsModel { @@ -159,6 +174,18 @@ export namespace StringCommentsModel { resolver: User; resolvedAt: string; createdAt: string; + attachments?: Attachment[]; + } + + export interface Attachment { + id: number; + name: string; + mime: string; + size: number; + category: string; + thumbnailUrl: string | null; + url: string; + downloadUrl: string; } export interface User { @@ -185,6 +212,11 @@ export namespace StringCommentsModel { type: Type; isShared?: boolean; issueType?: IssueType; + attachments?: AttachmentRequest[]; + } + + export interface AttachmentRequest { + id: number; } export type Type = 'comment' | 'issue'; diff --git a/tests/stringComments/api.test.ts b/tests/stringComments/api.test.ts index 124b7d149..4191771df 100644 --- a/tests/stringComments/api.test.ts +++ b/tests/stringComments/api.test.ts @@ -11,6 +11,7 @@ describe('String Comments API', () => { const projectId = 2; const stringId = 3; const stringCommentId = 4; + const attachmentId = 5; const text = 'test'; const languageId = 'uk'; const type = 'comment'; @@ -131,6 +132,17 @@ describe('String Comments API', () => { }, }, ], + }) + .delete(`/projects/${projectId}/comments/${stringCommentId}/attachments/${attachmentId}`, undefined, { + reqheaders: { + Authorization: `Bearer ${api.token}`, + }, + }) + .reply(200, { + data: { + id: stringCommentId, + attachments: [], + }, }); }); @@ -197,4 +209,10 @@ describe('String Comments API', () => { expect(translations.data[0].data.type).toBe(type); expect(translations.data[0].data.issueType).toBe(issueType); }); + + it('Delete string comment attachment', async () => { + const comment = await api.deleteStringCommentAttachment(projectId, stringCommentId, attachmentId); + expect(comment.data.id).toBe(stringCommentId); + expect(comment.data.attachments).toEqual([]); + }); });