@doist/todoist-api-typescript 6.0.1 → 6.1.5
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 +105 -5
- package/dist/cjs/authentication.js +59 -63
- package/dist/cjs/rest-client.js +18 -11
- package/dist/cjs/test-utils/mocks.js +2 -45
- package/dist/cjs/test-utils/msw-setup.js +74 -5
- package/dist/cjs/test-utils/obsidian-fetch-adapter.js +53 -0
- package/dist/cjs/todoist-api.js +80 -30
- package/dist/cjs/types/entities.js +4 -4
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/utils/fetch-with-retry.js +37 -14
- package/dist/cjs/utils/multipart-upload.js +2 -1
- package/dist/esm/authentication.js +59 -63
- package/dist/esm/rest-client.js +18 -11
- package/dist/esm/test-utils/mocks.js +3 -10
- package/dist/esm/test-utils/msw-setup.js +67 -2
- package/dist/esm/test-utils/obsidian-fetch-adapter.js +50 -0
- package/dist/esm/todoist-api.js +80 -30
- package/dist/esm/types/entities.js +4 -4
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/utils/fetch-with-retry.js +37 -14
- package/dist/esm/utils/multipart-upload.js +2 -1
- package/dist/types/authentication.d.ts +26 -3
- package/dist/types/rest-client.d.ts +2 -1
- package/dist/types/test-utils/mocks.d.ts +0 -1
- package/dist/types/test-utils/msw-setup.d.ts +31 -1
- package/dist/types/test-utils/obsidian-fetch-adapter.d.ts +29 -0
- package/dist/types/todoist-api.d.ts +19 -7
- package/dist/types/types/entities.d.ts +4 -4
- package/dist/types/types/http.d.ts +17 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/sync.d.ts +5 -5
- package/dist/types/utils/fetch-with-retry.d.ts +2 -1
- package/dist/types/utils/multipart-upload.d.ts +2 -0
- package/package.json +8 -7
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import { CustomFetch } from './types/http';
|
|
2
|
+
/**
|
|
3
|
+
* Options for authentication functions
|
|
4
|
+
*/
|
|
5
|
+
export type AuthOptions = {
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
customFetch?: CustomFetch;
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
10
|
* Permission scopes that can be requested during OAuth2 authorization.
|
|
3
11
|
* @see {@link https://todoist.com/api/v1/docs#tag/Authorization}
|
|
@@ -89,7 +97,12 @@ export declare function getAuthorizationUrl({ clientId, permissions, state, base
|
|
|
89
97
|
* @returns The access token response
|
|
90
98
|
* @throws {@link TodoistRequestError} If the token exchange fails
|
|
91
99
|
*/
|
|
92
|
-
|
|
100
|
+
/**
|
|
101
|
+
* @deprecated Use options object instead: getAuthToken(args, { baseUrl, customFetch })
|
|
102
|
+
*/
|
|
103
|
+
export declare function getAuthToken(args: AuthTokenRequestArgs, baseUrl: string): Promise<AuthTokenResponse>;
|
|
104
|
+
export declare function getAuthToken(args: AuthTokenRequestArgs): Promise<AuthTokenResponse>;
|
|
105
|
+
export declare function getAuthToken(args: AuthTokenRequestArgs, options?: AuthOptions): Promise<AuthTokenResponse>;
|
|
93
106
|
/**
|
|
94
107
|
* Revokes an access token, making it invalid for future use.
|
|
95
108
|
*
|
|
@@ -106,7 +119,12 @@ export declare function getAuthToken(args: AuthTokenRequestArgs, baseUrl?: strin
|
|
|
106
119
|
* @returns True if revocation was successful
|
|
107
120
|
* @see https://todoist.com/api/v1/docs#tag/Authorization/operation/revoke_access_token_api_api_v1_access_tokens_delete
|
|
108
121
|
*/
|
|
109
|
-
|
|
122
|
+
/**
|
|
123
|
+
* @deprecated Use options object instead: revokeAuthToken(args, { baseUrl, customFetch })
|
|
124
|
+
*/
|
|
125
|
+
export declare function revokeAuthToken(args: RevokeAuthTokenRequestArgs, baseUrl: string): Promise<boolean>;
|
|
126
|
+
export declare function revokeAuthToken(args: RevokeAuthTokenRequestArgs): Promise<boolean>;
|
|
127
|
+
export declare function revokeAuthToken(args: RevokeAuthTokenRequestArgs, options?: AuthOptions): Promise<boolean>;
|
|
110
128
|
/**
|
|
111
129
|
* Revokes a token using the RFC 7009 OAuth 2.0 Token Revocation standard.
|
|
112
130
|
*
|
|
@@ -126,4 +144,9 @@ export declare function revokeAuthToken(args: RevokeAuthTokenRequestArgs, baseUr
|
|
|
126
144
|
* @see https://datatracker.ietf.org/doc/html/rfc7009
|
|
127
145
|
* @see https://todoist.com/api/v1/docs#tag/Authorization
|
|
128
146
|
*/
|
|
129
|
-
|
|
147
|
+
/**
|
|
148
|
+
* @deprecated Use options object instead: revokeToken(args, { baseUrl, customFetch })
|
|
149
|
+
*/
|
|
150
|
+
export declare function revokeToken(args: RevokeTokenRequestArgs, baseUrl: string): Promise<boolean>;
|
|
151
|
+
export declare function revokeToken(args: RevokeTokenRequestArgs): Promise<boolean>;
|
|
152
|
+
export declare function revokeToken(args: RevokeTokenRequestArgs, options?: AuthOptions): Promise<boolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpMethod, HttpResponse } from './types/http';
|
|
1
|
+
import { HttpMethod, HttpResponse, CustomFetch } from './types/http';
|
|
2
2
|
type RequestArgs = {
|
|
3
3
|
httpMethod: HttpMethod;
|
|
4
4
|
baseUri: string;
|
|
@@ -8,6 +8,7 @@ type RequestArgs = {
|
|
|
8
8
|
requestId?: string;
|
|
9
9
|
hasSyncCommands?: boolean;
|
|
10
10
|
customHeaders?: Record<string, string>;
|
|
11
|
+
customFetch?: CustomFetch;
|
|
11
12
|
};
|
|
12
13
|
export declare function paramsSerializer(params: Record<string, unknown>): string;
|
|
13
14
|
export declare function isSuccess(response: HttpResponse): boolean;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function setupRestClientMock(responseData: unknown, status?: number): jest.SpyInstance;
|
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
import { http, HttpResponse, type DefaultBodyType } from 'msw';
|
|
2
|
+
export type MockApiOptions = {
|
|
3
|
+
status?: number;
|
|
4
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
export type CapturedRequest = {
|
|
8
|
+
url: string;
|
|
9
|
+
method: string;
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
body: unknown;
|
|
12
|
+
};
|
|
13
|
+
export declare function captureRequest({ request, body }: {
|
|
14
|
+
request: Request;
|
|
15
|
+
body: unknown;
|
|
16
|
+
}): void;
|
|
17
|
+
export declare function getLastRequest(): CapturedRequest | undefined;
|
|
18
|
+
export declare function getAllRequests(): CapturedRequest[];
|
|
19
|
+
export declare function clearCapturedRequests(): void;
|
|
1
20
|
export declare const handlers: never[];
|
|
2
21
|
export declare const server: import("msw/node").SetupServerApi;
|
|
3
|
-
export {
|
|
22
|
+
export declare function mockApiResponse<T extends DefaultBodyType>({ endpoint, data, options, }: {
|
|
23
|
+
endpoint: string;
|
|
24
|
+
data: T;
|
|
25
|
+
options?: MockApiOptions;
|
|
26
|
+
}): void;
|
|
27
|
+
export declare function mockApiError<T extends DefaultBodyType>({ endpoint, data, status, options, }: {
|
|
28
|
+
endpoint: string;
|
|
29
|
+
data: T;
|
|
30
|
+
status: number;
|
|
31
|
+
options?: Omit<MockApiOptions, 'status'>;
|
|
32
|
+
}): void;
|
|
33
|
+
export { http, HttpResponse };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { RequestUrlParam, RequestUrlResponse } from 'obsidian';
|
|
2
|
+
import type { CustomFetch } from '../types/http';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a CustomFetch adapter for Obsidian's requestUrl API.
|
|
5
|
+
*
|
|
6
|
+
* This adapter bridges the gap between Obsidian's requestUrl interface and the
|
|
7
|
+
* standard fetch-like interface expected by the Todoist API SDK.
|
|
8
|
+
*
|
|
9
|
+
* Key differences handled by this adapter:
|
|
10
|
+
* - Obsidian returns response data as properties (response.json, response.text)
|
|
11
|
+
* while the SDK expects methods (response.json(), response.text())
|
|
12
|
+
* - Obsidian's requestUrl bypasses CORS restrictions that would block standard fetch
|
|
13
|
+
* - Obsidian throws on HTTP errors by default; we set throw: false to handle manually
|
|
14
|
+
* - Obsidian doesn't provide statusText; we default to empty string
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { requestUrl } from 'obsidian';
|
|
19
|
+
* import { createObsidianFetchAdapter } from './obsidian-fetch-adapter';
|
|
20
|
+
*
|
|
21
|
+
* const api = new TodoistApi('your-token', {
|
|
22
|
+
* customFetch: createObsidianFetchAdapter(requestUrl)
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @param requestUrl - The Obsidian requestUrl function
|
|
27
|
+
* @returns A CustomFetch function compatible with the Todoist API SDK
|
|
28
|
+
*/
|
|
29
|
+
export declare function createObsidianFetchAdapter(requestUrl: (request: RequestUrlParam | string) => Promise<RequestUrlResponse>): CustomFetch;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Attachment, PersonalProject, WorkspaceProject, Label, Section, Comment, Task, CurrentUser, ProductivityStats, WorkspaceInvitation, WorkspacePlanDetails, JoinWorkspaceResult } from './types/entities';
|
|
2
2
|
import { AddCommentArgs, AddLabelArgs, AddProjectArgs, AddSectionArgs, AddTaskArgs, GetProjectCommentsArgs, GetTaskCommentsArgs, GetTasksArgs, GetTasksByFilterArgs, UpdateCommentArgs, UpdateLabelArgs, UpdateProjectArgs, UpdateSectionArgs, UpdateTaskArgs, QuickAddTaskArgs, GetSharedLabelsArgs, RenameSharedLabelArgs, RemoveSharedLabelArgs, GetProjectsArgs, GetProjectCollaboratorsArgs, GetLabelsArgs, GetLabelsResponse, GetTasksResponse, GetProjectsResponse, GetProjectCollaboratorsResponse, GetSectionsArgs, GetSectionsResponse, GetSharedLabelsResponse, GetCommentsResponse, type MoveTaskArgs, GetCompletedTasksByCompletionDateArgs, GetCompletedTasksByDueDateArgs, GetCompletedTasksResponse, GetArchivedProjectsArgs, GetArchivedProjectsResponse, SearchCompletedTasksArgs, GetActivityLogsArgs, GetActivityLogsResponse, UploadFileArgs, DeleteUploadArgs, GetWorkspaceInvitationsArgs, DeleteWorkspaceInvitationArgs, WorkspaceInvitationActionArgs, JoinWorkspaceArgs, WorkspaceLogoArgs, GetWorkspacePlanDetailsArgs, GetWorkspaceUsersArgs, GetWorkspaceUsersResponse, GetWorkspaceProjectsArgs, WorkspaceInvitationsResponse, AllWorkspaceInvitationsResponse, WorkspaceLogoResponse } from './types/requests';
|
|
3
|
+
import { CustomFetch } from './types/http';
|
|
3
4
|
/**
|
|
4
5
|
* A client for interacting with the Todoist API v1.
|
|
5
6
|
* This class provides methods to manage tasks, projects, sections, labels, and comments in Todoist.
|
|
@@ -21,18 +22,29 @@ import { AddCommentArgs, AddLabelArgs, AddProjectArgs, AddSectionArgs, AddTaskAr
|
|
|
21
22
|
* For more information about the Todoist API v1, see the [official documentation](https://todoist.com/api/v1).
|
|
22
23
|
* If you're migrating from v9, please refer to the [migration guide](https://todoist.com/api/v1/docs#tag/Migrating-from-v9).
|
|
23
24
|
*/
|
|
25
|
+
/**
|
|
26
|
+
* Configuration options for the TodoistApi constructor
|
|
27
|
+
*/
|
|
28
|
+
export type TodoistApiOptions = {
|
|
29
|
+
/**
|
|
30
|
+
* Optional custom API base URL. If not provided, defaults to Todoist's standard API endpoint
|
|
31
|
+
*/
|
|
32
|
+
baseUrl?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Optional custom fetch function for alternative HTTP clients (e.g., Obsidian's requestUrl, React Native fetch)
|
|
35
|
+
*/
|
|
36
|
+
customFetch?: CustomFetch;
|
|
37
|
+
};
|
|
24
38
|
export declare class TodoistApi {
|
|
25
39
|
private authToken;
|
|
26
40
|
private syncApiBase;
|
|
27
|
-
|
|
41
|
+
private customFetch?;
|
|
28
42
|
/**
|
|
29
|
-
*
|
|
30
|
-
*/
|
|
31
|
-
authToken: string,
|
|
32
|
-
/**
|
|
33
|
-
* Optional custom API base URL. If not provided, defaults to Todoist's standard API endpoint
|
|
43
|
+
* @deprecated Use options object instead: new TodoistApi(token, { baseUrl, customFetch })
|
|
34
44
|
*/
|
|
35
|
-
baseUrl
|
|
45
|
+
constructor(authToken: string, baseUrl: string);
|
|
46
|
+
constructor(authToken: string);
|
|
47
|
+
constructor(authToken: string, options?: TodoistApiOptions);
|
|
36
48
|
/**
|
|
37
49
|
* Retrieves information about the authenticated user.
|
|
38
50
|
*
|
|
@@ -818,15 +818,15 @@ export declare const WorkspacePlanDetailsSchema: z.ZodObject<{
|
|
|
818
818
|
*/
|
|
819
819
|
export type WorkspacePlanDetails = z.infer<typeof WorkspacePlanDetailsSchema>;
|
|
820
820
|
export declare const JoinWorkspaceResultSchema: z.ZodObject<{
|
|
821
|
-
|
|
822
|
-
|
|
821
|
+
customSortingApplied: z.ZodBoolean;
|
|
822
|
+
projectSortPreference: z.ZodString;
|
|
823
823
|
role: z.ZodEnum<{
|
|
824
824
|
ADMIN: "ADMIN";
|
|
825
825
|
MEMBER: "MEMBER";
|
|
826
826
|
GUEST: "GUEST";
|
|
827
827
|
}>;
|
|
828
|
-
|
|
829
|
-
|
|
828
|
+
userId: z.ZodString;
|
|
829
|
+
workspaceId: z.ZodString;
|
|
830
830
|
}, z.core.$strip>;
|
|
831
831
|
/**
|
|
832
832
|
* Result returned when successfully joining a workspace.
|
|
@@ -66,3 +66,20 @@ export declare function isNetworkError(error: Error): error is NetworkError;
|
|
|
66
66
|
* Type guard to check if an error is an HTTP error
|
|
67
67
|
*/
|
|
68
68
|
export declare function isHttpError(error: Error): error is HttpError;
|
|
69
|
+
/**
|
|
70
|
+
* Custom fetch response interface that custom HTTP clients must implement
|
|
71
|
+
*/
|
|
72
|
+
export type CustomFetchResponse = {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
status: number;
|
|
75
|
+
statusText: string;
|
|
76
|
+
headers: Record<string, string>;
|
|
77
|
+
text(): Promise<string>;
|
|
78
|
+
json(): Promise<unknown>;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Custom fetch function type for alternative HTTP clients
|
|
82
|
+
*/
|
|
83
|
+
export type CustomFetch = (url: string, options?: RequestInit & {
|
|
84
|
+
timeout?: number;
|
|
85
|
+
}) => Promise<CustomFetchResponse>;
|
|
@@ -6,10 +6,10 @@ export type Command = {
|
|
|
6
6
|
};
|
|
7
7
|
export type SyncError = {
|
|
8
8
|
error: string;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
errorCode: number;
|
|
10
|
+
errorExtra: Record<string, unknown>;
|
|
11
|
+
errorTag: string;
|
|
12
|
+
httpCode: number;
|
|
13
13
|
};
|
|
14
14
|
export type SyncRequest = {
|
|
15
15
|
commands: Command[];
|
|
@@ -17,5 +17,5 @@ export type SyncRequest = {
|
|
|
17
17
|
};
|
|
18
18
|
export type SyncResponse = {
|
|
19
19
|
items?: Task[];
|
|
20
|
-
|
|
20
|
+
syncStatus?: Record<string, 'ok' | SyncError>;
|
|
21
21
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HttpResponse, RetryConfig } from '../types/http';
|
|
1
|
+
import type { HttpResponse, RetryConfig, CustomFetch } from '../types/http';
|
|
2
2
|
/**
|
|
3
3
|
* Performs a fetch request with retry logic and timeout support
|
|
4
4
|
*/
|
|
@@ -8,4 +8,5 @@ export declare function fetchWithRetry<T = unknown>(args: {
|
|
|
8
8
|
timeout?: number;
|
|
9
9
|
};
|
|
10
10
|
retryConfig?: Partial<RetryConfig>;
|
|
11
|
+
customFetch?: CustomFetch;
|
|
11
12
|
}): Promise<HttpResponse<T>>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CustomFetch } from '../types/http';
|
|
1
2
|
type UploadMultipartFileArgs = {
|
|
2
3
|
baseUrl: string;
|
|
3
4
|
authToken: string;
|
|
@@ -6,6 +7,7 @@ type UploadMultipartFileArgs = {
|
|
|
6
7
|
fileName?: string;
|
|
7
8
|
additionalFields: Record<string, string | number | boolean>;
|
|
8
9
|
requestId?: string;
|
|
10
|
+
customFetch?: CustomFetch;
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* Uploads a file using multipart/form-data.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/todoist-api-typescript",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.5",
|
|
4
4
|
"description": "A typescript wrapper for the Todoist REST API.",
|
|
5
5
|
"author": "Doist developers",
|
|
6
6
|
"repository": "git@github.com:doist/todoist-api-typescript.git",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"clean": "rimraf dist",
|
|
26
|
-
"format-check": "npx prettier --check \"./**/*.{ts,tsx,json,md,yml,babelrc,html}\"",
|
|
27
|
-
"format-fix": "npx prettier --write \"./**/*.{ts,tsx,json,md,yml,babelrc,html}\"",
|
|
26
|
+
"format-check": "npx prettier --check \"./**/*.{ts,tsx,json,md,yml,babelrc,html}\" --ignore-path .prettierignore",
|
|
27
|
+
"format-fix": "npx prettier --write \"./**/*.{ts,tsx,json,md,yml,babelrc,html}\" --ignore-path .prettierignore",
|
|
28
28
|
"lint": "eslint ./src --ext ts,tsx --fix",
|
|
29
29
|
"lint-check": "eslint ./src --ext ts,tsx",
|
|
30
30
|
"ts-compile-check": "npx tsc -p tsconfig.typecheck.json",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"zod": "4.1.12"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@doist/eslint-config": "
|
|
51
|
+
"@doist/eslint-config": "12.0.0",
|
|
52
52
|
"@doist/prettier-config": "4.0.0",
|
|
53
53
|
"@types/jest": "30.0.0",
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "
|
|
55
|
-
"@typescript-eslint/parser": "
|
|
56
|
-
"eslint": "8.
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "8.46.3",
|
|
55
|
+
"@typescript-eslint/parser": "8.46.3",
|
|
56
|
+
"eslint": "8.57.1",
|
|
57
57
|
"eslint-config-prettier": "8.7.0",
|
|
58
58
|
"eslint-import-resolver-webpack": "0.13.2",
|
|
59
59
|
"eslint-plugin-import": "2.27.5",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"lint-staged": "16.1.6",
|
|
64
64
|
"msw": "2.11.6",
|
|
65
65
|
"npm-run-all2": "8.0.4",
|
|
66
|
+
"obsidian": "^1.10.2-1",
|
|
66
67
|
"prettier": "3.3.2",
|
|
67
68
|
"rimraf": "6.0.1",
|
|
68
69
|
"ts-jest": "29.4.5",
|