@doist/todoist-api-typescript 7.4.0 → 7.6.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/README.md +2 -0
- package/dist/cjs/authentication.js +50 -6
- package/dist/cjs/consts/endpoints.js +63 -1
- package/dist/cjs/test-utils/test-defaults.js +33 -1
- package/dist/cjs/todoist-api.js +1130 -168
- package/dist/cjs/{utils → transport}/fetch-with-retry.js +23 -71
- package/dist/cjs/{rest-client.js → transport/http-client.js} +5 -5
- package/dist/cjs/transport/http-dispatcher.js +72 -0
- package/dist/cjs/types/entities.js +124 -1
- package/dist/cjs/types/errors.js +9 -1
- package/dist/cjs/types/http.js +3 -1
- package/dist/cjs/types/requests.js +24 -0
- package/dist/cjs/types/sync/commands/shared.js +2 -8
- package/dist/cjs/types/sync/resources/reminders.js +2 -0
- package/dist/cjs/utils/multipart-upload.js +1 -1
- package/dist/cjs/utils/validators.js +19 -2
- package/dist/esm/authentication.js +47 -4
- package/dist/esm/consts/endpoints.js +52 -0
- package/dist/esm/test-utils/test-defaults.js +32 -0
- package/dist/esm/todoist-api.js +1061 -99
- package/dist/esm/{utils → transport}/fetch-with-retry.js +23 -38
- package/dist/esm/{rest-client.js → transport/http-client.js} +5 -5
- package/dist/esm/transport/http-dispatcher.js +35 -0
- package/dist/esm/types/entities.js +122 -0
- package/dist/esm/types/errors.js +7 -0
- package/dist/esm/types/http.js +3 -1
- package/dist/esm/types/requests.js +23 -1
- package/dist/esm/types/sync/commands/shared.js +1 -8
- package/dist/esm/types/sync/resources/reminders.js +2 -0
- package/dist/esm/utils/multipart-upload.js +1 -1
- package/dist/esm/utils/validators.js +19 -2
- package/dist/types/authentication.d.ts +51 -6
- package/dist/types/consts/endpoints.d.ts +31 -0
- package/dist/types/test-utils/test-defaults.d.ts +5 -1
- package/dist/types/todoist-api.d.ts +338 -6
- package/dist/types/{utils → transport}/fetch-with-retry.d.ts +1 -1
- package/dist/types/{rest-client.d.ts → transport/http-client.d.ts} +1 -1
- package/dist/types/transport/http-dispatcher.d.ts +3 -0
- package/dist/types/types/entities.d.ts +258 -14
- package/dist/types/types/errors.d.ts +4 -0
- package/dist/types/types/requests.d.ts +537 -43
- package/dist/types/types/sync/commands/projects.d.ts +2 -2
- package/dist/types/types/sync/commands/shared.d.ts +1 -4
- package/dist/types/types/sync/resources/reminders.d.ts +4 -0
- package/dist/types/types/sync/resources/user.d.ts +2 -2
- package/dist/types/types/sync/resources/view-options.d.ts +5 -5
- package/dist/types/types/sync/user-preferences.d.ts +1 -1
- package/dist/types/utils/validators.d.ts +202 -6
- package/package.json +4 -4
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
36
3
|
var t = {};
|
|
37
4
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -46,6 +13,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
46
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
14
|
exports.fetchWithRetry = fetchWithRetry;
|
|
48
15
|
const http_1 = require("../types/http");
|
|
16
|
+
const http_dispatcher_1 = require("./http-dispatcher");
|
|
49
17
|
/**
|
|
50
18
|
* Default retry configuration matching the original axios-retry behavior
|
|
51
19
|
*/
|
|
@@ -58,32 +26,11 @@ const DEFAULT_RETRY_CONFIG = {
|
|
|
58
26
|
return retryNumber === 1 ? 0 : 500;
|
|
59
27
|
},
|
|
60
28
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Gets the HTTP agent for Node.js environments or undefined for browser environments.
|
|
68
|
-
* Uses dynamic import to avoid loading undici in browser environments.
|
|
69
|
-
*/
|
|
70
|
-
async function getHttpAgent() {
|
|
71
|
-
var _a;
|
|
72
|
-
if (httpAgent === null) {
|
|
73
|
-
if (typeof process !== 'undefined' && ((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node)) {
|
|
74
|
-
// We're in Node.js - dynamically import undici
|
|
75
|
-
const { Agent } = await Promise.resolve().then(() => __importStar(require('undici')));
|
|
76
|
-
httpAgent = new Agent({
|
|
77
|
-
keepAliveTimeout: 1, // Close connections after 1ms of idle time
|
|
78
|
-
keepAliveMaxTimeout: 1, // Maximum time to keep connections alive
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
// We're in browser - no agent needed
|
|
83
|
-
httpAgent = undefined;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return httpAgent;
|
|
29
|
+
const TIMEOUT_ERROR_NAME = 'TimeoutError';
|
|
30
|
+
function createTimeoutError(timeoutMs) {
|
|
31
|
+
const error = new Error(`Request timeout after ${timeoutMs}ms`);
|
|
32
|
+
error.name = TIMEOUT_ERROR_NAME;
|
|
33
|
+
return error;
|
|
87
34
|
}
|
|
88
35
|
/**
|
|
89
36
|
* Converts Headers object to a plain object
|
|
@@ -103,10 +50,14 @@ function createTimeoutSignal(timeoutMs, existingSignal) {
|
|
|
103
50
|
const controller = new AbortController();
|
|
104
51
|
// Timeout logic
|
|
105
52
|
const timeoutId = setTimeout(() => {
|
|
106
|
-
controller.abort(
|
|
53
|
+
controller.abort(createTimeoutError(timeoutMs));
|
|
107
54
|
}, timeoutMs);
|
|
55
|
+
let abortHandler;
|
|
108
56
|
function clear() {
|
|
109
57
|
clearTimeout(timeoutId);
|
|
58
|
+
if (existingSignal && abortHandler) {
|
|
59
|
+
existingSignal.removeEventListener('abort', abortHandler);
|
|
60
|
+
}
|
|
110
61
|
}
|
|
111
62
|
// If there's an existing signal, forward its abort
|
|
112
63
|
if (existingSignal) {
|
|
@@ -115,10 +66,11 @@ function createTimeoutSignal(timeoutMs, existingSignal) {
|
|
|
115
66
|
controller.abort(existingSignal.reason);
|
|
116
67
|
}
|
|
117
68
|
else {
|
|
118
|
-
|
|
69
|
+
abortHandler = () => {
|
|
119
70
|
clearTimeout(timeoutId);
|
|
120
71
|
controller.abort(existingSignal.reason);
|
|
121
|
-
}
|
|
72
|
+
};
|
|
73
|
+
existingSignal.addEventListener('abort', abortHandler, { once: true });
|
|
122
74
|
}
|
|
123
75
|
}
|
|
124
76
|
// Clean up timeout when request completes
|
|
@@ -167,9 +119,13 @@ async function fetchWithRetry(args) {
|
|
|
167
119
|
fetchResponse = await customFetch(url, Object.assign(Object.assign({}, fetchOptions), { signal: requestSignal, timeout }));
|
|
168
120
|
}
|
|
169
121
|
else {
|
|
170
|
-
const
|
|
122
|
+
const dispatcher = await (0, http_dispatcher_1.getDefaultDispatcher)();
|
|
123
|
+
const nativeFetchOptions = Object.assign(Object.assign({}, fetchOptions), { signal: requestSignal });
|
|
124
|
+
if (dispatcher !== undefined) {
|
|
171
125
|
// @ts-expect-error - dispatcher is a valid option for Node.js fetch but not in the TS types
|
|
172
|
-
dispatcher
|
|
126
|
+
nativeFetchOptions.dispatcher = dispatcher;
|
|
127
|
+
}
|
|
128
|
+
const nativeResponse = await fetch(url, nativeFetchOptions);
|
|
173
129
|
fetchResponse = convertResponseToCustomFetch(nativeResponse);
|
|
174
130
|
}
|
|
175
131
|
// Check if the response is successful
|
|
@@ -224,6 +180,9 @@ async function fetchWithRetry(args) {
|
|
|
224
180
|
};
|
|
225
181
|
}
|
|
226
182
|
catch (error) {
|
|
183
|
+
if (clearTimeoutFn) {
|
|
184
|
+
clearTimeoutFn();
|
|
185
|
+
}
|
|
227
186
|
lastError = error;
|
|
228
187
|
// Check if this error should trigger a retry
|
|
229
188
|
const shouldRetry = attempt < config.retries && config.retryCondition(lastError);
|
|
@@ -233,9 +192,6 @@ async function fetchWithRetry(args) {
|
|
|
233
192
|
const networkError = lastError;
|
|
234
193
|
networkError.isNetworkError = true;
|
|
235
194
|
}
|
|
236
|
-
if (clearTimeoutFn) {
|
|
237
|
-
clearTimeoutFn();
|
|
238
|
-
}
|
|
239
195
|
throw lastError;
|
|
240
196
|
}
|
|
241
197
|
// Wait before retrying
|
|
@@ -243,10 +199,6 @@ async function fetchWithRetry(args) {
|
|
|
243
199
|
if (delay > 0) {
|
|
244
200
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
245
201
|
}
|
|
246
|
-
// Retry path – ensure this attempt's timeout is cleared before looping
|
|
247
|
-
if (clearTimeoutFn) {
|
|
248
|
-
clearTimeoutFn();
|
|
249
|
-
}
|
|
250
202
|
}
|
|
251
203
|
}
|
|
252
204
|
// This should never be reached, but just in case
|
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.paramsSerializer = paramsSerializer;
|
|
4
4
|
exports.isSuccess = isSuccess;
|
|
5
5
|
exports.request = request;
|
|
6
|
-
const errors_1 = require("./types/errors");
|
|
7
|
-
const http_1 = require("./types/http");
|
|
8
6
|
const uuid_1 = require("uuid");
|
|
9
|
-
const endpoints_1 = require("
|
|
10
|
-
const
|
|
11
|
-
const
|
|
7
|
+
const endpoints_1 = require("../consts/endpoints");
|
|
8
|
+
const errors_1 = require("../types/errors");
|
|
9
|
+
const http_1 = require("../types/http");
|
|
10
|
+
const case_conversion_1 = require("../utils/case-conversion");
|
|
11
|
+
const fetch_with_retry_1 = require("./fetch-with-retry");
|
|
12
12
|
function paramsSerializer(params) {
|
|
13
13
|
const qs = new URLSearchParams();
|
|
14
14
|
Object.keys(params).forEach((key) => {
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getDefaultDispatcher = getDefaultDispatcher;
|
|
37
|
+
exports.resetDefaultDispatcherForTests = resetDefaultDispatcherForTests;
|
|
38
|
+
// Use effectively-disabled keep-alive so short-lived CLI processes do not stay
|
|
39
|
+
// open waiting on idle sockets. Undici requires positive values, so we use 1ms.
|
|
40
|
+
const KEEP_ALIVE_OPTIONS = {
|
|
41
|
+
keepAliveTimeout: 1,
|
|
42
|
+
keepAliveMaxTimeout: 1,
|
|
43
|
+
};
|
|
44
|
+
let defaultDispatcherPromise;
|
|
45
|
+
function getDefaultDispatcher() {
|
|
46
|
+
if (!isNodeEnvironment()) {
|
|
47
|
+
return Promise.resolve(undefined);
|
|
48
|
+
}
|
|
49
|
+
if (!defaultDispatcherPromise) {
|
|
50
|
+
defaultDispatcherPromise = createDefaultDispatcher().catch((error) => {
|
|
51
|
+
defaultDispatcherPromise = undefined;
|
|
52
|
+
throw error;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return defaultDispatcherPromise;
|
|
56
|
+
}
|
|
57
|
+
async function resetDefaultDispatcherForTests() {
|
|
58
|
+
if (!defaultDispatcherPromise) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const dispatcherPromise = defaultDispatcherPromise;
|
|
62
|
+
defaultDispatcherPromise = undefined;
|
|
63
|
+
await dispatcherPromise.then((dispatcher) => dispatcher.close(), () => undefined);
|
|
64
|
+
}
|
|
65
|
+
async function createDefaultDispatcher() {
|
|
66
|
+
const { EnvHttpProxyAgent } = await Promise.resolve().then(() => __importStar(require('undici')));
|
|
67
|
+
return new EnvHttpProxyAgent(KEEP_ALIVE_OPTIONS);
|
|
68
|
+
}
|
|
69
|
+
function isNodeEnvironment() {
|
|
70
|
+
var _a;
|
|
71
|
+
return typeof process !== 'undefined' && Boolean((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
|
|
72
|
+
}
|
|
@@ -11,7 +11,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.WorkspaceSchema = exports.WorkspacePropertiesSchema = exports.WorkspaceLimitsSchema = exports.WorkspacePlanSchema = exports.WORKSPACE_PLANS = exports.JoinWorkspaceResultSchema = exports.WorkspacePlanDetailsSchema = exports.WORKSPACE_PLAN_STATUSES = exports.WORKSPACE_CURRENT_PLANS = exports.FormattedPriceListingSchema = exports.PlanPriceSchema = exports.WorkspaceInvitationSchema = exports.WorkspaceUserSchema = exports.WorkspaceRoleSchema = exports.WORKSPACE_ROLES = exports.ActivityEventSchema = exports.ActivityEventExtraDataSchema = exports.ColorSchema = exports.ProductivityStatsSchema = exports.KarmaUpdateSchema = exports.ItemsWithDateSchema = exports.CompletedItemSchema = exports.StreakSchema = exports.CurrentUserSchema = exports.PREMIUM_STATUSES = exports.TimezoneInfoSchema = exports.UserSchema = exports.CommentSchema = exports.RawCommentSchema = exports.AttachmentSchema = exports.UPLOAD_STATES = exports.LabelSchema = exports.SectionSchema = exports.PROJECT_VIEW_STYLES = exports.WorkspaceProjectSchema = exports.ProjectVisibilitySchema = exports.PROJECT_VISIBILITIES = exports.PersonalProjectSchema = exports.BaseProjectSchema = exports.TaskSchema = exports.DeadlineSchema = exports.DurationSchema = exports.DURATION_UNITS = exports.DueDateSchema = void 0;
|
|
14
|
+
exports.ProjectActivityStatsSchema = exports.WeekRollupSchema = exports.DayActivitySchema = exports.WorkspaceUserTaskSchema = exports.MemberActivityInfoSchema = exports.WorkspaceSchema = exports.WorkspacePropertiesSchema = exports.WorkspaceLimitsSchema = exports.WorkspacePlanSchema = exports.WORKSPACE_PLANS = exports.JoinWorkspaceResultSchema = exports.WorkspacePlanDetailsSchema = exports.WORKSPACE_PLAN_STATUSES = exports.WORKSPACE_CURRENT_PLANS = exports.FormattedPriceListingSchema = exports.PlanPriceSchema = exports.WorkspaceInvitationSchema = exports.WorkspaceUserSchema = exports.WorkspaceRoleSchema = exports.WORKSPACE_ROLES = exports.COLLABORATOR_ROLES = exports.ActivityEventSchema = exports.ActivityEventExtraDataSchema = exports.ColorSchema = exports.ProductivityStatsSchema = exports.KarmaUpdateSchema = exports.ItemsWithDateSchema = exports.CompletedItemSchema = exports.StreakSchema = exports.CurrentUserSchema = exports.PREMIUM_STATUSES = exports.TimezoneInfoSchema = exports.UserSchema = exports.CommentSchema = exports.RawCommentSchema = exports.AttachmentSchema = exports.UPLOAD_STATES = exports.LabelSchema = exports.SectionSchema = exports.PROJECT_VIEW_STYLES = exports.WorkspaceProjectSchema = exports.ProjectVisibilitySchema = exports.PROJECT_VISIBILITIES = exports.PersonalProjectSchema = exports.BaseProjectSchema = exports.TaskSchema = exports.DeadlineSchema = exports.DurationSchema = exports.DURATION_UNITS = exports.DueDateSchema = void 0;
|
|
15
|
+
exports.MovedIdSchema = exports.IdMappingSchema = exports.BackupSchema = exports.WorkspaceInsightsSchema = exports.ProjectInsightSchema = exports.ProjectProgressSchema = exports.ProjectHealthContextSchema = exports.TaskContextSchema = exports.ProjectMetricsSchema = exports.ProjectHealthSchema = exports.TaskRecommendationSchema = exports.HEALTH_STATUSES = void 0;
|
|
15
16
|
const zod_1 = require("zod");
|
|
16
17
|
const url_helpers_1 = require("../utils/url-helpers");
|
|
17
18
|
const uncompletable_helpers_1 = require("../utils/uncompletable-helpers");
|
|
@@ -322,6 +323,14 @@ exports.ActivityEventSchema = zod_1.z
|
|
|
322
323
|
extraData: exports.ActivityEventExtraDataSchema,
|
|
323
324
|
})
|
|
324
325
|
.catchall(zod_1.z.any());
|
|
326
|
+
/** Available project collaborator roles. */
|
|
327
|
+
exports.COLLABORATOR_ROLES = [
|
|
328
|
+
'CREATOR',
|
|
329
|
+
'ADMIN',
|
|
330
|
+
'READ_WRITE',
|
|
331
|
+
'EDIT_ONLY',
|
|
332
|
+
'COMPLETE_ONLY',
|
|
333
|
+
];
|
|
325
334
|
/**
|
|
326
335
|
* Available workspace roles.
|
|
327
336
|
*/
|
|
@@ -427,3 +436,117 @@ exports.WorkspaceSchema = zod_1.z.object({
|
|
|
427
436
|
creatorId: zod_1.z.string(),
|
|
428
437
|
properties: exports.WorkspacePropertiesSchema,
|
|
429
438
|
});
|
|
439
|
+
exports.MemberActivityInfoSchema = zod_1.z.object({
|
|
440
|
+
userId: zod_1.z.string(),
|
|
441
|
+
tasksAssigned: zod_1.z.number().int(),
|
|
442
|
+
tasksOverdue: zod_1.z.number().int(),
|
|
443
|
+
});
|
|
444
|
+
exports.WorkspaceUserTaskSchema = zod_1.z.object({
|
|
445
|
+
id: zod_1.z.string(),
|
|
446
|
+
content: zod_1.z.string(),
|
|
447
|
+
responsibleUid: zod_1.z.string().nullable(),
|
|
448
|
+
due: exports.DueDateSchema.nullable(),
|
|
449
|
+
deadline: exports.DeadlineSchema.nullable(),
|
|
450
|
+
labels: zod_1.z.array(zod_1.z.string()),
|
|
451
|
+
notesCount: zod_1.z.number().int(),
|
|
452
|
+
projectId: zod_1.z.string(),
|
|
453
|
+
projectName: zod_1.z.string(),
|
|
454
|
+
priority: zod_1.z.number().int(),
|
|
455
|
+
description: zod_1.z.string(),
|
|
456
|
+
isOverdue: zod_1.z.boolean(),
|
|
457
|
+
});
|
|
458
|
+
// Insights entities
|
|
459
|
+
exports.DayActivitySchema = zod_1.z.object({
|
|
460
|
+
date: zod_1.z.string(),
|
|
461
|
+
totalCount: zod_1.z.number().int(),
|
|
462
|
+
});
|
|
463
|
+
exports.WeekRollupSchema = zod_1.z.object({
|
|
464
|
+
fromDate: zod_1.z.string(),
|
|
465
|
+
toDate: zod_1.z.string(),
|
|
466
|
+
totalCount: zod_1.z.number().int(),
|
|
467
|
+
});
|
|
468
|
+
exports.ProjectActivityStatsSchema = zod_1.z.object({
|
|
469
|
+
dayItems: zod_1.z.array(exports.DayActivitySchema),
|
|
470
|
+
weekItems: zod_1.z.array(exports.WeekRollupSchema).nullable(),
|
|
471
|
+
});
|
|
472
|
+
/** Available project health statuses. */
|
|
473
|
+
exports.HEALTH_STATUSES = [
|
|
474
|
+
'UNKNOWN',
|
|
475
|
+
'ON_TRACK',
|
|
476
|
+
'AT_RISK',
|
|
477
|
+
'CRITICAL',
|
|
478
|
+
'EXCELLENT',
|
|
479
|
+
'ERROR',
|
|
480
|
+
];
|
|
481
|
+
exports.TaskRecommendationSchema = zod_1.z.object({
|
|
482
|
+
taskId: zod_1.z.string(),
|
|
483
|
+
recommendation: zod_1.z.string(),
|
|
484
|
+
});
|
|
485
|
+
exports.ProjectHealthSchema = zod_1.z.object({
|
|
486
|
+
status: zod_1.z.enum(exports.HEALTH_STATUSES),
|
|
487
|
+
description: zod_1.z.string().nullable().optional(),
|
|
488
|
+
descriptionSummary: zod_1.z.string().nullable().optional(),
|
|
489
|
+
taskRecommendations: zod_1.z.array(exports.TaskRecommendationSchema).nullable().optional(),
|
|
490
|
+
projectId: zod_1.z.string().nullable().optional(),
|
|
491
|
+
updatedAt: zod_1.z.string().nullable().optional(),
|
|
492
|
+
isStale: zod_1.z.boolean().default(false),
|
|
493
|
+
updateInProgress: zod_1.z.boolean().default(false),
|
|
494
|
+
});
|
|
495
|
+
exports.ProjectMetricsSchema = zod_1.z.object({
|
|
496
|
+
totalTasks: zod_1.z.number().int(),
|
|
497
|
+
completedTasks: zod_1.z.number().int(),
|
|
498
|
+
overdueTasks: zod_1.z.number().int(),
|
|
499
|
+
tasksCreatedThisWeek: zod_1.z.number().int(),
|
|
500
|
+
tasksCompletedThisWeek: zod_1.z.number().int(),
|
|
501
|
+
averageCompletionTime: zod_1.z.number().nullable(),
|
|
502
|
+
});
|
|
503
|
+
exports.TaskContextSchema = zod_1.z.object({
|
|
504
|
+
id: zod_1.z.string(),
|
|
505
|
+
content: zod_1.z.string(),
|
|
506
|
+
due: zod_1.z.string().nullable().optional(),
|
|
507
|
+
deadline: zod_1.z.string().nullable().optional(),
|
|
508
|
+
priority: zod_1.z.string(),
|
|
509
|
+
isCompleted: zod_1.z.boolean(),
|
|
510
|
+
createdAt: zod_1.z.string(),
|
|
511
|
+
updatedAt: zod_1.z.string(),
|
|
512
|
+
completedAt: zod_1.z.string().nullable(),
|
|
513
|
+
completedByUid: zod_1.z.string().nullable(),
|
|
514
|
+
labels: zod_1.z.array(zod_1.z.string()),
|
|
515
|
+
});
|
|
516
|
+
exports.ProjectHealthContextSchema = zod_1.z.object({
|
|
517
|
+
projectId: zod_1.z.string(),
|
|
518
|
+
projectName: zod_1.z.string(),
|
|
519
|
+
projectDescription: zod_1.z.string().nullable(),
|
|
520
|
+
projectMetrics: exports.ProjectMetricsSchema,
|
|
521
|
+
tasks: zod_1.z.array(exports.TaskContextSchema),
|
|
522
|
+
language: zod_1.z.string().nullable().optional(),
|
|
523
|
+
});
|
|
524
|
+
exports.ProjectProgressSchema = zod_1.z.object({
|
|
525
|
+
projectId: zod_1.z.string(),
|
|
526
|
+
completedCount: zod_1.z.number().int(),
|
|
527
|
+
activeCount: zod_1.z.number().int(),
|
|
528
|
+
progressPercent: zod_1.z.number().int(),
|
|
529
|
+
});
|
|
530
|
+
exports.ProjectInsightSchema = zod_1.z.object({
|
|
531
|
+
projectId: zod_1.z.string(),
|
|
532
|
+
health: exports.ProjectHealthSchema.nullable(),
|
|
533
|
+
progress: exports.ProjectProgressSchema.nullable(),
|
|
534
|
+
});
|
|
535
|
+
exports.WorkspaceInsightsSchema = zod_1.z.object({
|
|
536
|
+
folderId: zod_1.z.string().nullable(),
|
|
537
|
+
projectInsights: zod_1.z.array(exports.ProjectInsightSchema),
|
|
538
|
+
});
|
|
539
|
+
// Backups
|
|
540
|
+
exports.BackupSchema = zod_1.z.object({
|
|
541
|
+
version: zod_1.z.string(),
|
|
542
|
+
url: zod_1.z.string(),
|
|
543
|
+
});
|
|
544
|
+
// ID Mappings
|
|
545
|
+
exports.IdMappingSchema = zod_1.z.object({
|
|
546
|
+
oldId: zod_1.z.string().nullable(),
|
|
547
|
+
newId: zod_1.z.string().nullable(),
|
|
548
|
+
});
|
|
549
|
+
exports.MovedIdSchema = zod_1.z.object({
|
|
550
|
+
oldId: zod_1.z.string(),
|
|
551
|
+
newId: zod_1.z.string(),
|
|
552
|
+
});
|
package/dist/cjs/types/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TodoistRequestError = void 0;
|
|
3
|
+
exports.TodoistArgumentError = exports.TodoistRequestError = void 0;
|
|
4
4
|
const ts_custom_error_1 = require("ts-custom-error");
|
|
5
5
|
const authenticationErrorCodes = [401, 403];
|
|
6
6
|
class TodoistRequestError extends ts_custom_error_1.CustomError {
|
|
@@ -19,3 +19,11 @@ class TodoistRequestError extends ts_custom_error_1.CustomError {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
exports.TodoistRequestError = TodoistRequestError;
|
|
22
|
+
class TodoistArgumentError extends ts_custom_error_1.CustomError {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.message = message;
|
|
26
|
+
Object.defineProperty(this, 'name', { value: 'TodoistArgumentError' });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.TodoistArgumentError = TodoistArgumentError;
|
package/dist/cjs/types/http.js
CHANGED
|
@@ -6,12 +6,14 @@ exports.isHttpError = isHttpError;
|
|
|
6
6
|
* Type guard to check if an error is a network error
|
|
7
7
|
*/
|
|
8
8
|
function isNetworkError(error) {
|
|
9
|
-
// Network errors in fetch are typically TypeError with specific messages
|
|
9
|
+
// Network errors in fetch are typically TypeError with specific messages.
|
|
10
|
+
// Timeout errors are created by fetch-with-retry with the TimeoutError name.
|
|
10
11
|
return ((error instanceof TypeError &&
|
|
11
12
|
(error.message.includes('fetch') ||
|
|
12
13
|
error.message.includes('network') ||
|
|
13
14
|
error.message.includes('Failed to fetch') ||
|
|
14
15
|
error.message.includes('NetworkError'))) ||
|
|
16
|
+
error.name === 'TimeoutError' ||
|
|
15
17
|
error.isNetworkError === true);
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
@@ -1,2 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MOVED_ID_OBJECT_TYPES = exports.ID_MAPPING_OBJECT_TYPES = exports.EMAIL_OBJECT_TYPES = exports.REMINDER_DELIVERY_SERVICES = void 0;
|
|
4
|
+
/** Available reminder delivery services. */
|
|
5
|
+
exports.REMINDER_DELIVERY_SERVICES = ['email', 'push'];
|
|
6
|
+
// Email forwarding types
|
|
7
|
+
/** Object types that support email forwarding. */
|
|
8
|
+
exports.EMAIL_OBJECT_TYPES = ['project', 'project_comments', 'task'];
|
|
9
|
+
// ID mapping types
|
|
10
|
+
/** Object types that support ID mappings. */
|
|
11
|
+
exports.ID_MAPPING_OBJECT_TYPES = [
|
|
12
|
+
'sections',
|
|
13
|
+
'tasks',
|
|
14
|
+
'comments',
|
|
15
|
+
'reminders',
|
|
16
|
+
'location_reminders',
|
|
17
|
+
'projects',
|
|
18
|
+
];
|
|
19
|
+
/** Object types that support moved ID lookups. */
|
|
20
|
+
exports.MOVED_ID_OBJECT_TYPES = [
|
|
21
|
+
'sections',
|
|
22
|
+
'tasks',
|
|
23
|
+
'comments',
|
|
24
|
+
'reminders',
|
|
25
|
+
'location_reminders',
|
|
26
|
+
];
|
|
@@ -12,14 +12,8 @@ exports.PROJECT_STATUSES = [
|
|
|
12
12
|
'COMPLETED',
|
|
13
13
|
'CANCELED',
|
|
14
14
|
];
|
|
15
|
-
|
|
16
|
-
exports.COLLABORATOR_ROLES
|
|
17
|
-
'CREATOR',
|
|
18
|
-
'ADMIN',
|
|
19
|
-
'READ_WRITE',
|
|
20
|
-
'EDIT_ONLY',
|
|
21
|
-
'COMPLETE_ONLY',
|
|
22
|
-
];
|
|
15
|
+
var entities_1 = require("../../entities");
|
|
16
|
+
Object.defineProperty(exports, "COLLABORATOR_ROLES", { enumerable: true, get: function () { return entities_1.COLLABORATOR_ROLES; } });
|
|
23
17
|
/** Available reminder notification services. */
|
|
24
18
|
exports.REMINDER_SERVICES = ['default', 'email', 'mobile', 'push', 'no_default'];
|
|
25
19
|
/** Available workspace project sort orders. */
|
|
@@ -23,11 +23,13 @@ exports.LocationReminderSchema = exports.ReminderBaseSchema.extend({
|
|
|
23
23
|
exports.AbsoluteReminderSchema = exports.ReminderBaseSchema.extend({
|
|
24
24
|
type: zod_1.z.literal('absolute'),
|
|
25
25
|
due: entities_1.DueDateSchema,
|
|
26
|
+
isUrgent: zod_1.z.boolean().optional(),
|
|
26
27
|
}).passthrough();
|
|
27
28
|
exports.RelativeReminderSchema = exports.ReminderBaseSchema.extend({
|
|
28
29
|
type: zod_1.z.literal('relative'),
|
|
29
30
|
minuteOffset: zod_1.z.number().int(),
|
|
30
31
|
due: entities_1.DueDateSchema.optional(),
|
|
32
|
+
isUrgent: zod_1.z.boolean().optional(),
|
|
31
33
|
}).passthrough();
|
|
32
34
|
exports.ReminderSchema = zod_1.z.discriminatedUnion('type', [
|
|
33
35
|
exports.LocationReminderSchema,
|
|
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.uploadMultipartFile = uploadMultipartFile;
|
|
37
|
-
const fetch_with_retry_1 = require("
|
|
37
|
+
const fetch_with_retry_1 = require("../transport/fetch-with-retry");
|
|
38
38
|
/**
|
|
39
39
|
* Helper function to determine content-type from filename extension.
|
|
40
40
|
* @param fileName - The filename to analyze
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.validateSuggestionArray = exports.validateSuggestion = exports.validateUserSettings = exports.validateSyncUser = exports.validateSyncWorkspaceArray = exports.validateSyncWorkspace = exports.validateLiveNotificationArray = exports.validateLiveNotification = void 0;
|
|
3
|
+
exports.validateWorkspaceFilterArray = exports.validateWorkspaceFilter = exports.validateTooltips = exports.validateNoteArray = exports.validateNote = exports.validateFolderArray = exports.validateFolder = exports.validateCollaboratorStateArray = exports.validateCollaboratorState = exports.validateCollaboratorArray = exports.validateCollaborator = exports.validateFilterArray = exports.validateFilter = exports.validateMovedIdArray = exports.validateMovedId = exports.validateIdMappingArray = exports.validateIdMapping = exports.validateBackupArray = exports.validateBackup = exports.validateWorkspaceInsights = exports.validateProjectProgress = exports.validateProjectHealthContext = exports.validateProjectHealth = exports.validateProjectActivityStats = exports.validateWorkspaceUserTaskArray = exports.validateWorkspaceUserTask = exports.validateMemberActivityInfoArray = exports.validateMemberActivityInfo = exports.validateWorkspaceArray = exports.validateWorkspace = exports.validateJoinWorkspaceResult = exports.validateWorkspacePlanDetails = exports.validateWorkspaceInvitationArray = exports.validateWorkspaceInvitation = exports.validateWorkspaceUser = exports.validateAttachment = exports.validateActivityEventArray = exports.validateActivityEvent = exports.validateCurrentUser = exports.validateProductivityStats = exports.validateUserArray = exports.validateUser = exports.validateCommentArray = exports.validateComment = exports.validateLabelArray = exports.validateLabel = exports.validateSectionArray = exports.validateSection = exports.validateTaskArray = exports.validateTask = void 0;
|
|
4
|
+
exports.validateSuggestionArray = exports.validateSuggestion = exports.validateUserSettings = exports.validateSyncUser = exports.validateSyncWorkspaceArray = exports.validateSyncWorkspace = exports.validateLiveNotificationArray = exports.validateLiveNotification = exports.validateUserPlanLimits = exports.validateProjectViewOptionsDefaultsArray = exports.validateProjectViewOptionsDefaults = exports.validateViewOptionsArray = exports.validateViewOptions = exports.validateCompletedInfoArray = exports.validateCompletedInfo = exports.validateLocationReminderArray = exports.validateLocationReminder = exports.validateReminderArray = exports.validateReminder = exports.validateCalendarAccountArray = exports.validateCalendarAccount = exports.validateCalendarArray = exports.validateCalendar = exports.validateWorkspaceGoalArray = exports.validateWorkspaceGoal = void 0;
|
|
5
5
|
exports.isWorkspaceProject = isWorkspaceProject;
|
|
6
6
|
exports.isPersonalProject = isPersonalProject;
|
|
7
7
|
exports.validateProject = validateProject;
|
|
@@ -74,6 +74,21 @@ exports.validateWorkspacePlanDetails = createValidator(entities_1.WorkspacePlanD
|
|
|
74
74
|
exports.validateJoinWorkspaceResult = createValidator(entities_1.JoinWorkspaceResultSchema);
|
|
75
75
|
exports.validateWorkspace = createValidator(entities_1.WorkspaceSchema);
|
|
76
76
|
exports.validateWorkspaceArray = createArrayValidator(exports.validateWorkspace);
|
|
77
|
+
exports.validateMemberActivityInfo = createValidator(entities_1.MemberActivityInfoSchema);
|
|
78
|
+
exports.validateMemberActivityInfoArray = createArrayValidator(exports.validateMemberActivityInfo);
|
|
79
|
+
exports.validateWorkspaceUserTask = createValidator(entities_1.WorkspaceUserTaskSchema);
|
|
80
|
+
exports.validateWorkspaceUserTaskArray = createArrayValidator(exports.validateWorkspaceUserTask);
|
|
81
|
+
exports.validateProjectActivityStats = createValidator(entities_1.ProjectActivityStatsSchema);
|
|
82
|
+
exports.validateProjectHealth = createValidator(entities_1.ProjectHealthSchema);
|
|
83
|
+
exports.validateProjectHealthContext = createValidator(entities_1.ProjectHealthContextSchema);
|
|
84
|
+
exports.validateProjectProgress = createValidator(entities_1.ProjectProgressSchema);
|
|
85
|
+
exports.validateWorkspaceInsights = createValidator(entities_1.WorkspaceInsightsSchema);
|
|
86
|
+
exports.validateBackup = createValidator(entities_1.BackupSchema);
|
|
87
|
+
exports.validateBackupArray = createArrayValidator(exports.validateBackup);
|
|
88
|
+
exports.validateIdMapping = createValidator(entities_1.IdMappingSchema);
|
|
89
|
+
exports.validateIdMappingArray = createArrayValidator(exports.validateIdMapping);
|
|
90
|
+
exports.validateMovedId = createValidator(entities_1.MovedIdSchema);
|
|
91
|
+
exports.validateMovedIdArray = createArrayValidator(exports.validateMovedId);
|
|
77
92
|
// Sync resource validators
|
|
78
93
|
exports.validateFilter = createValidator(resources_1.FilterSchema);
|
|
79
94
|
exports.validateFilterArray = createArrayValidator(exports.validateFilter);
|
|
@@ -96,6 +111,8 @@ exports.validateCalendarAccount = createValidator(resources_1.CalendarAccountSch
|
|
|
96
111
|
exports.validateCalendarAccountArray = createArrayValidator(exports.validateCalendarAccount);
|
|
97
112
|
exports.validateReminder = createValidator(resources_1.ReminderSchema);
|
|
98
113
|
exports.validateReminderArray = createArrayValidator(exports.validateReminder);
|
|
114
|
+
exports.validateLocationReminder = createValidator(resources_1.LocationReminderSchema);
|
|
115
|
+
exports.validateLocationReminderArray = createArrayValidator(exports.validateLocationReminder);
|
|
99
116
|
exports.validateCompletedInfo = createValidator(resources_1.CompletedInfoSchema);
|
|
100
117
|
exports.validateCompletedInfoArray = createArrayValidator(exports.validateCompletedInfo);
|
|
101
118
|
exports.validateViewOptions = createValidator(resources_1.ViewOptionsSchema);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { request, isSuccess } from './
|
|
1
|
+
import { request, isSuccess } from './transport/http-client.js';
|
|
2
2
|
import { v4 as uuid } from 'uuid';
|
|
3
3
|
import { TodoistRequestError } from './types/index.js';
|
|
4
|
-
import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, } from './consts/endpoints.js';
|
|
4
|
+
import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, ENDPOINT_REST_ACCESS_TOKENS_MIGRATE, } from './consts/endpoints.js';
|
|
5
5
|
/** Available OAuth2 permission scopes. */
|
|
6
6
|
export const PERMISSIONS = [
|
|
7
7
|
'task:add',
|
|
@@ -51,7 +51,7 @@ export function getAuthStateParameter() {
|
|
|
51
51
|
* ```
|
|
52
52
|
*
|
|
53
53
|
* @returns The full authorization URL to redirect users to
|
|
54
|
-
* @see https://todoist.com/api/v1
|
|
54
|
+
* @see https://developer.todoist.com/api/v1/#tag/Authorization/OAuth
|
|
55
55
|
*/
|
|
56
56
|
export function getAuthorizationUrl({ clientId, permissions, state, baseUrl, }) {
|
|
57
57
|
if (!(permissions === null || permissions === void 0 ? void 0 : permissions.length)) {
|
|
@@ -119,7 +119,7 @@ export async function getAuthToken(args, options) {
|
|
|
119
119
|
*
|
|
120
120
|
* @returns True if revocation was successful
|
|
121
121
|
* @see https://datatracker.ietf.org/doc/html/rfc7009
|
|
122
|
-
* @see https://todoist.com/api/v1
|
|
122
|
+
* @see https://developer.todoist.com/api/v1/#tag/Authorization
|
|
123
123
|
*/
|
|
124
124
|
export async function revokeToken(args, options) {
|
|
125
125
|
if (typeof options === 'string') {
|
|
@@ -151,3 +151,46 @@ export async function revokeToken(args, options) {
|
|
|
151
151
|
});
|
|
152
152
|
return isSuccess(response);
|
|
153
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Migrates a personal API token to an OAuth access token.
|
|
156
|
+
*
|
|
157
|
+
* This allows applications to transition users from personal API tokens
|
|
158
|
+
* to proper OAuth tokens without requiring the user to go through the
|
|
159
|
+
* full OAuth authorization flow.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const { accessToken } = await migratePersonalToken({
|
|
164
|
+
* clientId: 'your-client-id',
|
|
165
|
+
* clientSecret: 'your-client-secret',
|
|
166
|
+
* personalToken: 'user-personal-token',
|
|
167
|
+
* scope: 'data:read_write,data:delete'
|
|
168
|
+
* })
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @returns The new OAuth token response
|
|
172
|
+
* @throws {@link TodoistRequestError} If the migration fails
|
|
173
|
+
*/
|
|
174
|
+
export async function migratePersonalToken(args, options) {
|
|
175
|
+
var _a;
|
|
176
|
+
const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
|
|
177
|
+
const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
|
|
178
|
+
try {
|
|
179
|
+
const response = await request({
|
|
180
|
+
httpMethod: 'POST',
|
|
181
|
+
baseUri: getSyncBaseUri(baseUrl),
|
|
182
|
+
relativePath: ENDPOINT_REST_ACCESS_TOKENS_MIGRATE,
|
|
183
|
+
apiToken: undefined,
|
|
184
|
+
payload: Object.assign(Object.assign({}, args), { scope: args.scope.join(',') }),
|
|
185
|
+
customFetch,
|
|
186
|
+
});
|
|
187
|
+
if (response.status !== 200 || !((_a = response.data) === null || _a === void 0 ? void 0 : _a.accessToken)) {
|
|
188
|
+
throw new TodoistRequestError('Personal token migration failed.', response.status, response.data);
|
|
189
|
+
}
|
|
190
|
+
return response.data;
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
const err = error;
|
|
194
|
+
throw new TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
|
|
195
|
+
}
|
|
196
|
+
}
|