@doist/todoist-sdk 8.0.0 → 8.1.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.
- package/dist/cjs/authentication.js +74 -7
- package/dist/cjs/consts/endpoints.js +2 -1
- package/dist/cjs/test-utils/test-defaults.js +51 -1
- package/dist/cjs/todoist-api.js +18 -5
- package/dist/esm/authentication.js +73 -7
- package/dist/esm/consts/endpoints.js +1 -0
- package/dist/esm/test-utils/test-defaults.js +50 -0
- package/dist/esm/todoist-api.js +19 -6
- package/dist/types/authentication.d.ts +73 -5
- package/dist/types/consts/endpoints.d.ts +1 -0
- package/dist/types/test-utils/test-defaults.d.ts +7 -1
- package/dist/types/todoist-api.d.ts +8 -5
- package/dist/types/types/projects/requests.d.ts +21 -0
- package/package.json +1 -1
|
@@ -1,11 +1,23 @@
|
|
|
1
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
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PERMISSIONS = void 0;
|
|
14
|
+
exports.TOKEN_ENDPOINT_AUTH_METHODS = exports.PERMISSIONS = void 0;
|
|
4
15
|
exports.getAuthStateParameter = getAuthStateParameter;
|
|
5
16
|
exports.getAuthorizationUrl = getAuthorizationUrl;
|
|
6
17
|
exports.getAuthToken = getAuthToken;
|
|
7
18
|
exports.revokeToken = revokeToken;
|
|
8
19
|
exports.migratePersonalToken = migratePersonalToken;
|
|
20
|
+
exports.registerClient = registerClient;
|
|
9
21
|
const http_client_1 = require("./transport/http-client");
|
|
10
22
|
const uuid_1 = require("uuid");
|
|
11
23
|
const types_1 = require("./types");
|
|
@@ -19,6 +31,12 @@ exports.PERMISSIONS = [
|
|
|
19
31
|
'project:delete',
|
|
20
32
|
'backups:read',
|
|
21
33
|
];
|
|
34
|
+
/** Supported token endpoint authentication methods for dynamic client registration. */
|
|
35
|
+
exports.TOKEN_ENDPOINT_AUTH_METHODS = [
|
|
36
|
+
'client_secret_post',
|
|
37
|
+
'client_secret_basic',
|
|
38
|
+
'none',
|
|
39
|
+
];
|
|
22
40
|
/**
|
|
23
41
|
* Creates a Basic Authentication header value from client credentials.
|
|
24
42
|
* @param clientId - The OAuth client ID
|
|
@@ -48,13 +66,17 @@ function getAuthStateParameter() {
|
|
|
48
66
|
/**
|
|
49
67
|
* Generates the authorization URL for the OAuth2 flow.
|
|
50
68
|
*
|
|
69
|
+
* The `clientId` can be either a traditional client ID string (e.g. from
|
|
70
|
+
* {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
|
|
71
|
+
* as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
|
|
72
|
+
*
|
|
51
73
|
* @example
|
|
52
74
|
* ```typescript
|
|
53
|
-
* const url = getAuthorizationUrl(
|
|
54
|
-
* 'your-client-id',
|
|
55
|
-
* ['data:read', 'task:add'],
|
|
56
|
-
* state
|
|
57
|
-
* )
|
|
75
|
+
* const url = getAuthorizationUrl({
|
|
76
|
+
* clientId: 'your-client-id',
|
|
77
|
+
* permissions: ['data:read', 'task:add'],
|
|
78
|
+
* state,
|
|
79
|
+
* })
|
|
58
80
|
* // Redirect user to url
|
|
59
81
|
* ```
|
|
60
82
|
*
|
|
@@ -66,7 +88,7 @@ function getAuthorizationUrl({ clientId, permissions, state, baseUrl, }) {
|
|
|
66
88
|
throw new Error('At least one scope value should be passed for permissions.');
|
|
67
89
|
}
|
|
68
90
|
const scope = permissions.join(',');
|
|
69
|
-
return `${(0, endpoints_1.getAuthBaseUri)(baseUrl)}${endpoints_1.ENDPOINT_AUTHORIZATION}?client_id=${clientId}&scope=${scope}&state=${state}`;
|
|
91
|
+
return `${(0, endpoints_1.getAuthBaseUri)(baseUrl)}${endpoints_1.ENDPOINT_AUTHORIZATION}?client_id=${encodeURIComponent(clientId)}&scope=${scope}&state=${state}`;
|
|
70
92
|
}
|
|
71
93
|
/**
|
|
72
94
|
* Exchanges an authorization code for an access token.
|
|
@@ -202,3 +224,48 @@ async function migratePersonalToken(args, options) {
|
|
|
202
224
|
throw new types_1.TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
|
|
203
225
|
}
|
|
204
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const client = await registerClient({
|
|
233
|
+
* redirectUris: ['https://example.com/callback'],
|
|
234
|
+
* clientName: 'My App',
|
|
235
|
+
* scope: ['data:read_write', 'task:add'],
|
|
236
|
+
* })
|
|
237
|
+
* // Use client.clientId and client.clientSecret for OAuth flows
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* @returns The registered client details
|
|
241
|
+
* @throws {@link TodoistRequestError} If the registration fails
|
|
242
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
243
|
+
*/
|
|
244
|
+
async function registerClient(args, options) {
|
|
245
|
+
var _a, _b;
|
|
246
|
+
const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
|
|
247
|
+
const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
|
|
248
|
+
try {
|
|
249
|
+
const response = await (0, http_client_1.request)({
|
|
250
|
+
httpMethod: 'POST',
|
|
251
|
+
baseUri: (0, endpoints_1.getAuthBaseUri)(baseUrl),
|
|
252
|
+
relativePath: endpoints_1.ENDPOINT_REGISTER,
|
|
253
|
+
apiToken: undefined,
|
|
254
|
+
payload: Object.assign(Object.assign({}, args), { scope: (_a = args.scope) === null || _a === void 0 ? void 0 : _a.join(' ') }),
|
|
255
|
+
customFetch,
|
|
256
|
+
});
|
|
257
|
+
if (!(0, http_client_1.isSuccess)(response) || !((_b = response.data) === null || _b === void 0 ? void 0 : _b.clientId)) {
|
|
258
|
+
throw new types_1.TodoistRequestError('Dynamic client registration failed.', response.status, response.data);
|
|
259
|
+
}
|
|
260
|
+
const _c = response.data, { clientIdIssuedAt, clientSecretExpiresAt, scope } = _c, rest = __rest(_c, ["clientIdIssuedAt", "clientSecretExpiresAt", "scope"]);
|
|
261
|
+
return Object.assign(Object.assign({}, rest), { scope: scope ? scope.split(' ') : undefined, clientIdIssuedAt: clientIdIssuedAt !== undefined ? new Date(clientIdIssuedAt * 1000) : undefined, clientSecretExpiresAt: clientSecretExpiresAt === undefined
|
|
262
|
+
? undefined
|
|
263
|
+
: clientSecretExpiresAt === 0
|
|
264
|
+
? null
|
|
265
|
+
: new Date(clientSecretExpiresAt * 1000) });
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
const err = error;
|
|
269
|
+
throw new types_1.TodoistRequestError('Dynamic client registration failed.', err.httpStatusCode, err.responseData);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ENDPOINT_REST_ID_MAPPINGS = exports.ENDPOINT_REST_EMAILS = exports.ENDPOINT_REST_BACKUPS_DOWNLOAD = exports.ENDPOINT_REST_BACKUPS = exports.ENDPOINT_REST_ACCESS_TOKENS_MIGRATE = exports.ENDPOINT_REST_TEMPLATES_IMPORT_FROM_ID = exports.ENDPOINT_REST_TEMPLATES_IMPORT_FROM_FILE = exports.ENDPOINT_REST_TEMPLATES_CREATE_FROM_FILE = exports.ENDPOINT_REST_TEMPLATES_URL = exports.ENDPOINT_REST_TEMPLATES_FILE = exports.ENDPOINT_REST_TASKS_COMPLETED = exports.ENDPOINT_REST_PROJECTS_MOVE_TO_PERSONAL = exports.ENDPOINT_REST_PROJECTS_MOVE_TO_WORKSPACE = exports.SECTION_UNARCHIVE = exports.SECTION_ARCHIVE = exports.ENDPOINT_REST_PROJECT_JOIN = exports.ENDPOINT_REST_PROJECT_FULL = exports.ENDPOINT_REST_PROJECTS_PERMISSIONS = exports.ENDPOINT_REST_PROJECTS_ARCHIVED_COUNT = exports.PROJECT_UNARCHIVE = exports.PROJECT_ARCHIVE = exports.ENDPOINT_REST_UPLOADS = exports.ENDPOINT_REST_ACTIVITIES = exports.ENDPOINT_REST_PRODUCTIVITY = exports.ENDPOINT_REST_USER = exports.ENDPOINT_REST_PROJECT_COLLABORATORS = exports.ENDPOINT_REST_PROJECTS_ARCHIVED = exports.ENDPOINT_REST_PROJECTS_SEARCH = exports.ENDPOINT_REST_PROJECTS = exports.ENDPOINT_REST_TASK_MOVE = exports.ENDPOINT_REST_TASK_REOPEN = exports.ENDPOINT_REST_TASK_CLOSE = exports.ENDPOINT_REST_LOCATION_REMINDERS = exports.ENDPOINT_REST_REMINDERS = exports.ENDPOINT_REST_COMMENTS = exports.ENDPOINT_REST_LABELS_SHARED_REMOVE = exports.ENDPOINT_REST_LABELS_SHARED_RENAME = exports.ENDPOINT_REST_LABELS_SHARED = exports.ENDPOINT_REST_LABELS_SEARCH = exports.ENDPOINT_REST_LABELS = exports.ENDPOINT_REST_SECTIONS_SEARCH = exports.ENDPOINT_REST_SECTIONS = exports.ENDPOINT_REST_TASKS_COMPLETED_SEARCH = exports.ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE = exports.ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE = exports.ENDPOINT_REST_TASKS_FILTER = exports.ENDPOINT_REST_TASKS = exports.API_BASE_URI = exports.API_VERSION = exports.TODOIST_WEB_URI = void 0;
|
|
4
|
-
exports.ENDPOINT_WORKSPACE_MEMBERS = exports.ENDPOINT_WORKSPACE_USERS = exports.ENDPOINT_WORKSPACE_PLAN_DETAILS = exports.ENDPOINT_WORKSPACE_LOGO = exports.ENDPOINT_WORKSPACE_JOIN = exports.ENDPOINT_WORKSPACE_INVITATIONS_DELETE = exports.ENDPOINT_WORKSPACE_INVITATIONS_ALL = exports.ENDPOINT_WORKSPACE_INVITATIONS = exports.ENDPOINT_REST_WORKSPACES = exports.ENDPOINT_REST_FOLDERS = exports.ENDPOINT_REVOKE = exports.ENDPOINT_GET_TOKEN = exports.ENDPOINT_AUTHORIZATION = exports.ENDPOINT_SYNC = exports.ENDPOINT_SYNC_QUICK_ADD = exports.ENDPOINT_REST_MOVED_IDS = void 0;
|
|
4
|
+
exports.ENDPOINT_WORKSPACE_MEMBERS = exports.ENDPOINT_WORKSPACE_USERS = exports.ENDPOINT_WORKSPACE_PLAN_DETAILS = exports.ENDPOINT_WORKSPACE_LOGO = exports.ENDPOINT_WORKSPACE_JOIN = exports.ENDPOINT_WORKSPACE_INVITATIONS_DELETE = exports.ENDPOINT_WORKSPACE_INVITATIONS_ALL = exports.ENDPOINT_WORKSPACE_INVITATIONS = exports.ENDPOINT_REST_WORKSPACES = exports.ENDPOINT_REST_FOLDERS = exports.ENDPOINT_REGISTER = exports.ENDPOINT_REVOKE = exports.ENDPOINT_GET_TOKEN = exports.ENDPOINT_AUTHORIZATION = exports.ENDPOINT_SYNC = exports.ENDPOINT_SYNC_QUICK_ADD = exports.ENDPOINT_REST_MOVED_IDS = void 0;
|
|
5
5
|
exports.getSyncBaseUri = getSyncBaseUri;
|
|
6
6
|
exports.getAuthBaseUri = getAuthBaseUri;
|
|
7
7
|
exports.getWorkspaceInvitationAcceptEndpoint = getWorkspaceInvitationAcceptEndpoint;
|
|
@@ -84,6 +84,7 @@ exports.ENDPOINT_SYNC = 'sync';
|
|
|
84
84
|
exports.ENDPOINT_AUTHORIZATION = 'authorize';
|
|
85
85
|
exports.ENDPOINT_GET_TOKEN = 'access_token';
|
|
86
86
|
exports.ENDPOINT_REVOKE = 'revoke';
|
|
87
|
+
exports.ENDPOINT_REGISTER = 'register';
|
|
87
88
|
exports.ENDPOINT_REST_FOLDERS = 'folders';
|
|
88
89
|
// Workspace endpoints
|
|
89
90
|
exports.ENDPOINT_REST_WORKSPACES = 'workspaces';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_FOLDER = exports.COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT = exports.RAW_COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT = exports.COMMENT_WITH_ATTACHMENT_WITH_OPTIONALS_AS_NULL = exports.RAW_COMMENT_WITH_ATTACHMENT_WITH_OPTIONALS_AS_NULL = exports.COMMENT_WITH_OPTIONALS_AS_NULL_TASK = exports.RAW_COMMENT_WITH_OPTIONALS_AS_NULL_TASK = exports.INVALID_COMMENT = exports.DEFAULT_LOCATION_REMINDER = exports.DEFAULT_ABSOLUTE_REMINDER = exports.DEFAULT_RELATIVE_REMINDER = exports.DEFAULT_REMINDER_ID = exports.DEFAULT_COMMENT = exports.DEFAULT_RAW_COMMENT = exports.INVALID_ATTACHMENT = exports.DEFAULT_ATTACHMENT = exports.INVALID_USER = exports.DEFAULT_USER = exports.INVALID_LABEL = exports.DEFAULT_LABEL = exports.INVALID_SECTION = exports.DEFAULT_SECTION = exports.PROJECT_WITH_OPTIONALS_AS_NULL = exports.INVALID_PROJECT = exports.DEFAULT_PROJECT = exports.TASK_WITH_OPTIONALS_AS_NULL = exports.INVALID_TASK = exports.DEFAULT_TASK = exports.DEFAULT_DEADLINE = exports.DEFAULT_DURATION = exports.DEFAULT_DUE_DATE = exports.INVALID_ENTITY_ID = exports.DEFAULT_REQUEST_ID = exports.DEFAULT_AUTH_TOKEN = exports.DEFAULT_PROJECT_VIEW_STYLE = exports.DEFAULT_PROJECT_NAME = exports.DEFAULT_PROJECT_ID = exports.DEFAULT_ORDER = exports.DEFAULT_TASK_PRIORITY = exports.DEFAULT_TASK_DESCRIPTION = exports.DEFAULT_TASK_CONTENT = exports.DEFAULT_TASK_ID = void 0;
|
|
3
|
+
exports.DEFAULT_NOTE = exports.DEFAULT_COLLABORATOR_STATE = exports.DEFAULT_COLLABORATOR = exports.DEFAULT_FOLDER = exports.COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT = exports.RAW_COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT = exports.COMMENT_WITH_ATTACHMENT_WITH_OPTIONALS_AS_NULL = exports.RAW_COMMENT_WITH_ATTACHMENT_WITH_OPTIONALS_AS_NULL = exports.COMMENT_WITH_OPTIONALS_AS_NULL_TASK = exports.RAW_COMMENT_WITH_OPTIONALS_AS_NULL_TASK = exports.INVALID_COMMENT = exports.DEFAULT_LOCATION_REMINDER = exports.DEFAULT_ABSOLUTE_REMINDER = exports.DEFAULT_RELATIVE_REMINDER = exports.DEFAULT_REMINDER_ID = exports.DEFAULT_COMMENT = exports.DEFAULT_RAW_COMMENT = exports.INVALID_ATTACHMENT = exports.DEFAULT_ATTACHMENT = exports.INVALID_USER = exports.DEFAULT_USER = exports.INVALID_LABEL = exports.DEFAULT_LABEL = exports.INVALID_SECTION = exports.DEFAULT_SECTION = exports.DEFAULT_WORKSPACE_PROJECT = exports.PROJECT_WITH_OPTIONALS_AS_NULL = exports.INVALID_PROJECT = exports.DEFAULT_PROJECT = exports.TASK_WITH_OPTIONALS_AS_NULL = exports.INVALID_TASK = exports.DEFAULT_TASK = exports.DEFAULT_DEADLINE = exports.DEFAULT_DURATION = exports.DEFAULT_DUE_DATE = exports.INVALID_ENTITY_ID = exports.DEFAULT_REQUEST_ID = exports.DEFAULT_AUTH_TOKEN = exports.DEFAULT_PROJECT_VIEW_STYLE = exports.DEFAULT_PROJECT_NAME = exports.DEFAULT_PROJECT_ID = exports.DEFAULT_ORDER = exports.DEFAULT_TASK_PRIORITY = exports.DEFAULT_TASK_DESCRIPTION = exports.DEFAULT_TASK_CONTENT = exports.DEFAULT_TASK_ID = void 0;
|
|
4
4
|
const url_helpers_1 = require("../utils/url-helpers");
|
|
5
5
|
exports.DEFAULT_TASK_ID = '1234';
|
|
6
6
|
exports.DEFAULT_TASK_CONTENT = 'This is a task';
|
|
@@ -131,6 +131,32 @@ exports.DEFAULT_PROJECT = {
|
|
|
131
131
|
};
|
|
132
132
|
exports.INVALID_PROJECT = Object.assign(Object.assign({}, exports.DEFAULT_PROJECT), { name: 123 });
|
|
133
133
|
exports.PROJECT_WITH_OPTIONALS_AS_NULL = Object.assign(Object.assign({}, exports.DEFAULT_PROJECT), { parentId: null });
|
|
134
|
+
exports.DEFAULT_WORKSPACE_PROJECT = {
|
|
135
|
+
id: exports.DEFAULT_PROJECT_ID,
|
|
136
|
+
name: exports.DEFAULT_PROJECT_NAME,
|
|
137
|
+
color: DEFAULT_ENTITY_COLOR,
|
|
138
|
+
childOrder: exports.DEFAULT_ORDER,
|
|
139
|
+
isFavorite: false,
|
|
140
|
+
isShared: true,
|
|
141
|
+
viewStyle: exports.DEFAULT_PROJECT_VIEW_STYLE,
|
|
142
|
+
canAssignTasks: DEFAULT_CAN_ASSIGN_TASKS,
|
|
143
|
+
isArchived: DEFAULT_IS_ARCHIVED,
|
|
144
|
+
isDeleted: DEFAULT_IS_DELETED,
|
|
145
|
+
isFrozen: DEFAULT_IS_FROZEN,
|
|
146
|
+
createdAt: DEFAULT_DATE,
|
|
147
|
+
updatedAt: DEFAULT_DATE,
|
|
148
|
+
defaultOrder: exports.DEFAULT_ORDER,
|
|
149
|
+
description: '',
|
|
150
|
+
isCollapsed: DEFAULT_IS_COLLAPSED,
|
|
151
|
+
url: DEFAULT_PROJECT_URL,
|
|
152
|
+
workspaceId: '100',
|
|
153
|
+
folderId: null,
|
|
154
|
+
collaboratorRoleDefault: 'READ_WRITE',
|
|
155
|
+
isInviteOnly: false,
|
|
156
|
+
isLinkSharingEnabled: true,
|
|
157
|
+
role: 'ADMIN',
|
|
158
|
+
status: 'ACTIVE',
|
|
159
|
+
};
|
|
134
160
|
exports.DEFAULT_SECTION = {
|
|
135
161
|
id: DEFAULT_SECTION_ID,
|
|
136
162
|
userId: DEFAULT_USER_ID,
|
|
@@ -238,3 +264,27 @@ exports.DEFAULT_FOLDER = {
|
|
|
238
264
|
childOrder: 3,
|
|
239
265
|
isDeleted: false,
|
|
240
266
|
};
|
|
267
|
+
exports.DEFAULT_COLLABORATOR = {
|
|
268
|
+
id: DEFAULT_USER_ID,
|
|
269
|
+
email: DEFAULT_USER_EMAIL,
|
|
270
|
+
fullName: DEFAULT_USER_NAME,
|
|
271
|
+
timezone: 'UTC',
|
|
272
|
+
imageId: null,
|
|
273
|
+
};
|
|
274
|
+
exports.DEFAULT_COLLABORATOR_STATE = {
|
|
275
|
+
userId: DEFAULT_USER_ID,
|
|
276
|
+
projectId: exports.DEFAULT_PROJECT_ID,
|
|
277
|
+
state: 'active',
|
|
278
|
+
isDeleted: false,
|
|
279
|
+
};
|
|
280
|
+
exports.DEFAULT_NOTE = {
|
|
281
|
+
id: DEFAULT_COMMENT_ID,
|
|
282
|
+
projectId: exports.DEFAULT_PROJECT_ID,
|
|
283
|
+
content: DEFAULT_COMMENT_CONTENT,
|
|
284
|
+
postedAt: DEFAULT_DATE,
|
|
285
|
+
fileAttachment: exports.DEFAULT_ATTACHMENT,
|
|
286
|
+
postedUid: DEFAULT_USER_ID,
|
|
287
|
+
uidsToNotify: null,
|
|
288
|
+
reactions: DEFAULT_COMMENT_REACTIONS,
|
|
289
|
+
isDeleted: false,
|
|
290
|
+
};
|
package/dist/cjs/todoist-api.js
CHANGED
|
@@ -12,6 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.TodoistApi = void 0;
|
|
15
|
+
const projects_1 = require("./types/projects");
|
|
15
16
|
const reminders_1 = require("./types/reminders");
|
|
16
17
|
const http_client_1 = require("./transport/http-client");
|
|
17
18
|
const endpoints_1 = require("./consts/endpoints");
|
|
@@ -771,15 +772,18 @@ class TodoistApi {
|
|
|
771
772
|
};
|
|
772
773
|
}
|
|
773
774
|
/**
|
|
774
|
-
* Joins a
|
|
775
|
+
* Joins a workspace project.
|
|
775
776
|
*
|
|
776
|
-
*
|
|
777
|
+
* Only used for workspaces — this endpoint is used to join a workspace project
|
|
778
|
+
* by a workspace user.
|
|
779
|
+
*
|
|
780
|
+
* @param id - The unique identifier of the workspace project to join.
|
|
777
781
|
* @param requestId - Optional custom identifier for the request.
|
|
778
|
-
* @returns A promise that resolves to the
|
|
782
|
+
* @returns A promise that resolves to the full project data after joining.
|
|
779
783
|
*/
|
|
780
784
|
async joinProject(id, requestId) {
|
|
781
785
|
zod_1.z.string().parse(id);
|
|
782
|
-
const
|
|
786
|
+
const { data } = await (0, http_client_1.request)({
|
|
783
787
|
httpMethod: 'POST',
|
|
784
788
|
baseUri: this.syncApiBase,
|
|
785
789
|
relativePath: generatePath(endpoints_1.ENDPOINT_REST_PROJECTS, id, endpoints_1.ENDPOINT_REST_PROJECT_JOIN),
|
|
@@ -787,7 +791,16 @@ class TodoistApi {
|
|
|
787
791
|
customFetch: this.customFetch,
|
|
788
792
|
requestId: requestId,
|
|
789
793
|
});
|
|
790
|
-
return
|
|
794
|
+
return {
|
|
795
|
+
project: projects_1.WorkspaceProjectSchema.parse(data.project),
|
|
796
|
+
tasks: (0, validators_1.validateTaskArray)(data.tasks),
|
|
797
|
+
sections: (0, validators_1.validateSectionArray)(data.sections),
|
|
798
|
+
comments: (0, validators_1.validateNoteArray)(data.comments),
|
|
799
|
+
collaborators: (0, validators_1.validateCollaboratorArray)(data.collaborators),
|
|
800
|
+
collaboratorStates: (0, validators_1.validateCollaboratorStateArray)(data.collaboratorStates),
|
|
801
|
+
folder: data.folder ? (0, validators_1.validateFolder)(data.folder) : null,
|
|
802
|
+
subprojects: data.subprojects.map((p) => projects_1.WorkspaceProjectSchema.parse(p)),
|
|
803
|
+
};
|
|
791
804
|
}
|
|
792
805
|
/**
|
|
793
806
|
* Retrieves a list of collaborators for a specific project.
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
1
12
|
import { request, isSuccess } from './transport/http-client.js';
|
|
2
13
|
import { v4 as uuid } from 'uuid';
|
|
3
14
|
import { TodoistRequestError } from './types/index.js';
|
|
4
|
-
import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, ENDPOINT_REST_ACCESS_TOKENS_MIGRATE, } from './consts/endpoints.js';
|
|
15
|
+
import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, ENDPOINT_REGISTER, ENDPOINT_REST_ACCESS_TOKENS_MIGRATE, } from './consts/endpoints.js';
|
|
5
16
|
/** Available OAuth2 permission scopes. */
|
|
6
17
|
export const PERMISSIONS = [
|
|
7
18
|
'task:add',
|
|
@@ -11,6 +22,12 @@ export const PERMISSIONS = [
|
|
|
11
22
|
'project:delete',
|
|
12
23
|
'backups:read',
|
|
13
24
|
];
|
|
25
|
+
/** Supported token endpoint authentication methods for dynamic client registration. */
|
|
26
|
+
export const TOKEN_ENDPOINT_AUTH_METHODS = [
|
|
27
|
+
'client_secret_post',
|
|
28
|
+
'client_secret_basic',
|
|
29
|
+
'none',
|
|
30
|
+
];
|
|
14
31
|
/**
|
|
15
32
|
* Creates a Basic Authentication header value from client credentials.
|
|
16
33
|
* @param clientId - The OAuth client ID
|
|
@@ -40,13 +57,17 @@ export function getAuthStateParameter() {
|
|
|
40
57
|
/**
|
|
41
58
|
* Generates the authorization URL for the OAuth2 flow.
|
|
42
59
|
*
|
|
60
|
+
* The `clientId` can be either a traditional client ID string (e.g. from
|
|
61
|
+
* {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
|
|
62
|
+
* as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
|
|
63
|
+
*
|
|
43
64
|
* @example
|
|
44
65
|
* ```typescript
|
|
45
|
-
* const url = getAuthorizationUrl(
|
|
46
|
-
* 'your-client-id',
|
|
47
|
-
* ['data:read', 'task:add'],
|
|
48
|
-
* state
|
|
49
|
-
* )
|
|
66
|
+
* const url = getAuthorizationUrl({
|
|
67
|
+
* clientId: 'your-client-id',
|
|
68
|
+
* permissions: ['data:read', 'task:add'],
|
|
69
|
+
* state,
|
|
70
|
+
* })
|
|
50
71
|
* // Redirect user to url
|
|
51
72
|
* ```
|
|
52
73
|
*
|
|
@@ -58,7 +79,7 @@ export function getAuthorizationUrl({ clientId, permissions, state, baseUrl, })
|
|
|
58
79
|
throw new Error('At least one scope value should be passed for permissions.');
|
|
59
80
|
}
|
|
60
81
|
const scope = permissions.join(',');
|
|
61
|
-
return `${getAuthBaseUri(baseUrl)}${ENDPOINT_AUTHORIZATION}?client_id=${clientId}&scope=${scope}&state=${state}`;
|
|
82
|
+
return `${getAuthBaseUri(baseUrl)}${ENDPOINT_AUTHORIZATION}?client_id=${encodeURIComponent(clientId)}&scope=${scope}&state=${state}`;
|
|
62
83
|
}
|
|
63
84
|
/**
|
|
64
85
|
* Exchanges an authorization code for an access token.
|
|
@@ -194,3 +215,48 @@ export async function migratePersonalToken(args, options) {
|
|
|
194
215
|
throw new TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
|
|
195
216
|
}
|
|
196
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* const client = await registerClient({
|
|
224
|
+
* redirectUris: ['https://example.com/callback'],
|
|
225
|
+
* clientName: 'My App',
|
|
226
|
+
* scope: ['data:read_write', 'task:add'],
|
|
227
|
+
* })
|
|
228
|
+
* // Use client.clientId and client.clientSecret for OAuth flows
|
|
229
|
+
* ```
|
|
230
|
+
*
|
|
231
|
+
* @returns The registered client details
|
|
232
|
+
* @throws {@link TodoistRequestError} If the registration fails
|
|
233
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
234
|
+
*/
|
|
235
|
+
export async function registerClient(args, options) {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
|
|
238
|
+
const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
|
|
239
|
+
try {
|
|
240
|
+
const response = await request({
|
|
241
|
+
httpMethod: 'POST',
|
|
242
|
+
baseUri: getAuthBaseUri(baseUrl),
|
|
243
|
+
relativePath: ENDPOINT_REGISTER,
|
|
244
|
+
apiToken: undefined,
|
|
245
|
+
payload: Object.assign(Object.assign({}, args), { scope: (_a = args.scope) === null || _a === void 0 ? void 0 : _a.join(' ') }),
|
|
246
|
+
customFetch,
|
|
247
|
+
});
|
|
248
|
+
if (!isSuccess(response) || !((_b = response.data) === null || _b === void 0 ? void 0 : _b.clientId)) {
|
|
249
|
+
throw new TodoistRequestError('Dynamic client registration failed.', response.status, response.data);
|
|
250
|
+
}
|
|
251
|
+
const _c = response.data, { clientIdIssuedAt, clientSecretExpiresAt, scope } = _c, rest = __rest(_c, ["clientIdIssuedAt", "clientSecretExpiresAt", "scope"]);
|
|
252
|
+
return Object.assign(Object.assign({}, rest), { scope: scope ? scope.split(' ') : undefined, clientIdIssuedAt: clientIdIssuedAt !== undefined ? new Date(clientIdIssuedAt * 1000) : undefined, clientSecretExpiresAt: clientSecretExpiresAt === undefined
|
|
253
|
+
? undefined
|
|
254
|
+
: clientSecretExpiresAt === 0
|
|
255
|
+
? null
|
|
256
|
+
: new Date(clientSecretExpiresAt * 1000) });
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
const err = error;
|
|
260
|
+
throw new TodoistRequestError('Dynamic client registration failed.', err.httpStatusCode, err.responseData);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
@@ -65,6 +65,7 @@ export const ENDPOINT_SYNC = 'sync';
|
|
|
65
65
|
export const ENDPOINT_AUTHORIZATION = 'authorize';
|
|
66
66
|
export const ENDPOINT_GET_TOKEN = 'access_token';
|
|
67
67
|
export const ENDPOINT_REVOKE = 'revoke';
|
|
68
|
+
export const ENDPOINT_REGISTER = 'register';
|
|
68
69
|
export const ENDPOINT_REST_FOLDERS = 'folders';
|
|
69
70
|
// Workspace endpoints
|
|
70
71
|
export const ENDPOINT_REST_WORKSPACES = 'workspaces';
|
|
@@ -128,6 +128,32 @@ export const DEFAULT_PROJECT = {
|
|
|
128
128
|
};
|
|
129
129
|
export const INVALID_PROJECT = Object.assign(Object.assign({}, DEFAULT_PROJECT), { name: 123 });
|
|
130
130
|
export const PROJECT_WITH_OPTIONALS_AS_NULL = Object.assign(Object.assign({}, DEFAULT_PROJECT), { parentId: null });
|
|
131
|
+
export const DEFAULT_WORKSPACE_PROJECT = {
|
|
132
|
+
id: DEFAULT_PROJECT_ID,
|
|
133
|
+
name: DEFAULT_PROJECT_NAME,
|
|
134
|
+
color: DEFAULT_ENTITY_COLOR,
|
|
135
|
+
childOrder: DEFAULT_ORDER,
|
|
136
|
+
isFavorite: false,
|
|
137
|
+
isShared: true,
|
|
138
|
+
viewStyle: DEFAULT_PROJECT_VIEW_STYLE,
|
|
139
|
+
canAssignTasks: DEFAULT_CAN_ASSIGN_TASKS,
|
|
140
|
+
isArchived: DEFAULT_IS_ARCHIVED,
|
|
141
|
+
isDeleted: DEFAULT_IS_DELETED,
|
|
142
|
+
isFrozen: DEFAULT_IS_FROZEN,
|
|
143
|
+
createdAt: DEFAULT_DATE,
|
|
144
|
+
updatedAt: DEFAULT_DATE,
|
|
145
|
+
defaultOrder: DEFAULT_ORDER,
|
|
146
|
+
description: '',
|
|
147
|
+
isCollapsed: DEFAULT_IS_COLLAPSED,
|
|
148
|
+
url: DEFAULT_PROJECT_URL,
|
|
149
|
+
workspaceId: '100',
|
|
150
|
+
folderId: null,
|
|
151
|
+
collaboratorRoleDefault: 'READ_WRITE',
|
|
152
|
+
isInviteOnly: false,
|
|
153
|
+
isLinkSharingEnabled: true,
|
|
154
|
+
role: 'ADMIN',
|
|
155
|
+
status: 'ACTIVE',
|
|
156
|
+
};
|
|
131
157
|
export const DEFAULT_SECTION = {
|
|
132
158
|
id: DEFAULT_SECTION_ID,
|
|
133
159
|
userId: DEFAULT_USER_ID,
|
|
@@ -235,3 +261,27 @@ export const DEFAULT_FOLDER = {
|
|
|
235
261
|
childOrder: 3,
|
|
236
262
|
isDeleted: false,
|
|
237
263
|
};
|
|
264
|
+
export const DEFAULT_COLLABORATOR = {
|
|
265
|
+
id: DEFAULT_USER_ID,
|
|
266
|
+
email: DEFAULT_USER_EMAIL,
|
|
267
|
+
fullName: DEFAULT_USER_NAME,
|
|
268
|
+
timezone: 'UTC',
|
|
269
|
+
imageId: null,
|
|
270
|
+
};
|
|
271
|
+
export const DEFAULT_COLLABORATOR_STATE = {
|
|
272
|
+
userId: DEFAULT_USER_ID,
|
|
273
|
+
projectId: DEFAULT_PROJECT_ID,
|
|
274
|
+
state: 'active',
|
|
275
|
+
isDeleted: false,
|
|
276
|
+
};
|
|
277
|
+
export const DEFAULT_NOTE = {
|
|
278
|
+
id: DEFAULT_COMMENT_ID,
|
|
279
|
+
projectId: DEFAULT_PROJECT_ID,
|
|
280
|
+
content: DEFAULT_COMMENT_CONTENT,
|
|
281
|
+
postedAt: DEFAULT_DATE,
|
|
282
|
+
fileAttachment: DEFAULT_ATTACHMENT,
|
|
283
|
+
postedUid: DEFAULT_USER_ID,
|
|
284
|
+
uidsToNotify: null,
|
|
285
|
+
reactions: DEFAULT_COMMENT_REACTIONS,
|
|
286
|
+
isDeleted: false,
|
|
287
|
+
};
|
package/dist/esm/todoist-api.js
CHANGED
|
@@ -9,10 +9,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
+
import { WorkspaceProjectSchema, } from './types/projects/index.js';
|
|
12
13
|
import { UpdateReminderArgsSchema, UpdateLocationReminderArgsSchema, ReminderIdSchema, } from './types/reminders/index.js';
|
|
13
14
|
import { request, isSuccess } from './transport/http-client.js';
|
|
14
15
|
import { getSyncBaseUri, ENDPOINT_REST_TASKS, ENDPOINT_REST_TASKS_FILTER, ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE, ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE, ENDPOINT_REST_TASKS_COMPLETED_SEARCH, ENDPOINT_REST_TASKS_COMPLETED, ENDPOINT_REST_TEMPLATES_FILE, ENDPOINT_REST_TEMPLATES_URL, ENDPOINT_REST_TEMPLATES_CREATE_FROM_FILE, ENDPOINT_REST_TEMPLATES_IMPORT_FROM_FILE, ENDPOINT_REST_TEMPLATES_IMPORT_FROM_ID, ENDPOINT_REST_PROJECTS, ENDPOINT_REST_PROJECTS_SEARCH, ENDPOINT_SYNC_QUICK_ADD, ENDPOINT_REST_TASK_CLOSE, ENDPOINT_REST_TASK_REOPEN, ENDPOINT_REST_TASK_MOVE, ENDPOINT_REST_LABELS, ENDPOINT_REST_LABELS_SEARCH, ENDPOINT_REST_PROJECT_COLLABORATORS, ENDPOINT_REST_SECTIONS, ENDPOINT_REST_SECTIONS_SEARCH, ENDPOINT_REST_COMMENTS, ENDPOINT_REST_LOCATION_REMINDERS, ENDPOINT_REST_REMINDERS, ENDPOINT_REST_LABELS_SHARED, ENDPOINT_REST_LABELS_SHARED_RENAME, ENDPOINT_REST_LABELS_SHARED_REMOVE, ENDPOINT_SYNC, PROJECT_ARCHIVE, PROJECT_UNARCHIVE, ENDPOINT_REST_PROJECTS_MOVE_TO_WORKSPACE, ENDPOINT_REST_PROJECTS_MOVE_TO_PERSONAL, ENDPOINT_REST_PROJECTS_ARCHIVED, ENDPOINT_REST_PROJECTS_ARCHIVED_COUNT, ENDPOINT_REST_PROJECTS_PERMISSIONS, ENDPOINT_REST_PROJECT_FULL, ENDPOINT_REST_PROJECT_JOIN, SECTION_ARCHIVE, SECTION_UNARCHIVE, ENDPOINT_REST_USER, ENDPOINT_REST_PRODUCTIVITY, ENDPOINT_REST_ACTIVITIES, ENDPOINT_REST_UPLOADS, getProjectInsightsActivityStatsEndpoint, getProjectInsightsHealthEndpoint, getProjectInsightsHealthContextEndpoint, getProjectInsightsProgressEndpoint, getProjectInsightsHealthAnalyzeEndpoint, getWorkspaceInsightsEndpoint, ENDPOINT_REST_BACKUPS, ENDPOINT_REST_BACKUPS_DOWNLOAD, ENDPOINT_REST_EMAILS, ENDPOINT_REST_ID_MAPPINGS, ENDPOINT_REST_MOVED_IDS, ENDPOINT_REST_WORKSPACES, ENDPOINT_WORKSPACE_MEMBERS, getWorkspaceUserTasksEndpoint, getWorkspaceInviteUsersEndpoint, getWorkspaceUserEndpoint, ENDPOINT_WORKSPACE_INVITATIONS, ENDPOINT_WORKSPACE_INVITATIONS_ALL, ENDPOINT_WORKSPACE_INVITATIONS_DELETE, getWorkspaceInvitationAcceptEndpoint, getWorkspaceInvitationRejectEndpoint, ENDPOINT_WORKSPACE_JOIN, ENDPOINT_WORKSPACE_LOGO, ENDPOINT_WORKSPACE_PLAN_DETAILS, ENDPOINT_WORKSPACE_USERS, getWorkspaceActiveProjectsEndpoint, getWorkspaceArchivedProjectsEndpoint, ENDPOINT_REST_FOLDERS, } from './consts/endpoints.js';
|
|
15
|
-
import { validateAttachment, validateComment, validateCommentArray, validateCurrentUser, validateLabel, validateLabelArray, validateProject, validateProjectArray, validateSection, validateSectionArray, validateTask, validateTaskArray, validateUserArray, validateProductivityStats, validateReminder, validateReminderArray, validateLocationReminderArray, validateActivityEventArray, validateWorkspaceUserArray, validateWorkspaceInvitation, validateWorkspaceInvitationArray, validateWorkspacePlanDetails, validateJoinWorkspaceResult, validateWorkspace, validateWorkspaceArray, validateMemberActivityInfoArray, validateWorkspaceUserTaskArray, validateProjectActivityStats, validateProjectHealth, validateProjectHealthContext, validateProjectProgress, validateWorkspaceInsights, validateBackupArray, validateIdMappingArray, validateMovedIdArray, validateFolder, validateFolderArray, } from './utils/validators.js';
|
|
16
|
+
import { validateAttachment, validateComment, validateCommentArray, validateCurrentUser, validateLabel, validateLabelArray, validateProject, validateProjectArray, validateSection, validateSectionArray, validateTask, validateTaskArray, validateUserArray, validateProductivityStats, validateReminder, validateReminderArray, validateLocationReminderArray, validateActivityEventArray, validateWorkspaceUserArray, validateWorkspaceInvitation, validateWorkspaceInvitationArray, validateWorkspacePlanDetails, validateJoinWorkspaceResult, validateWorkspace, validateWorkspaceArray, validateMemberActivityInfoArray, validateWorkspaceUserTaskArray, validateProjectActivityStats, validateProjectHealth, validateProjectHealthContext, validateProjectProgress, validateWorkspaceInsights, validateBackupArray, validateIdMappingArray, validateMovedIdArray, validateFolder, validateFolderArray, validateCollaboratorArray, validateCollaboratorStateArray, validateNoteArray, } from './utils/validators.js';
|
|
16
17
|
import { formatDateToYYYYMMDD } from './utils/url-helpers.js';
|
|
17
18
|
import { uploadMultipartFile } from './utils/multipart-upload.js';
|
|
18
19
|
import { camelCaseKeys } from './utils/case-conversion.js';
|
|
@@ -768,15 +769,18 @@ export class TodoistApi {
|
|
|
768
769
|
};
|
|
769
770
|
}
|
|
770
771
|
/**
|
|
771
|
-
* Joins a
|
|
772
|
+
* Joins a workspace project.
|
|
772
773
|
*
|
|
773
|
-
*
|
|
774
|
+
* Only used for workspaces — this endpoint is used to join a workspace project
|
|
775
|
+
* by a workspace user.
|
|
776
|
+
*
|
|
777
|
+
* @param id - The unique identifier of the workspace project to join.
|
|
774
778
|
* @param requestId - Optional custom identifier for the request.
|
|
775
|
-
* @returns A promise that resolves to the
|
|
779
|
+
* @returns A promise that resolves to the full project data after joining.
|
|
776
780
|
*/
|
|
777
781
|
async joinProject(id, requestId) {
|
|
778
782
|
z.string().parse(id);
|
|
779
|
-
const
|
|
783
|
+
const { data } = await request({
|
|
780
784
|
httpMethod: 'POST',
|
|
781
785
|
baseUri: this.syncApiBase,
|
|
782
786
|
relativePath: generatePath(ENDPOINT_REST_PROJECTS, id, ENDPOINT_REST_PROJECT_JOIN),
|
|
@@ -784,7 +788,16 @@ export class TodoistApi {
|
|
|
784
788
|
customFetch: this.customFetch,
|
|
785
789
|
requestId: requestId,
|
|
786
790
|
});
|
|
787
|
-
return
|
|
791
|
+
return {
|
|
792
|
+
project: WorkspaceProjectSchema.parse(data.project),
|
|
793
|
+
tasks: validateTaskArray(data.tasks),
|
|
794
|
+
sections: validateSectionArray(data.sections),
|
|
795
|
+
comments: validateNoteArray(data.comments),
|
|
796
|
+
collaborators: validateCollaboratorArray(data.collaborators),
|
|
797
|
+
collaboratorStates: validateCollaboratorStateArray(data.collaboratorStates),
|
|
798
|
+
folder: data.folder ? validateFolder(data.folder) : null,
|
|
799
|
+
subprojects: data.subprojects.map((p) => WorkspaceProjectSchema.parse(p)),
|
|
800
|
+
};
|
|
788
801
|
}
|
|
789
802
|
/**
|
|
790
803
|
* Retrieves a list of collaborators for a specific project.
|
|
@@ -13,6 +13,51 @@ export declare const PERMISSIONS: readonly ["task:add", "data:read", "data:read_
|
|
|
13
13
|
* @see {@link https://developer.todoist.com/api/v1/#tag/Authorization}
|
|
14
14
|
*/
|
|
15
15
|
export type Permission = (typeof PERMISSIONS)[number];
|
|
16
|
+
/** Supported token endpoint authentication methods for dynamic client registration. */
|
|
17
|
+
export declare const TOKEN_ENDPOINT_AUTH_METHODS: readonly ["client_secret_post", "client_secret_basic", "none"];
|
|
18
|
+
/**
|
|
19
|
+
* Authentication method used at the token endpoint.
|
|
20
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591#section-2 RFC 7591 Section 2}
|
|
21
|
+
*/
|
|
22
|
+
export type TokenEndpointAuthMethod = (typeof TOKEN_ENDPOINT_AUTH_METHODS)[number];
|
|
23
|
+
/**
|
|
24
|
+
* Parameters for registering a new OAuth client via Dynamic Client Registration.
|
|
25
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
26
|
+
*/
|
|
27
|
+
export type ClientRegistrationRequest = {
|
|
28
|
+
redirectUris: string[];
|
|
29
|
+
clientName?: string;
|
|
30
|
+
clientUri?: string;
|
|
31
|
+
logoUri?: string;
|
|
32
|
+
scope?: readonly Permission[];
|
|
33
|
+
grantTypes?: string[];
|
|
34
|
+
responseTypes?: string[];
|
|
35
|
+
tokenEndpointAuthMethod?: TokenEndpointAuthMethod;
|
|
36
|
+
};
|
|
37
|
+
type RawClientRegistrationResponse = {
|
|
38
|
+
clientId: string;
|
|
39
|
+
clientSecret?: string;
|
|
40
|
+
clientName: string;
|
|
41
|
+
redirectUris: string[];
|
|
42
|
+
scope?: string;
|
|
43
|
+
grantTypes: string[];
|
|
44
|
+
responseTypes: string[];
|
|
45
|
+
tokenEndpointAuthMethod: string;
|
|
46
|
+
clientIdIssuedAt?: number;
|
|
47
|
+
clientSecretExpiresAt?: number;
|
|
48
|
+
clientUri?: string;
|
|
49
|
+
logoUri?: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Response from a successful dynamic client registration.
|
|
53
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1 RFC 7591 Section 3.2.1}
|
|
54
|
+
*/
|
|
55
|
+
export type ClientRegistrationResponse = Omit<RawClientRegistrationResponse, 'clientIdIssuedAt' | 'clientSecretExpiresAt' | 'scope'> & {
|
|
56
|
+
scope?: Permission[];
|
|
57
|
+
clientIdIssuedAt?: Date;
|
|
58
|
+
/** `null` indicates the client secret never expires. Absent when no secret is issued. */
|
|
59
|
+
clientSecretExpiresAt?: Date | null;
|
|
60
|
+
};
|
|
16
61
|
/**
|
|
17
62
|
* Parameters required to exchange an authorization code for an access token.
|
|
18
63
|
* @see https://developer.todoist.com/api/v1/#tag/Authorization/OAuth
|
|
@@ -80,13 +125,17 @@ export declare function getAuthStateParameter(): string;
|
|
|
80
125
|
/**
|
|
81
126
|
* Generates the authorization URL for the OAuth2 flow.
|
|
82
127
|
*
|
|
128
|
+
* The `clientId` can be either a traditional client ID string (e.g. from
|
|
129
|
+
* {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
|
|
130
|
+
* as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
|
|
131
|
+
*
|
|
83
132
|
* @example
|
|
84
133
|
* ```typescript
|
|
85
|
-
* const url = getAuthorizationUrl(
|
|
86
|
-
* 'your-client-id',
|
|
87
|
-
* ['data:read', 'task:add'],
|
|
88
|
-
* state
|
|
89
|
-
* )
|
|
134
|
+
* const url = getAuthorizationUrl({
|
|
135
|
+
* clientId: 'your-client-id',
|
|
136
|
+
* permissions: ['data:read', 'task:add'],
|
|
137
|
+
* state,
|
|
138
|
+
* })
|
|
90
139
|
* // Redirect user to url
|
|
91
140
|
* ```
|
|
92
141
|
*
|
|
@@ -156,3 +205,22 @@ export declare function revokeToken(args: RevokeTokenRequestArgs, options?: Auth
|
|
|
156
205
|
* @throws {@link TodoistRequestError} If the migration fails
|
|
157
206
|
*/
|
|
158
207
|
export declare function migratePersonalToken(args: MigratePersonalTokenArgs, options?: AuthOptions): Promise<MigratePersonalTokenResponse>;
|
|
208
|
+
/**
|
|
209
|
+
* Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* const client = await registerClient({
|
|
214
|
+
* redirectUris: ['https://example.com/callback'],
|
|
215
|
+
* clientName: 'My App',
|
|
216
|
+
* scope: ['data:read_write', 'task:add'],
|
|
217
|
+
* })
|
|
218
|
+
* // Use client.clientId and client.clientSecret for OAuth flows
|
|
219
|
+
* ```
|
|
220
|
+
*
|
|
221
|
+
* @returns The registered client details
|
|
222
|
+
* @throws {@link TodoistRequestError} If the registration fails
|
|
223
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
224
|
+
*/
|
|
225
|
+
export declare function registerClient(args: ClientRegistrationRequest, options?: AuthOptions): Promise<ClientRegistrationResponse>;
|
|
226
|
+
export {};
|
|
@@ -56,6 +56,7 @@ export declare const ENDPOINT_SYNC = "sync";
|
|
|
56
56
|
export declare const ENDPOINT_AUTHORIZATION = "authorize";
|
|
57
57
|
export declare const ENDPOINT_GET_TOKEN = "access_token";
|
|
58
58
|
export declare const ENDPOINT_REVOKE = "revoke";
|
|
59
|
+
export declare const ENDPOINT_REGISTER = "register";
|
|
59
60
|
export declare const ENDPOINT_REST_FOLDERS = "folders";
|
|
60
61
|
export declare const ENDPOINT_REST_WORKSPACES = "workspaces";
|
|
61
62
|
export declare const ENDPOINT_WORKSPACE_INVITATIONS = "workspaces/invitations";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { Label, Section, Task, User, Attachment, Duration, Deadline, RawComment, PersonalProject, Reminder, Folder } from '../types/index.js';
|
|
1
|
+
import { Label, Section, Task, User, Attachment, Duration, Deadline, RawComment, PersonalProject, WorkspaceProject, Reminder, Folder } from '../types/index.js';
|
|
2
|
+
import type { Collaborator, CollaboratorState } from '../types/sync/resources/collaborators.js';
|
|
3
|
+
import type { Note } from '../types/sync/resources/notes.js';
|
|
2
4
|
export declare const DEFAULT_TASK_ID = "1234";
|
|
3
5
|
export declare const DEFAULT_TASK_CONTENT = "This is a task";
|
|
4
6
|
export declare const DEFAULT_TASK_DESCRIPTION = "A description";
|
|
@@ -77,6 +79,7 @@ export declare const INVALID_PROJECT: {
|
|
|
77
79
|
inboxProject: boolean;
|
|
78
80
|
};
|
|
79
81
|
export declare const PROJECT_WITH_OPTIONALS_AS_NULL: PersonalProject;
|
|
82
|
+
export declare const DEFAULT_WORKSPACE_PROJECT: WorkspaceProject;
|
|
80
83
|
export declare const DEFAULT_SECTION: Section;
|
|
81
84
|
export declare const INVALID_SECTION: {
|
|
82
85
|
projectId: undefined;
|
|
@@ -259,3 +262,6 @@ export declare const COMMENT_WITH_OPTIONALS_AS_NULL_PROJECT: {
|
|
|
259
262
|
projectId?: string | undefined;
|
|
260
263
|
};
|
|
261
264
|
export declare const DEFAULT_FOLDER: Folder;
|
|
265
|
+
export declare const DEFAULT_COLLABORATOR: Collaborator;
|
|
266
|
+
export declare const DEFAULT_COLLABORATOR_STATE: CollaboratorState;
|
|
267
|
+
export declare const DEFAULT_NOTE: Note;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Task, AddTaskArgs, GetTasksArgs, GetTasksByFilterArgs, UpdateTaskArgs, QuickAddTaskArgs, type MoveTaskArgs, GetCompletedTasksByCompletionDateArgs, GetCompletedTasksByDueDateArgs, GetCompletedTasksResponse, SearchCompletedTasksArgs, GetTasksResponse, GetAllCompletedTasksArgs, GetAllCompletedTasksResponse } from './types/tasks/index.js';
|
|
2
|
-
import { PersonalProject, WorkspaceProject, AddProjectArgs, UpdateProjectArgs, GetProjectsArgs, SearchProjectsArgs, GetProjectCollaboratorsArgs, GetProjectsResponse, GetProjectCollaboratorsResponse, GetArchivedProjectsArgs, GetArchivedProjectsResponse, MoveProjectToWorkspaceArgs, MoveProjectToPersonalArgs, GetArchivedProjectsCountArgs, GetArchivedProjectsCountResponse, GetProjectPermissionsResponse, GetFullProjectArgs, GetFullProjectResponse } from './types/projects/index.js';
|
|
2
|
+
import { PersonalProject, WorkspaceProject, AddProjectArgs, UpdateProjectArgs, GetProjectsArgs, SearchProjectsArgs, GetProjectCollaboratorsArgs, GetProjectsResponse, GetProjectCollaboratorsResponse, GetArchivedProjectsArgs, GetArchivedProjectsResponse, MoveProjectToWorkspaceArgs, MoveProjectToPersonalArgs, GetArchivedProjectsCountArgs, GetArchivedProjectsCountResponse, GetProjectPermissionsResponse, GetFullProjectArgs, GetFullProjectResponse, JoinProjectResponse } from './types/projects/index.js';
|
|
3
3
|
import { Section, AddSectionArgs, UpdateSectionArgs, GetSectionsArgs, SearchSectionsArgs, GetSectionsResponse } from './types/sections/index.js';
|
|
4
4
|
import { Label, AddLabelArgs, UpdateLabelArgs, GetLabelsArgs, SearchLabelsArgs, GetLabelsResponse, GetSharedLabelsArgs, GetSharedLabelsResponse, RenameSharedLabelArgs, RemoveSharedLabelArgs } from './types/labels/index.js';
|
|
5
5
|
import { Attachment, Comment, AddCommentArgs, UpdateCommentArgs, GetProjectCommentsArgs, GetTaskCommentsArgs, GetCommentsResponse } from './types/comments/index.js';
|
|
@@ -318,13 +318,16 @@ export declare class TodoistApi {
|
|
|
318
318
|
*/
|
|
319
319
|
getFullProject(id: string, args?: GetFullProjectArgs): Promise<GetFullProjectResponse>;
|
|
320
320
|
/**
|
|
321
|
-
* Joins a
|
|
321
|
+
* Joins a workspace project.
|
|
322
322
|
*
|
|
323
|
-
*
|
|
323
|
+
* Only used for workspaces — this endpoint is used to join a workspace project
|
|
324
|
+
* by a workspace user.
|
|
325
|
+
*
|
|
326
|
+
* @param id - The unique identifier of the workspace project to join.
|
|
324
327
|
* @param requestId - Optional custom identifier for the request.
|
|
325
|
-
* @returns A promise that resolves to the
|
|
328
|
+
* @returns A promise that resolves to the full project data after joining.
|
|
326
329
|
*/
|
|
327
|
-
joinProject(id: string, requestId?: string): Promise<
|
|
330
|
+
joinProject(id: string, requestId?: string): Promise<JoinProjectResponse>;
|
|
328
331
|
/**
|
|
329
332
|
* Retrieves a list of collaborators for a specific project.
|
|
330
333
|
*
|
|
@@ -2,6 +2,9 @@ import type { ColorKey } from '../../utils/colors.js';
|
|
|
2
2
|
import type { SearchArgs } from '../common.js';
|
|
3
3
|
import type { Comment } from '../comments/types.js';
|
|
4
4
|
import type { Section } from '../sections/types.js';
|
|
5
|
+
import type { Collaborator, CollaboratorState } from '../sync/resources/collaborators.js';
|
|
6
|
+
import type { Folder } from '../sync/resources/folders.js';
|
|
7
|
+
import type { Note } from '../sync/resources/notes.js';
|
|
5
8
|
import type { Task } from '../tasks/types.js';
|
|
6
9
|
import type { User } from '../users/types.js';
|
|
7
10
|
import type { CollaboratorRole, WorkspaceRole } from '../workspaces/types.js';
|
|
@@ -167,3 +170,21 @@ export type GetFullProjectResponse = {
|
|
|
167
170
|
collaborators: User[];
|
|
168
171
|
notes: Comment[];
|
|
169
172
|
};
|
|
173
|
+
/**
|
|
174
|
+
* Response from joining a workspace project.
|
|
175
|
+
*
|
|
176
|
+
* Only used for workspaces — this endpoint is used to join a workspace project
|
|
177
|
+
* by a workspace user.
|
|
178
|
+
*
|
|
179
|
+
* @see https://developer.todoist.com/api/v1/#tag/Projects/operation/join_project_api_v1_projects__project_id__join_post
|
|
180
|
+
*/
|
|
181
|
+
export type JoinProjectResponse = {
|
|
182
|
+
project: WorkspaceProject;
|
|
183
|
+
tasks: Task[];
|
|
184
|
+
sections: Section[];
|
|
185
|
+
comments: Note[];
|
|
186
|
+
collaborators: Collaborator[];
|
|
187
|
+
collaboratorStates: CollaboratorState[];
|
|
188
|
+
folder: Folder | null;
|
|
189
|
+
subprojects: WorkspaceProject[];
|
|
190
|
+
};
|
package/package.json
CHANGED