@doist/todoist-sdk 14.1.0 → 15.0.0

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.
Files changed (172) hide show
  1. package/README.md +46 -1
  2. package/dist/esm/index.js +1 -1
  3. package/dist/esm/transport/http-dispatcher.js +25 -0
  4. package/dist/esm/utils/index.js +1 -1
  5. package/dist/esm/utils/multipart-upload.js +171 -57
  6. package/dist/esm/utils/url-helpers.js +151 -23
  7. package/dist/types/index.d.ts +2 -1
  8. package/dist/types/transport/http-dispatcher.d.ts +26 -1
  9. package/dist/types/utils/index.d.ts +2 -1
  10. package/dist/types/utils/url-helpers.d.ts +88 -0
  11. package/package.json +6 -12
  12. package/dist/cjs/authentication.js +0 -317
  13. package/dist/cjs/clients/activity-client.js +0 -63
  14. package/dist/cjs/clients/app-client.js +0 -345
  15. package/dist/cjs/clients/backup-client.js +0 -47
  16. package/dist/cjs/clients/base-client.js +0 -31
  17. package/dist/cjs/clients/billing-client.js +0 -152
  18. package/dist/cjs/clients/comment-client.js +0 -91
  19. package/dist/cjs/clients/email-client.js +0 -43
  20. package/dist/cjs/clients/folder-client.js +0 -79
  21. package/dist/cjs/clients/id-mapping-client.js +0 -39
  22. package/dist/cjs/clients/insights-client.js +0 -87
  23. package/dist/cjs/clients/label-client.js +0 -126
  24. package/dist/cjs/clients/productivity-client.js +0 -27
  25. package/dist/cjs/clients/project-client.js +0 -235
  26. package/dist/cjs/clients/reminder-client.js +0 -198
  27. package/dist/cjs/clients/section-client.js +0 -117
  28. package/dist/cjs/clients/task-client.js +0 -254
  29. package/dist/cjs/clients/template-client.js +0 -88
  30. package/dist/cjs/clients/ui-extension-client.js +0 -107
  31. package/dist/cjs/clients/upload-client.js +0 -155
  32. package/dist/cjs/clients/view-options-client.js +0 -25
  33. package/dist/cjs/clients/workspace-client.js +0 -366
  34. package/dist/cjs/consts/endpoints.js +0 -224
  35. package/dist/cjs/index.js +0 -23
  36. package/dist/cjs/package.json +0 -1
  37. package/dist/cjs/test-utils/asserts.js +0 -11
  38. package/dist/cjs/test-utils/msw-setup.js +0 -97
  39. package/dist/cjs/test-utils/obsidian-fetch-adapter.js +0 -54
  40. package/dist/cjs/test-utils/test-defaults.js +0 -371
  41. package/dist/cjs/test-utils/transport-seam.js +0 -17
  42. package/dist/cjs/test-utils/webhook-fixtures.js +0 -32
  43. package/dist/cjs/todoist-api.js +0 -1711
  44. package/dist/cjs/transport/fetch-with-retry.js +0 -219
  45. package/dist/cjs/transport/http-client.js +0 -134
  46. package/dist/cjs/transport/http-dispatcher.js +0 -173
  47. package/dist/cjs/transport/sync-request.js +0 -83
  48. package/dist/cjs/types/activity/index.js +0 -18
  49. package/dist/cjs/types/activity/requests.js +0 -2
  50. package/dist/cjs/types/activity/types.js +0 -28
  51. package/dist/cjs/types/apps/index.js +0 -18
  52. package/dist/cjs/types/apps/requests.js +0 -2
  53. package/dist/cjs/types/apps/types.js +0 -254
  54. package/dist/cjs/types/backups/index.js +0 -18
  55. package/dist/cjs/types/backups/requests.js +0 -2
  56. package/dist/cjs/types/backups/types.js +0 -8
  57. package/dist/cjs/types/billing/index.js +0 -18
  58. package/dist/cjs/types/billing/requests.js +0 -2
  59. package/dist/cjs/types/billing/types.js +0 -92
  60. package/dist/cjs/types/comments/index.js +0 -18
  61. package/dist/cjs/types/comments/requests.js +0 -2
  62. package/dist/cjs/types/comments/types.js +0 -60
  63. package/dist/cjs/types/common.js +0 -10
  64. package/dist/cjs/types/emails/index.js +0 -17
  65. package/dist/cjs/types/emails/requests.js +0 -5
  66. package/dist/cjs/types/errors.js +0 -29
  67. package/dist/cjs/types/folders/index.js +0 -17
  68. package/dist/cjs/types/folders/requests.js +0 -2
  69. package/dist/cjs/types/http.js +0 -24
  70. package/dist/cjs/types/id-mappings/index.js +0 -18
  71. package/dist/cjs/types/id-mappings/requests.js +0 -20
  72. package/dist/cjs/types/id-mappings/types.js +0 -12
  73. package/dist/cjs/types/index.js +0 -40
  74. package/dist/cjs/types/insights/index.js +0 -18
  75. package/dist/cjs/types/insights/requests.js +0 -2
  76. package/dist/cjs/types/insights/types.js +0 -80
  77. package/dist/cjs/types/labels/index.js +0 -18
  78. package/dist/cjs/types/labels/requests.js +0 -2
  79. package/dist/cjs/types/labels/types.js +0 -11
  80. package/dist/cjs/types/productivity/index.js +0 -17
  81. package/dist/cjs/types/productivity/types.js +0 -68
  82. package/dist/cjs/types/projects/index.js +0 -18
  83. package/dist/cjs/types/projects/requests.js +0 -2
  84. package/dist/cjs/types/projects/types.js +0 -66
  85. package/dist/cjs/types/reminders/index.js +0 -17
  86. package/dist/cjs/types/reminders/requests.js +0 -95
  87. package/dist/cjs/types/sections/index.js +0 -18
  88. package/dist/cjs/types/sections/requests.js +0 -2
  89. package/dist/cjs/types/sections/types.js +0 -25
  90. package/dist/cjs/types/sync/commands/calendars.js +0 -2
  91. package/dist/cjs/types/sync/commands/filters.js +0 -2
  92. package/dist/cjs/types/sync/commands/folders.js +0 -2
  93. package/dist/cjs/types/sync/commands/index.js +0 -34
  94. package/dist/cjs/types/sync/commands/labels.js +0 -5
  95. package/dist/cjs/types/sync/commands/notes.js +0 -2
  96. package/dist/cjs/types/sync/commands/notifications.js +0 -2
  97. package/dist/cjs/types/sync/commands/others.js +0 -2
  98. package/dist/cjs/types/sync/commands/project-view-options.js +0 -2
  99. package/dist/cjs/types/sync/commands/projects.js +0 -2
  100. package/dist/cjs/types/sync/commands/reminders.js +0 -2
  101. package/dist/cjs/types/sync/commands/sections.js +0 -2
  102. package/dist/cjs/types/sync/commands/shared.js +0 -20
  103. package/dist/cjs/types/sync/commands/sharing.js +0 -2
  104. package/dist/cjs/types/sync/commands/tasks.js +0 -2
  105. package/dist/cjs/types/sync/commands/view-options.js +0 -2
  106. package/dist/cjs/types/sync/commands/workspace-filters.js +0 -2
  107. package/dist/cjs/types/sync/commands/workspaces.js +0 -2
  108. package/dist/cjs/types/sync/index.js +0 -22
  109. package/dist/cjs/types/sync/request.js +0 -2
  110. package/dist/cjs/types/sync/resource-types.js +0 -39
  111. package/dist/cjs/types/sync/resources/calendars.js +0 -27
  112. package/dist/cjs/types/sync/resources/collaborators.js +0 -21
  113. package/dist/cjs/types/sync/resources/completed-info.js +0 -24
  114. package/dist/cjs/types/sync/resources/filters.js +0 -14
  115. package/dist/cjs/types/sync/resources/folders.js +0 -12
  116. package/dist/cjs/types/sync/resources/index.js +0 -32
  117. package/dist/cjs/types/sync/resources/live-notifications.js +0 -38
  118. package/dist/cjs/types/sync/resources/notes.js +0 -21
  119. package/dist/cjs/types/sync/resources/reminders.js +0 -50
  120. package/dist/cjs/types/sync/resources/suggestions.js +0 -36
  121. package/dist/cjs/types/sync/resources/tooltips.js +0 -8
  122. package/dist/cjs/types/sync/resources/user-plan-limits.js +0 -20
  123. package/dist/cjs/types/sync/resources/user-settings.js +0 -40
  124. package/dist/cjs/types/sync/resources/user.js +0 -110
  125. package/dist/cjs/types/sync/resources/view-options.js +0 -86
  126. package/dist/cjs/types/sync/resources/workspace-filters.js +0 -19
  127. package/dist/cjs/types/sync/resources/workspaces.js +0 -72
  128. package/dist/cjs/types/sync/response.js +0 -54
  129. package/dist/cjs/types/sync/user-preferences.js +0 -71
  130. package/dist/cjs/types/tasks/index.js +0 -18
  131. package/dist/cjs/types/tasks/requests.js +0 -2
  132. package/dist/cjs/types/tasks/types.js +0 -59
  133. package/dist/cjs/types/templates/index.js +0 -17
  134. package/dist/cjs/types/templates/requests.js +0 -2
  135. package/dist/cjs/types/ui-extensions/index.js +0 -18
  136. package/dist/cjs/types/ui-extensions/requests.js +0 -2
  137. package/dist/cjs/types/ui-extensions/types.js +0 -77
  138. package/dist/cjs/types/uploads/index.js +0 -17
  139. package/dist/cjs/types/uploads/requests.js +0 -2
  140. package/dist/cjs/types/users/index.js +0 -17
  141. package/dist/cjs/types/users/types.js +0 -51
  142. package/dist/cjs/types/webhooks/comments.js +0 -96
  143. package/dist/cjs/types/webhooks/envelope.js +0 -26
  144. package/dist/cjs/types/webhooks/filters.js +0 -30
  145. package/dist/cjs/types/webhooks/index.js +0 -25
  146. package/dist/cjs/types/webhooks/labels.js +0 -54
  147. package/dist/cjs/types/webhooks/projects.js +0 -36
  148. package/dist/cjs/types/webhooks/reminders.js +0 -35
  149. package/dist/cjs/types/webhooks/sections.js +0 -53
  150. package/dist/cjs/types/webhooks/tasks.js +0 -68
  151. package/dist/cjs/types/webhooks/types.js +0 -55
  152. package/dist/cjs/types/workspaces/index.js +0 -18
  153. package/dist/cjs/types/workspaces/requests.js +0 -2
  154. package/dist/cjs/types/workspaces/types.js +0 -154
  155. package/dist/cjs/utils/activity-helpers.js +0 -58
  156. package/dist/cjs/utils/case-conversion.js +0 -69
  157. package/dist/cjs/utils/colors.js +0 -143
  158. package/dist/cjs/utils/file-response.js +0 -32
  159. package/dist/cjs/utils/headers.js +0 -16
  160. package/dist/cjs/utils/index.js +0 -31
  161. package/dist/cjs/utils/multipart-upload.js +0 -179
  162. package/dist/cjs/utils/processing-helpers.js +0 -18
  163. package/dist/cjs/utils/project-helpers.js +0 -20
  164. package/dist/cjs/utils/request-helpers.js +0 -21
  165. package/dist/cjs/utils/sanitization.js +0 -116
  166. package/dist/cjs/utils/sync-helpers.js +0 -22
  167. package/dist/cjs/utils/task-sorting.js +0 -281
  168. package/dist/cjs/utils/uncompletable-helpers.js +0 -60
  169. package/dist/cjs/utils/url-helpers.js +0 -74
  170. package/dist/cjs/utils/validators.js +0 -108
  171. package/dist/cjs/utils/view-options.js +0 -19
  172. package/dist/cjs/utils/webhook-parser.js +0 -60
@@ -30,3 +30,91 @@ export declare function getProjectUrl(projectId: string, name?: string): string;
30
30
  * @returns The URL string for the section view.
31
31
  */
32
32
  export declare function getSectionUrl(sectionId: string, name?: string): string;
33
+ /**
34
+ * Generate the URL for a given label.
35
+ *
36
+ * @param labelId The ID of the label.
37
+ * @param name The name of the label.
38
+ * @returns The URL string for the label view.
39
+ */
40
+ export declare function getLabelUrl(labelId: string, name?: string): string;
41
+ /**
42
+ * Generate the URL for a given filter.
43
+ *
44
+ * @param filterId The ID of the filter.
45
+ * @param name The name of the filter.
46
+ * @returns The URL string for the filter view.
47
+ */
48
+ export declare function getFilterUrl(filterId: string, name?: string): string;
49
+ /**
50
+ * Generate the URL for a filter belonging to a workspace.
51
+ *
52
+ * @param workspaceId The ID of the workspace the filter belongs to.
53
+ * @param filterId The ID of the filter.
54
+ * @param name The name of the filter.
55
+ * @returns The URL string for the workspace filter view.
56
+ */
57
+ export declare function getWorkspaceFilterUrl(workspaceId: string, filterId: string, name?: string): string;
58
+ /**
59
+ * Generate the URL for a given workspace.
60
+ *
61
+ * @param workspaceId The ID of the workspace.
62
+ * @returns The URL string for the workspace view.
63
+ */
64
+ export declare function getWorkspaceUrl(workspaceId: string): string;
65
+ /**
66
+ * Generate the URL for the comments on a given task.
67
+ *
68
+ * @param taskId The ID of the task.
69
+ * @param content The content of the task.
70
+ * @returns The URL string for the task's comments.
71
+ */
72
+ export declare function getTaskCommentsUrl(taskId: string, content?: string): string;
73
+ /**
74
+ * Generate the URL for the comments on a given project.
75
+ *
76
+ * @param projectId The ID of the project.
77
+ * @param name The name of the project.
78
+ * @returns The URL string for the project's comments.
79
+ */
80
+ export declare function getProjectCommentsUrl(projectId: string, name?: string): string;
81
+ /**
82
+ * Generate the URL for a single comment on a given task.
83
+ *
84
+ * @param taskId The ID of the task.
85
+ * @param commentId The ID of the comment.
86
+ * @param content The content of the task.
87
+ * @returns The URL string for the comment.
88
+ */
89
+ export declare function getTaskCommentUrl(taskId: string, commentId: string, content?: string): string;
90
+ /**
91
+ * Generate the URL for a single comment on a given project.
92
+ *
93
+ * @param projectId The ID of the project.
94
+ * @param commentId The ID of the comment.
95
+ * @param name The name of the project.
96
+ * @returns The URL string for the comment.
97
+ */
98
+ export declare function getProjectCommentUrl(projectId: string, commentId: string, name?: string): string;
99
+ /** The kinds of Todoist entity a URL can point at. */
100
+ export declare const TODOIST_LINK_TYPES: readonly ["task", "project", "filter", "label", "section", "workspace", "template", "comment", "label_by_name"];
101
+ /** The kind of Todoist entity a URL points at. */
102
+ export type TodoistLinkType = (typeof TODOIST_LINK_TYPES)[number];
103
+ /** The entity a Todoist URL points at. */
104
+ export type TodoistUrlInfo = {
105
+ /** The kind of entity the URL points at. */
106
+ type: TodoistLinkType;
107
+ /** The ID of the entity. */
108
+ id: string;
109
+ /** The ID of the workspace the entity belongs to, when the URL names one. */
110
+ workspaceId: string | null;
111
+ /** The ID of the comment the URL points at, when the URL names one. */
112
+ commentId: string | null;
113
+ };
114
+ /**
115
+ * Parse a Todoist URL into the entity it points at.
116
+ *
117
+ * @param url The URL to parse.
118
+ * @returns The entity the URL points at, or `null` if it is not a Todoist URL.
119
+ */
120
+ export declare function parseTodoistUrl(url: string): TodoistUrlInfo | null;
package/package.json CHANGED
@@ -1,20 +1,17 @@
1
1
  {
2
2
  "name": "@doist/todoist-sdk",
3
- "version": "14.1.0",
3
+ "version": "15.0.0",
4
4
  "description": "The official TypeScript SDK for the Todoist REST API.",
5
5
  "author": "Doist developers",
6
6
  "repository": "https://github.com/Doist/todoist-sdk-typescript",
7
7
  "homepage": "https://doist.github.io/todoist-sdk-typescript/",
8
8
  "license": "MIT",
9
9
  "type": "module",
10
- "main": "dist/cjs/index.js",
11
- "module": "dist/esm/index.js",
12
10
  "types": "dist/types/index.d.ts",
13
11
  "exports": {
14
12
  ".": {
15
13
  "types": "./dist/types/index.d.ts",
16
- "import": "./dist/esm/index.js",
17
- "require": "./dist/cjs/index.js"
14
+ "default": "./dist/esm/index.js"
18
15
  }
19
16
  },
20
17
  "publishConfig": {
@@ -36,13 +33,11 @@
36
33
  "test:watch": "vitest",
37
34
  "test:coverage": "vitest run --coverage",
38
35
  "api:request": "node ./scripts/todoist-api-request.cjs",
39
- "build:cjs": "npx tsc -p tsconfig.cjs.json",
40
36
  "build:esm": "npx tsc -p tsconfig.esm.json",
41
37
  "build:fix-esm": "node scripts/fix-esm-imports.cjs",
42
38
  "build:fix-dts": "node scripts/fix-dts-imports.cjs",
43
- "build:post": "echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json",
44
- "build": "npm-run-all clean build:cjs build:esm build:fix-esm build:fix-dts build:post",
45
- "attw": "attw --pack --ignore-rules fallback-condition false-esm",
39
+ "build": "npm-run-all clean build:esm build:fix-esm build:fix-dts",
40
+ "attw": "attw --pack --ignore-rules cjs-resolves-to-esm",
46
41
  "integrity-checks": "npm-run-all clean check test build attw",
47
42
  "prepublishOnly": "npm run integrity-checks",
48
43
  "prepare": "npm run build"
@@ -51,11 +46,11 @@
51
46
  "fflate": "0.8.2"
52
47
  },
53
48
  "dependencies": {
49
+ "@doist/sdk-kmp": "0.2.3",
54
50
  "camelcase": "6.3.0",
55
51
  "emoji-regex": "10.6.0",
56
- "form-data": "4.0.6",
57
52
  "ts-custom-error": "^3.2.0",
58
- "undici": "7.24.8",
53
+ "undici": "^7.29.0",
59
54
  "uuid": "11.1.1",
60
55
  "zod": "4.3.6"
61
56
  },
@@ -92,7 +87,6 @@
92
87
  "*.{ts,tsx,json,md,yml,yaml}": "oxfmt --no-error-on-unmatched-pattern"
93
88
  },
94
89
  "files": [
95
- "dist/cjs/**/*",
96
90
  "dist/esm/**/*",
97
91
  "dist/types/**/*",
98
92
  "!dist/**/*.test.js",
@@ -1,317 +0,0 @@
1
- "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.TOKEN_ENDPOINT_AUTH_METHODS = exports.PERMISSIONS = void 0;
15
- exports.getAuthStateParameter = getAuthStateParameter;
16
- exports.getAuthorizationUrl = getAuthorizationUrl;
17
- exports.getAuthToken = getAuthToken;
18
- exports.refreshAuthToken = refreshAuthToken;
19
- exports.revokeToken = revokeToken;
20
- exports.migratePersonalToken = migratePersonalToken;
21
- exports.registerClient = registerClient;
22
- const uuid_1 = require("uuid");
23
- const endpoints_1 = require("./consts/endpoints");
24
- const http_client_1 = require("./transport/http-client");
25
- const types_1 = require("./types");
26
- /** Available OAuth2 permission scopes. */
27
- exports.PERMISSIONS = [
28
- 'task:add',
29
- 'data:read',
30
- 'data:read_write',
31
- 'data:delete',
32
- 'project:delete',
33
- 'backups:read',
34
- 'billing:read',
35
- 'billing:read_write',
36
- 'dev:app_console',
37
- ];
38
- /** Supported token endpoint authentication methods for dynamic client registration. */
39
- exports.TOKEN_ENDPOINT_AUTH_METHODS = [
40
- 'client_secret_post',
41
- 'client_secret_basic',
42
- 'none',
43
- ];
44
- /**
45
- * Creates a Basic Authentication header value from client credentials.
46
- * @param clientId - The OAuth client ID
47
- * @param clientSecret - The OAuth client secret
48
- * @returns The Basic Auth header value (without the 'Basic ' prefix)
49
- */
50
- function createBasicAuthHeader(clientId, clientSecret) {
51
- const credentials = `${clientId}:${clientSecret}`;
52
- return Buffer.from(credentials).toString('base64');
53
- }
54
- /**
55
- * Generates a random state parameter for OAuth2 authorization.
56
- * The state parameter helps prevent CSRF attacks.
57
- *
58
- * @example
59
- * ```typescript
60
- * const state = getAuthStateParameter()
61
- * // Store state in session
62
- * const authUrl = getAuthorizationUrl(clientId, ['data:read'], state)
63
- * ```
64
- *
65
- * @returns A random UUID v4 string
66
- */
67
- function getAuthStateParameter() {
68
- return (0, uuid_1.v4)();
69
- }
70
- /**
71
- * Generates the authorization URL for the OAuth2 flow.
72
- *
73
- * The `clientId` can be either a traditional client ID string (e.g. from
74
- * {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
75
- * as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
76
- *
77
- * @example
78
- * ```typescript
79
- * const url = getAuthorizationUrl({
80
- * clientId: 'your-client-id',
81
- * permissions: ['data:read', 'task:add'],
82
- * state,
83
- * })
84
- * // Redirect user to url
85
- * ```
86
- *
87
- * @returns The full authorization URL to redirect users to
88
- * @see https://developer.todoist.com/api/v1/#tag/Authorization/OAuth
89
- */
90
- function getAuthorizationUrl({ clientId, permissions, state, baseUrl, }) {
91
- if (!(permissions === null || permissions === void 0 ? void 0 : permissions.length)) {
92
- throw new Error('At least one scope value should be passed for permissions.');
93
- }
94
- const scope = permissions.join(',');
95
- return `${(0, endpoints_1.getAuthBaseUri)(baseUrl)}${endpoints_1.ENDPOINT_AUTHORIZATION}?client_id=${encodeURIComponent(clientId)}&scope=${scope}&state=${state}`;
96
- }
97
- /**
98
- * Exchanges an authorization code for an access token.
99
- *
100
- * @example
101
- * ```typescript
102
- * const { accessToken } = await getAuthToken({
103
- * clientId: 'your-client-id',
104
- * clientSecret: 'your-client-secret',
105
- * code: authCode
106
- * })
107
- * ```
108
- *
109
- * @returns The access token response
110
- * @throws {@link TodoistRequestError} If the token exchange fails
111
- */
112
- /**
113
- * Posts a payload to the OAuth token endpoint and returns the token response,
114
- * mapping any failure to a {@link TodoistRequestError} with `errorMessage`.
115
- * Shared by {@link getAuthToken} and {@link refreshAuthToken}.
116
- */
117
- async function requestAuthToken(payload, errorMessage, options) {
118
- var _a;
119
- try {
120
- const response = await (0, http_client_1.request)({
121
- httpMethod: 'POST',
122
- baseUri: (0, endpoints_1.getAuthBaseUri)(options === null || options === void 0 ? void 0 : options.baseUrl),
123
- relativePath: endpoints_1.ENDPOINT_GET_TOKEN,
124
- apiToken: undefined,
125
- payload,
126
- customFetch: options === null || options === void 0 ? void 0 : options.customFetch,
127
- });
128
- if (response.status !== 200 || !((_a = response.data) === null || _a === void 0 ? void 0 : _a.accessToken)) {
129
- throw new types_1.TodoistRequestError(errorMessage, response.status, response.data);
130
- }
131
- return response.data;
132
- }
133
- catch (error) {
134
- // Re-throw with custom message for authentication failures
135
- const err = error;
136
- throw new types_1.TodoistRequestError(errorMessage, err.httpStatusCode, err.responseData);
137
- }
138
- }
139
- async function getAuthToken(args, options) {
140
- if (typeof options === 'string') {
141
- throw new TypeError('Passing baseUrl as a string is no longer supported. Use an options object instead: getAuthToken(args, { baseUrl })');
142
- }
143
- return requestAuthToken(Object.assign({}, args), 'Authentication token exchange failed.', options);
144
- }
145
- /**
146
- * Exchanges a refresh token for a new access token using the OAuth2
147
- * `refresh_token` grant.
148
- *
149
- * Only relevant for OAuth apps that have refresh tokens enabled (the default for
150
- * new apps). Apps without them never receive a `refreshToken` from
151
- * {@link getAuthToken}, so they have nothing to pass here — their access tokens
152
- * are long-lived instead.
153
- *
154
- * Omit `clientSecret` for public clients registered with
155
- * `tokenEndpointAuthMethod: 'none'`.
156
- *
157
- * @example
158
- * ```typescript
159
- * const { accessToken, refreshToken } = await refreshAuthToken({
160
- * clientId: 'your-client-id',
161
- * clientSecret: 'your-client-secret',
162
- * refreshToken: storedRefreshToken,
163
- * })
164
- * ```
165
- *
166
- * @returns The refreshed token. The server rotates the refresh token, so the
167
- * response carries a new `refreshToken` — persist it in place of the old one.
168
- * @throws {@link TodoistRequestError} If the refresh fails
169
- */
170
- async function refreshAuthToken(args, options) {
171
- const payload = {
172
- clientId: args.clientId,
173
- refreshToken: args.refreshToken,
174
- grantType: 'refresh_token',
175
- };
176
- if (args.clientSecret !== undefined) {
177
- payload.clientSecret = args.clientSecret;
178
- }
179
- return requestAuthToken(payload, 'Authentication token refresh failed.', options);
180
- }
181
- /**
182
- * Revokes a token using the RFC 7009 OAuth 2.0 Token Revocation standard.
183
- *
184
- * This function uses HTTP Basic Authentication with client credentials and follows
185
- * the RFC 7009 specification for token revocation.
186
- *
187
- * @example
188
- * ```typescript
189
- * await revokeToken({
190
- * clientId: 'your-client-id',
191
- * clientSecret: 'your-client-secret',
192
- * token: 'access-token-to-revoke'
193
- * })
194
- * ```
195
- *
196
- * @returns True if revocation was successful
197
- * @see https://datatracker.ietf.org/doc/html/rfc7009
198
- * @see https://developer.todoist.com/api/v1/#tag/Authorization
199
- */
200
- async function revokeToken(args, options) {
201
- if (typeof options === 'string') {
202
- throw new TypeError('Passing baseUrl as a string is no longer supported. Use an options object instead: revokeToken(args, { baseUrl })');
203
- }
204
- const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
205
- const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
206
- const { clientId, clientSecret, token } = args;
207
- // Create Basic Auth header as per RFC 7009
208
- const basicAuth = createBasicAuthHeader(clientId, clientSecret);
209
- const customHeaders = {
210
- Authorization: `Basic ${basicAuth}`,
211
- };
212
- // Request body only contains the token and optional token_type_hint
213
- const requestBody = {
214
- token,
215
- token_type_hint: 'access_token',
216
- };
217
- const response = await (0, http_client_1.request)({
218
- httpMethod: 'POST',
219
- baseUri: (0, endpoints_1.getSyncBaseUri)(baseUrl),
220
- relativePath: endpoints_1.ENDPOINT_REVOKE,
221
- apiToken: undefined,
222
- payload: requestBody,
223
- requestId: undefined,
224
- hasSyncCommands: false,
225
- customHeaders: customHeaders,
226
- customFetch,
227
- });
228
- return (0, http_client_1.isSuccess)(response);
229
- }
230
- /**
231
- * Migrates a personal API token to an OAuth access token.
232
- *
233
- * This allows applications to transition users from personal API tokens
234
- * to proper OAuth tokens without requiring the user to go through the
235
- * full OAuth authorization flow.
236
- *
237
- * @example
238
- * ```typescript
239
- * const { accessToken } = await migratePersonalToken({
240
- * clientId: 'your-client-id',
241
- * clientSecret: 'your-client-secret',
242
- * personalToken: 'user-personal-token',
243
- * scope: 'data:read_write,data:delete'
244
- * })
245
- * ```
246
- *
247
- * @returns The new OAuth token response
248
- * @throws {@link TodoistRequestError} If the migration fails
249
- */
250
- async function migratePersonalToken(args, options) {
251
- var _a;
252
- const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
253
- const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
254
- try {
255
- const response = await (0, http_client_1.request)({
256
- httpMethod: 'POST',
257
- baseUri: (0, endpoints_1.getSyncBaseUri)(baseUrl),
258
- relativePath: endpoints_1.ENDPOINT_REST_ACCESS_TOKENS_MIGRATE,
259
- apiToken: undefined,
260
- payload: Object.assign(Object.assign({}, args), { scope: args.scope.join(',') }),
261
- customFetch,
262
- });
263
- if (response.status !== 200 || !((_a = response.data) === null || _a === void 0 ? void 0 : _a.accessToken)) {
264
- throw new types_1.TodoistRequestError('Personal token migration failed.', response.status, response.data);
265
- }
266
- return response.data;
267
- }
268
- catch (error) {
269
- const err = error;
270
- throw new types_1.TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
271
- }
272
- }
273
- /**
274
- * Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
275
- *
276
- * @example
277
- * ```typescript
278
- * const client = await registerClient({
279
- * redirectUris: ['https://example.com/callback'],
280
- * clientName: 'My App',
281
- * scope: ['data:read_write', 'task:add'],
282
- * })
283
- * // Use client.clientId and client.clientSecret for OAuth flows
284
- * ```
285
- *
286
- * @returns The registered client details
287
- * @throws {@link TodoistRequestError} If the registration fails
288
- * @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
289
- */
290
- async function registerClient(args, options) {
291
- var _a, _b;
292
- const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
293
- const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
294
- try {
295
- const response = await (0, http_client_1.request)({
296
- httpMethod: 'POST',
297
- baseUri: (0, endpoints_1.getAuthBaseUri)(baseUrl),
298
- relativePath: endpoints_1.ENDPOINT_REGISTER,
299
- apiToken: undefined,
300
- payload: Object.assign(Object.assign({}, args), { scope: (_a = args.scope) === null || _a === void 0 ? void 0 : _a.join(' ') }),
301
- customFetch,
302
- });
303
- if (!(0, http_client_1.isSuccess)(response) || !((_b = response.data) === null || _b === void 0 ? void 0 : _b.clientId)) {
304
- throw new types_1.TodoistRequestError('Dynamic client registration failed.', response.status, response.data);
305
- }
306
- const _c = response.data, { clientIdIssuedAt, clientSecretExpiresAt, scope } = _c, rest = __rest(_c, ["clientIdIssuedAt", "clientSecretExpiresAt", "scope"]);
307
- return Object.assign(Object.assign({}, rest), { scope: scope ? scope.split(' ') : undefined, clientIdIssuedAt: clientIdIssuedAt !== undefined ? new Date(clientIdIssuedAt * 1000) : undefined, clientSecretExpiresAt: clientSecretExpiresAt === undefined
308
- ? undefined
309
- : clientSecretExpiresAt === 0
310
- ? null
311
- : new Date(clientSecretExpiresAt * 1000) });
312
- }
313
- catch (error) {
314
- const err = error;
315
- throw new types_1.TodoistRequestError('Dynamic client registration failed.', err.httpStatusCode, err.responseData);
316
- }
317
- }
@@ -1,63 +0,0 @@
1
- "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.ActivityClient = void 0;
15
- const endpoints_1 = require("../consts/endpoints");
16
- const http_client_1 = require("../transport/http-client");
17
- const activity_helpers_1 = require("../utils/activity-helpers");
18
- const url_helpers_1 = require("../utils/url-helpers");
19
- const validators_1 = require("../utils/validators");
20
- const base_client_1 = require("./base-client");
21
- /**
22
- * Internal sub-client handling the activity-log endpoint.
23
- *
24
- * Instantiated by `TodoistApi`; the public `getActivityLogs` method on
25
- * `TodoistApi` delegates here. See `todoist-api.ts` for user-facing
26
- * JSDoc.
27
- */
28
- class ActivityClient extends base_client_1.BaseClient {
29
- async getActivityLogs(args = {}) {
30
- // Convert Date objects to YYYY-MM-DD strings
31
- const dateFrom = args.dateFrom instanceof Date ? (0, url_helpers_1.formatDateToYYYYMMDD)(args.dateFrom) : args.dateFrom;
32
- const dateTo = args.dateTo instanceof Date ? (0, url_helpers_1.formatDateToYYYYMMDD)(args.dateTo) : args.dateTo;
33
- // Destructure out raw date, filter-type, and removed legacy fields so they don't leak into payload
34
- const _a = args, { dateFrom: _dateFrom, dateTo: _dateTo, objectEventTypes, objectType: _objectType, eventType: _eventType, since: _since, until: _until } = _a, rest = __rest(_a, ["dateFrom", "dateTo", "objectEventTypes", "objectType", "eventType", "since", "until"]);
35
- // Build normalized objectEventTypes for the API
36
- let normalizedObjectEventTypes;
37
- if (objectEventTypes !== undefined) {
38
- const arr = Array.isArray(objectEventTypes) ? objectEventTypes : [objectEventTypes];
39
- normalizedObjectEventTypes = arr.map(activity_helpers_1.normalizeObjectEventTypeForApi);
40
- }
41
- const processedArgs = Object.assign(Object.assign(Object.assign(Object.assign({}, rest), (dateFrom !== undefined ? { dateFrom } : {})), (dateTo !== undefined ? { dateTo } : {})), (normalizedObjectEventTypes !== undefined
42
- ? { objectEventTypes: normalizedObjectEventTypes }
43
- : {}));
44
- const { data: { results, nextCursor }, } = await (0, http_client_1.request)({
45
- httpMethod: 'GET',
46
- baseUri: this.syncApiBase,
47
- relativePath: endpoints_1.ENDPOINT_REST_ACTIVITIES,
48
- apiToken: this.authToken,
49
- customFetch: this.customFetch,
50
- payload: processedArgs,
51
- });
52
- // Convert legacy API object types back to modern SDK types
53
- const normalizedResults = results.map((event) => {
54
- const normalizedType = (0, activity_helpers_1.denormalizeObjectTypeFromApi)(event.objectType);
55
- return Object.assign(Object.assign({}, event), { objectType: normalizedType || event.objectType });
56
- });
57
- return {
58
- results: (0, validators_1.validateActivityEventArray)(normalizedResults),
59
- nextCursor,
60
- };
61
- }
62
- }
63
- exports.ActivityClient = ActivityClient;