@kendew-agency/clickup-sdk 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +545 -0
- package/dist/clickup.d.ts +37 -0
- package/dist/clickup.d.ts.map +1 -0
- package/dist/clickup.js +44 -0
- package/dist/clickup.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +14 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +2 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/methods/attachments/attachments.d.ts +13 -0
- package/dist/methods/attachments/attachments.d.ts.map +1 -0
- package/dist/methods/attachments/attachments.js +27 -0
- package/dist/methods/attachments/attachments.js.map +1 -0
- package/dist/methods/attachments/types.d.ts +28 -0
- package/dist/methods/attachments/types.d.ts.map +1 -0
- package/dist/methods/attachments/types.js +2 -0
- package/dist/methods/attachments/types.js.map +1 -0
- package/dist/methods/authorization/authorization.d.ts +18 -0
- package/dist/methods/authorization/authorization.d.ts.map +1 -0
- package/dist/methods/authorization/authorization.js +28 -0
- package/dist/methods/authorization/authorization.js.map +1 -0
- package/dist/methods/authorization/types.d.ts +13 -0
- package/dist/methods/authorization/types.d.ts.map +1 -0
- package/dist/methods/authorization/types.js +2 -0
- package/dist/methods/authorization/types.js.map +1 -0
- package/dist/methods/base.d.ts +161 -0
- package/dist/methods/base.d.ts.map +1 -0
- package/dist/methods/base.js +314 -0
- package/dist/methods/base.js.map +1 -0
- package/dist/methods/comments/comments.d.ts +94 -0
- package/dist/methods/comments/comments.d.ts.map +1 -0
- package/dist/methods/comments/comments.js +158 -0
- package/dist/methods/comments/comments.js.map +1 -0
- package/dist/methods/comments/types.d.ts +70 -0
- package/dist/methods/comments/types.d.ts.map +1 -0
- package/dist/methods/comments/types.js +2 -0
- package/dist/methods/comments/types.js.map +1 -0
- package/dist/methods/custom-fields/custom-fields.d.ts +32 -0
- package/dist/methods/custom-fields/custom-fields.d.ts.map +1 -0
- package/dist/methods/custom-fields/custom-fields.js +43 -0
- package/dist/methods/custom-fields/custom-fields.js.map +1 -0
- package/dist/methods/custom-fields/types.d.ts +58 -0
- package/dist/methods/custom-fields/types.d.ts.map +1 -0
- package/dist/methods/custom-fields/types.js +2 -0
- package/dist/methods/custom-fields/types.js.map +1 -0
- package/dist/methods/custom-task-types/custom-task-types.d.ts +12 -0
- package/dist/methods/custom-task-types/custom-task-types.d.ts.map +1 -0
- package/dist/methods/custom-task-types/custom-task-types.js +15 -0
- package/dist/methods/custom-task-types/custom-task-types.js.map +1 -0
- package/dist/methods/custom-task-types/types.d.ts +15 -0
- package/dist/methods/custom-task-types/types.d.ts.map +1 -0
- package/dist/methods/custom-task-types/types.js +2 -0
- package/dist/methods/custom-task-types/types.js.map +1 -0
- package/dist/methods/folders/folders.d.ts +211 -0
- package/dist/methods/folders/folders.d.ts.map +1 -0
- package/dist/methods/folders/folders.js +80 -0
- package/dist/methods/folders/folders.js.map +1 -0
- package/dist/methods/folders/types.d.ts +71 -0
- package/dist/methods/folders/types.d.ts.map +1 -0
- package/dist/methods/folders/types.js +2 -0
- package/dist/methods/folders/types.js.map +1 -0
- package/dist/methods/goals/goals.d.ts +51 -0
- package/dist/methods/goals/goals.d.ts.map +1 -0
- package/dist/methods/goals/goals.js +86 -0
- package/dist/methods/goals/goals.js.map +1 -0
- package/dist/methods/goals/types.d.ts +92 -0
- package/dist/methods/goals/types.d.ts.map +1 -0
- package/dist/methods/goals/types.js +2 -0
- package/dist/methods/goals/types.js.map +1 -0
- package/dist/methods/lists/lists.d.ts +252 -0
- package/dist/methods/lists/lists.d.ts.map +1 -0
- package/dist/methods/lists/lists.js +132 -0
- package/dist/methods/lists/lists.js.map +1 -0
- package/dist/methods/lists/types.d.ts +91 -0
- package/dist/methods/lists/types.d.ts.map +1 -0
- package/dist/methods/lists/types.js +2 -0
- package/dist/methods/lists/types.js.map +1 -0
- package/dist/methods/spaces/spaces.d.ts +187 -0
- package/dist/methods/spaces/spaces.d.ts.map +1 -0
- package/dist/methods/spaces/spaces.js +87 -0
- package/dist/methods/spaces/spaces.js.map +1 -0
- package/dist/methods/spaces/types.d.ts +71 -0
- package/dist/methods/spaces/types.d.ts.map +1 -0
- package/dist/methods/spaces/types.js +2 -0
- package/dist/methods/spaces/types.js.map +1 -0
- package/dist/methods/tags/tags.d.ts +54 -0
- package/dist/methods/tags/tags.d.ts.map +1 -0
- package/dist/methods/tags/tags.js +65 -0
- package/dist/methods/tags/tags.js.map +1 -0
- package/dist/methods/tags/types.d.ts +27 -0
- package/dist/methods/tags/types.d.ts.map +1 -0
- package/dist/methods/tags/types.js +2 -0
- package/dist/methods/tags/types.js.map +1 -0
- package/dist/methods/tasks/tasks.d.ts +366 -0
- package/dist/methods/tasks/tasks.d.ts.map +1 -0
- package/dist/methods/tasks/tasks.js +214 -0
- package/dist/methods/tasks/tasks.js.map +1 -0
- package/dist/methods/tasks/types.d.ts +163 -0
- package/dist/methods/tasks/types.d.ts.map +1 -0
- package/dist/methods/tasks/types.js +2 -0
- package/dist/methods/tasks/types.js.map +1 -0
- package/dist/types/clickup.types.d.ts +35 -0
- package/dist/types/clickup.types.d.ts.map +1 -0
- package/dist/types/clickup.types.js +2 -0
- package/dist/types/clickup.types.js.map +1 -0
- package/dist/types/config.types.d.ts +14 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/config.types.js +2 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +15 -0
- package/dist/types/index.js.map +1 -0
- package/licence +21 -0
- package/package.json +57 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Base } from "../base";
|
|
2
|
+
export class Attachments extends Base {
|
|
3
|
+
/**
|
|
4
|
+
* Create a new task attachment
|
|
5
|
+
*
|
|
6
|
+
* @param params paramaters for creating a task attachment
|
|
7
|
+
* @returns the file stored in ClickUp or an error
|
|
8
|
+
* @see https://developer.clickup.com/reference/createtaskattachment
|
|
9
|
+
*/
|
|
10
|
+
async createTaskAttachement(params) {
|
|
11
|
+
// Clicup expects a multipart/form-data request
|
|
12
|
+
// Create new formdata
|
|
13
|
+
const formData = new FormData();
|
|
14
|
+
// Sanitize file name by replacing spaces with dashes
|
|
15
|
+
const sanitizedFileName = params.attachment.name.replace(/\s+/g, "-");
|
|
16
|
+
// Append the attachment to the form data
|
|
17
|
+
formData.append(`attachment`, params.attachment, sanitizedFileName);
|
|
18
|
+
return this.request(`/task/${params.task_id}/attachment`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
query: {
|
|
21
|
+
custom_task_ids: params.custom_task_ids,
|
|
22
|
+
team_id: params.team_id,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/methods/attachments/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAM/B,MAAM,OAAO,WAAY,SAAQ,IAAI;IACnC;;;;;;OAMG;IACI,KAAK,CAAC,qBAAqB,CAAC,MAAkC;QACnE,+CAA+C;QAE/C,sBAAsB;QACtB,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAChC,qDAAqD;QACrD,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtE,yCAAyC;QACzC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;QAEpE,OAAO,IAAI,CAAC,OAAO,CACjB,SAAS,MAAM,CAAC,OAAO,aAAa,EACpC;YACE,MAAM,EAAE,MAAM;YACd,KAAK,EAAE;gBACL,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB;SACF,CACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type CreateTaskAttachemntParams = CreateTaskAttachemntParamsBase & CreateTaskAttachemntParamsConditional;
|
|
2
|
+
type CreateTaskAttachemntParamsBase = {
|
|
3
|
+
task_id: string;
|
|
4
|
+
/**
|
|
5
|
+
* The attachment to upload.
|
|
6
|
+
* @description this differs from the documentation. Yet attachment `array` is not the correct type.
|
|
7
|
+
*/
|
|
8
|
+
attachment: File;
|
|
9
|
+
};
|
|
10
|
+
type CreateTaskAttachemntParamsConditional = {
|
|
11
|
+
custom_task_ids: true;
|
|
12
|
+
team_id: number;
|
|
13
|
+
} | {
|
|
14
|
+
custom_task_ids?: false;
|
|
15
|
+
team_id?: number;
|
|
16
|
+
};
|
|
17
|
+
export type CreateTaskAttachemntResponse = {
|
|
18
|
+
id: string;
|
|
19
|
+
version: string;
|
|
20
|
+
date: number;
|
|
21
|
+
title: string;
|
|
22
|
+
extension: string;
|
|
23
|
+
thumbnail_small: string;
|
|
24
|
+
thumbnail_large: string;
|
|
25
|
+
url: string;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/methods/attachments/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG,8BAA8B,GACrE,qCAAqC,CAAC;AAExC,KAAK,8BAA8B,GAAG;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAEF,KAAK,qCAAqC,GACtC;IACE,eAAe,EAAE,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,MAAM,MAAM,4BAA4B,GAAG;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/methods/attachments/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Base } from "../base";
|
|
2
|
+
import type { AccessTokenResponse, GetAccessTokenParams, GetAuthorizedUserResponse } from "./types";
|
|
3
|
+
export declare class Authorization extends Base {
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param params the parameters to get an access token
|
|
7
|
+
* @returns data or an error
|
|
8
|
+
* @see https://developer.clickup.com/reference/getaccesstoken
|
|
9
|
+
*/
|
|
10
|
+
getAccessToken(params: GetAccessTokenParams): Promise<import("../../interfaces").Response<AccessTokenResponse>>;
|
|
11
|
+
/**
|
|
12
|
+
* Get the authorized user connected to the current token
|
|
13
|
+
* @returns data or an error
|
|
14
|
+
* @see https://developer.clickup.com/reference/getauthorizeduser
|
|
15
|
+
*/
|
|
16
|
+
getAuthorizedUser(): Promise<import("../../interfaces").Response<GetAuthorizedUserResponse>>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=authorization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization.d.ts","sourceRoot":"","sources":["../../../src/methods/authorization/authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AAEjB,qBAAa,aAAc,SAAQ,IAAI;IACrC;;;;;OAKG;IACU,cAAc,CAAC,MAAM,EAAE,oBAAoB;IASxD;;;;OAIG;IACU,iBAAiB;CAK/B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Base } from "../base";
|
|
2
|
+
export class Authorization extends Base {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param params the parameters to get an access token
|
|
6
|
+
* @returns data or an error
|
|
7
|
+
* @see https://developer.clickup.com/reference/getaccesstoken
|
|
8
|
+
*/
|
|
9
|
+
async getAccessToken(params) {
|
|
10
|
+
return this.request("/oauth/token", {
|
|
11
|
+
method: "POST",
|
|
12
|
+
body: {
|
|
13
|
+
params,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the authorized user connected to the current token
|
|
19
|
+
* @returns data or an error
|
|
20
|
+
* @see https://developer.clickup.com/reference/getauthorizeduser
|
|
21
|
+
*/
|
|
22
|
+
async getAuthorizedUser() {
|
|
23
|
+
return this.request("/user", {
|
|
24
|
+
method: "GET",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=authorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/methods/authorization/authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAO/B,MAAM,OAAO,aAAc,SAAQ,IAAI;IACrC;;;;;OAKG;IACI,KAAK,CAAC,cAAc,CAAC,MAA4B;QACtD,OAAO,IAAI,CAAC,OAAO,CAAsB,cAAc,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE;gBACJ,MAAM;aACP;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,iBAAiB;QAC5B,OAAO,IAAI,CAAC,OAAO,CAA4B,OAAO,EAAE;YACtD,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { User } from "../../types/clickup.types";
|
|
2
|
+
export type GetAccessTokenParams = {
|
|
3
|
+
client_id: string;
|
|
4
|
+
client_secret: string;
|
|
5
|
+
code: string;
|
|
6
|
+
};
|
|
7
|
+
export type AccessTokenResponse = {
|
|
8
|
+
access_token: string;
|
|
9
|
+
};
|
|
10
|
+
export type GetAuthorizedUserResponse = {
|
|
11
|
+
user: User;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/methods/authorization/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEtD,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/methods/authorization/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { ClickUpConfig } from "../types/config.types";
|
|
2
|
+
import type { Response } from "../interfaces";
|
|
3
|
+
type RequestOptions = {
|
|
4
|
+
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
5
|
+
body?: Record<string, unknown>;
|
|
6
|
+
query?: Record<string, unknown>;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
};
|
|
9
|
+
export declare abstract class Base {
|
|
10
|
+
protected config: ClickUpConfig;
|
|
11
|
+
constructor(config: ClickUpConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Constructs a full URL for the ClickUp API by combining the base URL,
|
|
14
|
+
* endpoint path, and optional query parameters.
|
|
15
|
+
*
|
|
16
|
+
* @param endpoint - The API endpoint path (with or without leading slash)
|
|
17
|
+
* @param query - Optional query parameters to append to the URL
|
|
18
|
+
* @returns The complete URL string
|
|
19
|
+
*/
|
|
20
|
+
private buildUrl;
|
|
21
|
+
/**
|
|
22
|
+
* Builds request headers by merging authorization, content-type, config headers,
|
|
23
|
+
* and request-specific headers with proper priority.
|
|
24
|
+
*
|
|
25
|
+
* @param hasBody - Whether the request includes a body (for Content-Type header)
|
|
26
|
+
* @param requestHeaders - Optional request-specific headers to merge
|
|
27
|
+
* @returns Record of header key-value pairs with all values as strings
|
|
28
|
+
*/
|
|
29
|
+
private buildHeaders;
|
|
30
|
+
/**
|
|
31
|
+
* Prepares the request body for HTTP methods that support it.
|
|
32
|
+
* Serializes the body to JSON for POST, PUT, and PATCH requests.
|
|
33
|
+
* Returns undefined for GET and DELETE requests, ignoring any provided body.
|
|
34
|
+
*
|
|
35
|
+
* @param method - The HTTP method for the request
|
|
36
|
+
* @param body - Optional body data to serialize
|
|
37
|
+
* @returns JSON string for methods that accept body, undefined otherwise
|
|
38
|
+
*/
|
|
39
|
+
private prepareRequestBody;
|
|
40
|
+
/**
|
|
41
|
+
* Extracts error message from HTTP response.
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
private extractErrorMessage;
|
|
45
|
+
/**
|
|
46
|
+
* Handles HTTP error responses (non-2xx status codes).
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
private handleHttpError;
|
|
50
|
+
/**
|
|
51
|
+
* Parses successful HTTP response body.
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
private parseSuccessResponse;
|
|
55
|
+
/**
|
|
56
|
+
* Makes an authenticated HTTP request to the ClickUp API.
|
|
57
|
+
*
|
|
58
|
+
* This protected method provides a reusable interface for all API method
|
|
59
|
+
* implementations, handling authentication, URL construction, header
|
|
60
|
+
* management, and error handling automatically.
|
|
61
|
+
*
|
|
62
|
+
* **Features:**
|
|
63
|
+
* - Automatic authentication with Bearer token from config
|
|
64
|
+
* - Base URL prepending (https://api.clickup.com/api/v2)
|
|
65
|
+
* - URL normalization (handles endpoints with or without leading slash)
|
|
66
|
+
* - Query parameter encoding for GET requests
|
|
67
|
+
* - Request body serialization for POST/PUT/PATCH (ignored for GET/DELETE)
|
|
68
|
+
* - Header merging with proper priority (auth > config > request-specific)
|
|
69
|
+
* - Content-Type header automatically added when body is present
|
|
70
|
+
* - Consistent error handling with structured error responses
|
|
71
|
+
* - JSON response parsing with empty body handling
|
|
72
|
+
*
|
|
73
|
+
* @template T - The expected response data type
|
|
74
|
+
*
|
|
75
|
+
* @param endpoint - The API endpoint path (e.g., "/task" or "task").
|
|
76
|
+
* Leading slash is optional and will be normalized.
|
|
77
|
+
*
|
|
78
|
+
* @param options - Optional request configuration
|
|
79
|
+
* @param options.method - HTTP method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
|
|
80
|
+
* (default: "GET")
|
|
81
|
+
* @param options.body - Request body object for POST/PUT/PATCH requests.
|
|
82
|
+
* Automatically serialized to JSON. Ignored for GET/DELETE.
|
|
83
|
+
* @param options.query - Query parameters to append to URL. Values are
|
|
84
|
+
* automatically encoded. Null/undefined values are omitted.
|
|
85
|
+
* @param options.headers - Additional headers to merge with default headers.
|
|
86
|
+
* Cannot override Authorization header.
|
|
87
|
+
*
|
|
88
|
+
* @returns Promise resolving to Response<T> union type:
|
|
89
|
+
* - Success: `{ data: T, error: null }`
|
|
90
|
+
* - Error: `{ data: null, error: ErrorResponse }`
|
|
91
|
+
*
|
|
92
|
+
* **Error Cases:**
|
|
93
|
+
*
|
|
94
|
+
* The method returns structured errors (never throws) for:
|
|
95
|
+
*
|
|
96
|
+
* 1. **Missing API Token** (unauthorized)
|
|
97
|
+
* - Returned when config.apiToken is not set
|
|
98
|
+
* - statusCode: null
|
|
99
|
+
* - message: "API token is required"
|
|
100
|
+
*
|
|
101
|
+
* 2. **401 Unauthorized** (unauthorized)
|
|
102
|
+
* - Returned when API rejects authentication
|
|
103
|
+
* - statusCode: 401
|
|
104
|
+
* - message: Extracted from API response or "Unauthorized"
|
|
105
|
+
*
|
|
106
|
+
* 3. **HTTP Errors** (unknow_error)
|
|
107
|
+
* - Returned for any non-2xx status code (except 401)
|
|
108
|
+
* - statusCode: HTTP status code from response
|
|
109
|
+
* - message: Extracted from API response or status text
|
|
110
|
+
*
|
|
111
|
+
* 4. **Network Errors** (unknow_error)
|
|
112
|
+
* - Returned when fetch fails (connection, timeout, DNS, etc.)
|
|
113
|
+
* - statusCode: null
|
|
114
|
+
* - message: Error message from exception
|
|
115
|
+
*
|
|
116
|
+
* 5. **Invalid JSON** (unknow_error)
|
|
117
|
+
* - Returned when response body is not valid JSON
|
|
118
|
+
* - statusCode: null
|
|
119
|
+
* - message: "Invalid JSON response"
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* // GET request with query parameters
|
|
124
|
+
* const result = await this.request<Task[]>("/task", {
|
|
125
|
+
* query: { archived: false, page: 1 }
|
|
126
|
+
* });
|
|
127
|
+
* if (result.error) {
|
|
128
|
+
* console.error(result.error.message);
|
|
129
|
+
* } else {
|
|
130
|
+
* console.log(result.data); // Task[]
|
|
131
|
+
* }
|
|
132
|
+
*
|
|
133
|
+
* // POST request with body
|
|
134
|
+
* const result = await this.request<Task>("/task", {
|
|
135
|
+
* method: "POST",
|
|
136
|
+
* body: { name: "New Task", description: "Task details" }
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* // PUT request with custom headers
|
|
140
|
+
* const result = await this.request<Task>("/task/123", {
|
|
141
|
+
* method: "PUT",
|
|
142
|
+
* body: { status: "completed" },
|
|
143
|
+
* headers: { "X-Request-ID": "abc123" }
|
|
144
|
+
* });
|
|
145
|
+
*
|
|
146
|
+
* // DELETE request
|
|
147
|
+
* const result = await this.request<void>("/task/123", {
|
|
148
|
+
* method: "DELETE"
|
|
149
|
+
* });
|
|
150
|
+
*
|
|
151
|
+
* // PATCH request for partial update
|
|
152
|
+
* const result = await this.request<Task>("/task/123", {
|
|
153
|
+
* method: "PATCH",
|
|
154
|
+
* body: { priority: 3 }
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
protected request<T>(endpoint: string, options?: RequestOptions): Promise<Response<T>>;
|
|
159
|
+
}
|
|
160
|
+
export {};
|
|
161
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/methods/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,8BAAsB,IAAI;IACxB,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC;gBAEpB,MAAM,EAAE,aAAa;IAIjC;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;IAsBhB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAqCpB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;OAGG;YACW,mBAAmB;IAuBjC;;;OAGG;YACW,eAAe;IAgC7B;;;OAGG;YACW,oBAAoB;IA6BlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsGG;cACa,OAAO,CAAC,CAAC,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CAuDxB"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
export class Base {
|
|
2
|
+
constructor(config) {
|
|
3
|
+
this.config = config;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Constructs a full URL for the ClickUp API by combining the base URL,
|
|
7
|
+
* endpoint path, and optional query parameters.
|
|
8
|
+
*
|
|
9
|
+
* @param endpoint - The API endpoint path (with or without leading slash)
|
|
10
|
+
* @param query - Optional query parameters to append to the URL
|
|
11
|
+
* @returns The complete URL string
|
|
12
|
+
*/
|
|
13
|
+
buildUrl(endpoint, query) {
|
|
14
|
+
const baseUrl = "https://api.clickup.com/api/v2";
|
|
15
|
+
const normalizedEndpoint = endpoint.startsWith("/")
|
|
16
|
+
? endpoint
|
|
17
|
+
: `/${endpoint}`;
|
|
18
|
+
const url = `${baseUrl}${normalizedEndpoint}`;
|
|
19
|
+
if (!query || Object.keys(query).length === 0) {
|
|
20
|
+
return url;
|
|
21
|
+
}
|
|
22
|
+
const searchParams = new URLSearchParams();
|
|
23
|
+
for (const [key, value] of Object.entries(query)) {
|
|
24
|
+
if (value !== undefined && value !== null) {
|
|
25
|
+
searchParams.append(key, String(value));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const queryString = searchParams.toString();
|
|
29
|
+
return queryString ? `${url}?${queryString}` : url;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Builds request headers by merging authorization, content-type, config headers,
|
|
33
|
+
* and request-specific headers with proper priority.
|
|
34
|
+
*
|
|
35
|
+
* @param hasBody - Whether the request includes a body (for Content-Type header)
|
|
36
|
+
* @param requestHeaders - Optional request-specific headers to merge
|
|
37
|
+
* @returns Record of header key-value pairs with all values as strings
|
|
38
|
+
*/
|
|
39
|
+
buildHeaders(hasBody, requestHeaders) {
|
|
40
|
+
const headers = {};
|
|
41
|
+
// 1. Start with Authorization header using Bearer token
|
|
42
|
+
headers.Authorization = `Bearer ${this.config.apiToken}`;
|
|
43
|
+
// 2. Add Content-Type when body is present
|
|
44
|
+
if (hasBody) {
|
|
45
|
+
headers["Content-Type"] = "application/json";
|
|
46
|
+
}
|
|
47
|
+
// 3. Merge config.headers if provided
|
|
48
|
+
if (this.config.headers) {
|
|
49
|
+
for (const [key, value] of Object.entries(this.config.headers)) {
|
|
50
|
+
// Don't override Authorization header from config
|
|
51
|
+
if (key !== "Authorization" && value !== undefined && value !== null) {
|
|
52
|
+
headers[key] = String(value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// 4. Merge request-specific headers from options
|
|
57
|
+
if (requestHeaders) {
|
|
58
|
+
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
59
|
+
// Don't override Authorization header from request options
|
|
60
|
+
if (key !== "Authorization" && value !== undefined && value !== null) {
|
|
61
|
+
headers[key] = String(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return headers;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Prepares the request body for HTTP methods that support it.
|
|
69
|
+
* Serializes the body to JSON for POST, PUT, and PATCH requests.
|
|
70
|
+
* Returns undefined for GET and DELETE requests, ignoring any provided body.
|
|
71
|
+
*
|
|
72
|
+
* @param method - The HTTP method for the request
|
|
73
|
+
* @param body - Optional body data to serialize
|
|
74
|
+
* @returns JSON string for methods that accept body, undefined otherwise
|
|
75
|
+
*/
|
|
76
|
+
prepareRequestBody(method, body) {
|
|
77
|
+
// GET and DELETE requests should not have a body
|
|
78
|
+
if (method === "GET" || method === "DELETE") {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
// POST, PUT, and PATCH requests serialize body to JSON
|
|
82
|
+
if (body && (method === "POST" || method === "PUT" || method === "PATCH")) {
|
|
83
|
+
return JSON.stringify(body);
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Extracts error message from HTTP response.
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
async extractErrorMessage(response, defaultMessage) {
|
|
92
|
+
try {
|
|
93
|
+
const errorData = await response.json();
|
|
94
|
+
if (typeof errorData === "object" &&
|
|
95
|
+
errorData !== null &&
|
|
96
|
+
("message" in errorData || "err" in errorData)) {
|
|
97
|
+
return (errorData.message ||
|
|
98
|
+
errorData.err ||
|
|
99
|
+
defaultMessage);
|
|
100
|
+
}
|
|
101
|
+
return defaultMessage;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return defaultMessage;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Handles HTTP error responses (non-2xx status codes).
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
async handleHttpError(response) {
|
|
112
|
+
if (response.status === 401) {
|
|
113
|
+
const errorMessage = await this.extractErrorMessage(response, "Unauthorized");
|
|
114
|
+
return {
|
|
115
|
+
error: {
|
|
116
|
+
message: errorMessage,
|
|
117
|
+
statusCode: 401,
|
|
118
|
+
name: "unauthorized",
|
|
119
|
+
},
|
|
120
|
+
data: null,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const errorMessage = await this.extractErrorMessage(response, response.statusText || "Request failed");
|
|
124
|
+
return {
|
|
125
|
+
error: {
|
|
126
|
+
message: errorMessage,
|
|
127
|
+
statusCode: response.status,
|
|
128
|
+
name: "unknow_error",
|
|
129
|
+
},
|
|
130
|
+
data: null,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Parses successful HTTP response body.
|
|
135
|
+
* @private
|
|
136
|
+
*/
|
|
137
|
+
async parseSuccessResponse(response) {
|
|
138
|
+
try {
|
|
139
|
+
const text = await response.text();
|
|
140
|
+
if (!text || text.trim() === "") {
|
|
141
|
+
return {
|
|
142
|
+
data: {},
|
|
143
|
+
error: null,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
const data = JSON.parse(text);
|
|
147
|
+
return {
|
|
148
|
+
data,
|
|
149
|
+
error: null,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return {
|
|
154
|
+
error: {
|
|
155
|
+
message: "Invalid JSON response",
|
|
156
|
+
statusCode: null,
|
|
157
|
+
name: "unknow_error",
|
|
158
|
+
},
|
|
159
|
+
data: null,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Makes an authenticated HTTP request to the ClickUp API.
|
|
165
|
+
*
|
|
166
|
+
* This protected method provides a reusable interface for all API method
|
|
167
|
+
* implementations, handling authentication, URL construction, header
|
|
168
|
+
* management, and error handling automatically.
|
|
169
|
+
*
|
|
170
|
+
* **Features:**
|
|
171
|
+
* - Automatic authentication with Bearer token from config
|
|
172
|
+
* - Base URL prepending (https://api.clickup.com/api/v2)
|
|
173
|
+
* - URL normalization (handles endpoints with or without leading slash)
|
|
174
|
+
* - Query parameter encoding for GET requests
|
|
175
|
+
* - Request body serialization for POST/PUT/PATCH (ignored for GET/DELETE)
|
|
176
|
+
* - Header merging with proper priority (auth > config > request-specific)
|
|
177
|
+
* - Content-Type header automatically added when body is present
|
|
178
|
+
* - Consistent error handling with structured error responses
|
|
179
|
+
* - JSON response parsing with empty body handling
|
|
180
|
+
*
|
|
181
|
+
* @template T - The expected response data type
|
|
182
|
+
*
|
|
183
|
+
* @param endpoint - The API endpoint path (e.g., "/task" or "task").
|
|
184
|
+
* Leading slash is optional and will be normalized.
|
|
185
|
+
*
|
|
186
|
+
* @param options - Optional request configuration
|
|
187
|
+
* @param options.method - HTTP method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
|
|
188
|
+
* (default: "GET")
|
|
189
|
+
* @param options.body - Request body object for POST/PUT/PATCH requests.
|
|
190
|
+
* Automatically serialized to JSON. Ignored for GET/DELETE.
|
|
191
|
+
* @param options.query - Query parameters to append to URL. Values are
|
|
192
|
+
* automatically encoded. Null/undefined values are omitted.
|
|
193
|
+
* @param options.headers - Additional headers to merge with default headers.
|
|
194
|
+
* Cannot override Authorization header.
|
|
195
|
+
*
|
|
196
|
+
* @returns Promise resolving to Response<T> union type:
|
|
197
|
+
* - Success: `{ data: T, error: null }`
|
|
198
|
+
* - Error: `{ data: null, error: ErrorResponse }`
|
|
199
|
+
*
|
|
200
|
+
* **Error Cases:**
|
|
201
|
+
*
|
|
202
|
+
* The method returns structured errors (never throws) for:
|
|
203
|
+
*
|
|
204
|
+
* 1. **Missing API Token** (unauthorized)
|
|
205
|
+
* - Returned when config.apiToken is not set
|
|
206
|
+
* - statusCode: null
|
|
207
|
+
* - message: "API token is required"
|
|
208
|
+
*
|
|
209
|
+
* 2. **401 Unauthorized** (unauthorized)
|
|
210
|
+
* - Returned when API rejects authentication
|
|
211
|
+
* - statusCode: 401
|
|
212
|
+
* - message: Extracted from API response or "Unauthorized"
|
|
213
|
+
*
|
|
214
|
+
* 3. **HTTP Errors** (unknow_error)
|
|
215
|
+
* - Returned for any non-2xx status code (except 401)
|
|
216
|
+
* - statusCode: HTTP status code from response
|
|
217
|
+
* - message: Extracted from API response or status text
|
|
218
|
+
*
|
|
219
|
+
* 4. **Network Errors** (unknow_error)
|
|
220
|
+
* - Returned when fetch fails (connection, timeout, DNS, etc.)
|
|
221
|
+
* - statusCode: null
|
|
222
|
+
* - message: Error message from exception
|
|
223
|
+
*
|
|
224
|
+
* 5. **Invalid JSON** (unknow_error)
|
|
225
|
+
* - Returned when response body is not valid JSON
|
|
226
|
+
* - statusCode: null
|
|
227
|
+
* - message: "Invalid JSON response"
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* // GET request with query parameters
|
|
232
|
+
* const result = await this.request<Task[]>("/task", {
|
|
233
|
+
* query: { archived: false, page: 1 }
|
|
234
|
+
* });
|
|
235
|
+
* if (result.error) {
|
|
236
|
+
* console.error(result.error.message);
|
|
237
|
+
* } else {
|
|
238
|
+
* console.log(result.data); // Task[]
|
|
239
|
+
* }
|
|
240
|
+
*
|
|
241
|
+
* // POST request with body
|
|
242
|
+
* const result = await this.request<Task>("/task", {
|
|
243
|
+
* method: "POST",
|
|
244
|
+
* body: { name: "New Task", description: "Task details" }
|
|
245
|
+
* });
|
|
246
|
+
*
|
|
247
|
+
* // PUT request with custom headers
|
|
248
|
+
* const result = await this.request<Task>("/task/123", {
|
|
249
|
+
* method: "PUT",
|
|
250
|
+
* body: { status: "completed" },
|
|
251
|
+
* headers: { "X-Request-ID": "abc123" }
|
|
252
|
+
* });
|
|
253
|
+
*
|
|
254
|
+
* // DELETE request
|
|
255
|
+
* const result = await this.request<void>("/task/123", {
|
|
256
|
+
* method: "DELETE"
|
|
257
|
+
* });
|
|
258
|
+
*
|
|
259
|
+
* // PATCH request for partial update
|
|
260
|
+
* const result = await this.request<Task>("/task/123", {
|
|
261
|
+
* method: "PATCH",
|
|
262
|
+
* body: { priority: 3 }
|
|
263
|
+
* });
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
async request(endpoint, options) {
|
|
267
|
+
// 1. Validate API token is present
|
|
268
|
+
if (!this.config.apiToken) {
|
|
269
|
+
return {
|
|
270
|
+
error: {
|
|
271
|
+
message: "API token is required",
|
|
272
|
+
statusCode: null,
|
|
273
|
+
name: "unauthorized",
|
|
274
|
+
},
|
|
275
|
+
data: null,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// 2. Extract options with defaults
|
|
279
|
+
const method = options?.method || "GET";
|
|
280
|
+
const { body, query, headers: requestHeaders } = options || {};
|
|
281
|
+
// 3. Build full URL with query parameters
|
|
282
|
+
const url = this.buildUrl(endpoint, query);
|
|
283
|
+
// 4. Prepare request body if applicable
|
|
284
|
+
const requestBody = this.prepareRequestBody(method, body);
|
|
285
|
+
// 5. Build headers with authentication
|
|
286
|
+
const headers = this.buildHeaders(!!requestBody, requestHeaders);
|
|
287
|
+
try {
|
|
288
|
+
// 6. Execute fetch with constructed parameters
|
|
289
|
+
const response = await fetch(url, {
|
|
290
|
+
method,
|
|
291
|
+
headers,
|
|
292
|
+
body: requestBody,
|
|
293
|
+
});
|
|
294
|
+
// 7. Handle HTTP errors or parse success response
|
|
295
|
+
if (!response.ok) {
|
|
296
|
+
return this.handleHttpError(response);
|
|
297
|
+
}
|
|
298
|
+
return this.parseSuccessResponse(response);
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
// Network errors or other exceptions
|
|
302
|
+
const errorMessage = error instanceof Error ? error.message : "Network request failed";
|
|
303
|
+
return {
|
|
304
|
+
error: {
|
|
305
|
+
message: errorMessage,
|
|
306
|
+
statusCode: null,
|
|
307
|
+
name: "unknow_error",
|
|
308
|
+
},
|
|
309
|
+
data: null,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/methods/base.ts"],"names":[],"mappings":"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"}
|