@doist/todoist-sdk 15.4.0 → 15.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 +12 -0
- package/dist/esm/clients/activity-client.js +1 -0
- package/dist/esm/clients/app-client.js +25 -0
- package/dist/esm/clients/backup-client.js +5 -1
- package/dist/esm/clients/base-client.js +3 -1
- package/dist/esm/clients/billing-client.js +12 -0
- package/dist/esm/clients/comment-client.js +5 -0
- package/dist/esm/clients/email-client.js +2 -0
- package/dist/esm/clients/folder-client.js +5 -0
- package/dist/esm/clients/id-mapping-client.js +2 -0
- package/dist/esm/clients/insights-client.js +6 -0
- package/dist/esm/clients/label-client.js +9 -0
- package/dist/esm/clients/productivity-client.js +1 -0
- package/dist/esm/clients/project-client.js +16 -0
- package/dist/esm/clients/reminder-client.js +10 -0
- package/dist/esm/clients/section-client.js +8 -0
- package/dist/esm/clients/task-client.js +14 -0
- package/dist/esm/clients/template-client.js +5 -0
- package/dist/esm/clients/ui-extension-client.js +7 -0
- package/dist/esm/clients/upload-client.js +2 -0
- package/dist/esm/clients/workspace-client.js +22 -0
- package/dist/esm/todoist-api.js +4 -0
- package/dist/esm/transport/http-client.js +3 -1
- package/dist/esm/transport/sync-request.js +19 -3
- package/dist/esm/types/sync/resources/collaborators.js +3 -0
- package/dist/esm/types/sync/resources/index.js +1 -0
- package/dist/esm/types/sync/resources/user-status.js +22 -0
- package/dist/esm/types/sync/resources/user.js +2 -0
- package/dist/esm/utils/colors.js +8 -2
- package/dist/esm/utils/headers.js +22 -0
- package/dist/esm/utils/multipart-upload.js +7 -10
- package/dist/types/clients/base-client.d.ts +2 -1
- package/dist/types/todoist-api.d.ts +7 -0
- package/dist/types/transport/sync-request.d.ts +2 -1
- package/dist/types/types/sync/commands/others.d.ts +18 -0
- package/dist/types/types/sync/resources/collaborators.d.ts +18 -0
- package/dist/types/types/sync/resources/index.d.ts +1 -0
- package/dist/types/types/sync/resources/user-status.d.ts +46 -0
- package/dist/types/types/sync/resources/user.d.ts +17 -0
- package/dist/types/types/sync/response.d.ts +34 -0
- package/dist/types/utils/colors.d.ts +4 -0
- package/dist/types/utils/headers.d.ts +7 -0
- package/dist/types/utils/multipart-upload.d.ts +2 -0
- package/dist/types/utils/validators.d.ts +69 -0
- package/package.json +3 -3
|
@@ -3,6 +3,7 @@ import { API_BASE_URI } from '../consts/endpoints.js';
|
|
|
3
3
|
import { TodoistRequestError } from '../types/errors.js';
|
|
4
4
|
import { isHttpError, isNetworkError } from '../types/http.js';
|
|
5
5
|
import { camelCaseKeys, snakeCaseKeys } from '../utils/case-conversion.js';
|
|
6
|
+
import { mergeHeaders } from '../utils/headers.js';
|
|
6
7
|
import { fetchWithRetry } from './fetch-with-retry.js';
|
|
7
8
|
export function paramsSerializer(params) {
|
|
8
9
|
const qs = new URLSearchParams();
|
|
@@ -59,7 +60,8 @@ function getRequestConfiguration(args) {
|
|
|
59
60
|
const { baseURL, apiToken, requestId, customHeaders } = args;
|
|
60
61
|
const authHeader = apiToken ? { Authorization: getAuthHeader(apiToken) } : undefined;
|
|
61
62
|
const requestIdHeader = requestId ? { 'X-Request-Id': requestId } : undefined;
|
|
62
|
-
|
|
63
|
+
// Custom headers sit below auth and request id so they can never replace them.
|
|
64
|
+
const headers = mergeHeaders(defaultHeaders, customHeaders, authHeader, requestIdHeader);
|
|
63
65
|
return { baseURL, headers };
|
|
64
66
|
}
|
|
65
67
|
function getHttpClientConfig(args) {
|
|
@@ -4,8 +4,17 @@ import { DATE_FORMAT_TO_API, TIME_FORMAT_TO_API, DAY_OF_WEEK_TO_API, } from '../
|
|
|
4
4
|
import { spreadIfDefined } from '../utils/request-helpers.js';
|
|
5
5
|
import { parseSyncResponse } from '../utils/validators.js';
|
|
6
6
|
import { request } from './http-client.js';
|
|
7
|
+
// An invalid Date would otherwise be sent as `null`, which the API reads as "no expiry".
|
|
8
|
+
function serializeStatusActiveUntil(value) {
|
|
9
|
+
if (!(value instanceof Date))
|
|
10
|
+
return value;
|
|
11
|
+
if (Number.isNaN(value.getTime())) {
|
|
12
|
+
throw new TodoistArgumentError('status.activeUntil is an invalid Date');
|
|
13
|
+
}
|
|
14
|
+
return value.toISOString();
|
|
15
|
+
}
|
|
7
16
|
function serializeUserUpdateArgs(args) {
|
|
8
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, args), spreadIfDefined(args.dateFormat, (v) => ({
|
|
17
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, args), spreadIfDefined(args.dateFormat, (v) => ({
|
|
9
18
|
dateFormat: DATE_FORMAT_TO_API[v],
|
|
10
19
|
}))), spreadIfDefined(args.timeFormat, (v) => ({
|
|
11
20
|
timeFormat: TIME_FORMAT_TO_API[v],
|
|
@@ -13,7 +22,13 @@ function serializeUserUpdateArgs(args) {
|
|
|
13
22
|
startDay: DAY_OF_WEEK_TO_API[v],
|
|
14
23
|
}))), spreadIfDefined(args.nextWeek, (v) => ({
|
|
15
24
|
nextWeek: DAY_OF_WEEK_TO_API[v],
|
|
16
|
-
})))
|
|
25
|
+
}))), (args.status
|
|
26
|
+
? {
|
|
27
|
+
status: Object.assign(Object.assign({}, args.status), spreadIfDefined(args.status.activeUntil, (v) => ({
|
|
28
|
+
activeUntil: serializeStatusActiveUntil(v),
|
|
29
|
+
}))),
|
|
30
|
+
}
|
|
31
|
+
: {}));
|
|
17
32
|
}
|
|
18
33
|
function serializeTaskUpdateDateCompleteArgs(args) {
|
|
19
34
|
return Object.assign(Object.assign(Object.assign({}, args), { isForward: args.isForward ? 1 : 0 }), spreadIfDefined(args.resetSubtasks, (v) => ({
|
|
@@ -47,7 +62,7 @@ function preprocessSyncCommands(commands) {
|
|
|
47
62
|
/**
|
|
48
63
|
* Makes a request to the Sync API and handles error checking.
|
|
49
64
|
*
|
|
50
|
-
* @param ctx - HTTP identity (auth token, sync API base URI, optional custom fetch).
|
|
65
|
+
* @param ctx - HTTP identity (auth token, sync API base URI, optional custom fetch and headers).
|
|
51
66
|
* @param syncRequest - The sync request payload.
|
|
52
67
|
* @param options - Optional request identifier and commands flag.
|
|
53
68
|
* @returns The sync response data.
|
|
@@ -64,6 +79,7 @@ export async function performSyncRequest(ctx, syncRequest, options = {}) {
|
|
|
64
79
|
relativePath: ENDPOINT_SYNC,
|
|
65
80
|
apiToken: ctx.authToken,
|
|
66
81
|
customFetch: ctx.customFetch,
|
|
82
|
+
customHeaders: ctx.customHeaders,
|
|
67
83
|
payload: processedRequest,
|
|
68
84
|
requestId: requestId,
|
|
69
85
|
hasSyncCommands: hasSyncCommands,
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { WorkspaceRoleSchema } from '../../workspaces/types.js';
|
|
3
|
+
import { UserStatusSchema } from './user-status.js';
|
|
3
4
|
export const CollaboratorSchema = z.looseObject({
|
|
4
5
|
id: z.string(),
|
|
5
6
|
email: z.string(),
|
|
6
7
|
fullName: z.string(),
|
|
7
8
|
timezone: z.string(),
|
|
8
9
|
imageId: z.string().nullable(),
|
|
10
|
+
/** The collaborator's shared status. Not related to {@link CollaboratorStatus}. */
|
|
11
|
+
status: UserStatusSchema.nullish(),
|
|
9
12
|
});
|
|
10
13
|
/** Available collaborator statuses. */
|
|
11
14
|
export const COLLABORATOR_STATUSES = ['active', 'invited'];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* `mode` stays a plain string and `scope` optional so that a new mode, or an effect another
|
|
4
|
+
* client stored without a scope, does not break parsing.
|
|
5
|
+
*/
|
|
6
|
+
export const UserStatusEffectSchema = z.looseObject({
|
|
7
|
+
scope: z.looseObject({ mode: z.string() }).optional(),
|
|
8
|
+
});
|
|
9
|
+
export const UserStatusEffectsSchema = z.looseObject({
|
|
10
|
+
pauseNotifications: UserStatusEffectSchema.optional(),
|
|
11
|
+
pauseActivity: UserStatusEffectSchema.optional(),
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* A user's status, shared across Todoist and Comms. The API returns `null` in its place
|
|
15
|
+
* when the user has no status or it has expired.
|
|
16
|
+
*/
|
|
17
|
+
export const UserStatusSchema = z.looseObject({
|
|
18
|
+
message: z.string(),
|
|
19
|
+
emoji: z.string().nullish(),
|
|
20
|
+
activeUntil: z.coerce.date().nullish(),
|
|
21
|
+
effects: UserStatusEffectsSchema.default({}),
|
|
22
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { PREMIUM_STATUSES } from '../../users/types.js';
|
|
3
3
|
import { BooleanFromZeroOneSchema, DateFormatSchema, DayOfWeekSchema, TimeFormatSchema, } from '../user-preferences.js';
|
|
4
|
+
import { UserStatusSchema } from './user-status.js';
|
|
4
5
|
export const FeaturesSchema = z.looseObject({
|
|
5
6
|
karmaDisabled: z.union([z.boolean(), BooleanFromZeroOneSchema]),
|
|
6
7
|
restriction: z.number().int(),
|
|
@@ -95,6 +96,7 @@ export const SyncUserSchema = z.looseObject({
|
|
|
95
96
|
sortOrder: z.number().int(),
|
|
96
97
|
startDay: DayOfWeekSchema,
|
|
97
98
|
startPage: z.string(),
|
|
99
|
+
status: UserStatusSchema.nullish(),
|
|
98
100
|
themeId: z.string(),
|
|
99
101
|
timeFormat: TimeFormatSchema,
|
|
100
102
|
token: z.string().optional(),
|
package/dist/esm/utils/colors.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { colorForDisplay } from '@doist/sdk-kmp/shared-todoist-all';
|
|
1
2
|
export const berryRed = {
|
|
2
3
|
key: 'berry_red',
|
|
3
4
|
displayName: 'Berry Red',
|
|
@@ -98,6 +99,10 @@ export const taupe = {
|
|
|
98
99
|
displayName: 'Taupe',
|
|
99
100
|
hexValue: '#ccac93',
|
|
100
101
|
};
|
|
102
|
+
/**
|
|
103
|
+
* Every color, in the order the apps show them. The keys mirror `TodoistColor` from
|
|
104
|
+
* `@doist/sdk-kmp/shared-todoist-all`; the display names and hex values are the SDK's own.
|
|
105
|
+
*/
|
|
101
106
|
export const colors = [
|
|
102
107
|
berryRed,
|
|
103
108
|
red,
|
|
@@ -134,6 +139,7 @@ export const defaultColor = charcoal;
|
|
|
134
139
|
* ```
|
|
135
140
|
*/
|
|
136
141
|
export function getColorByKey(colorKey) {
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
var _a;
|
|
143
|
+
const { key } = colorForDisplay(colorKey);
|
|
144
|
+
return (_a = colors.find((color) => color.key === key)) !== null && _a !== void 0 ? _a : defaultColor;
|
|
139
145
|
}
|
|
@@ -11,3 +11,25 @@ export function headersToRecord(headers) {
|
|
|
11
11
|
});
|
|
12
12
|
return result;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Merges header records left to right. HTTP header names are case-insensitive,
|
|
16
|
+
* so a later record replaces any earlier header with the same name whatever
|
|
17
|
+
* its case. Without this, a caller's `authorization` would sit alongside the
|
|
18
|
+
* SDK's `Authorization` and `fetch` would join the two into one value.
|
|
19
|
+
*/
|
|
20
|
+
export function mergeHeaders(...sources) {
|
|
21
|
+
const merged = {};
|
|
22
|
+
for (const source of sources) {
|
|
23
|
+
if (!source)
|
|
24
|
+
continue;
|
|
25
|
+
for (const [name, value] of Object.entries(source)) {
|
|
26
|
+
const lowerName = name.toLowerCase();
|
|
27
|
+
for (const existingName of Object.keys(merged)) {
|
|
28
|
+
if (existingName.toLowerCase() === lowerName)
|
|
29
|
+
delete merged[existingName];
|
|
30
|
+
}
|
|
31
|
+
merged[name] = value;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return merged;
|
|
35
|
+
}
|
|
@@ -22,6 +22,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
22
22
|
import { fetchWithRetry } from '../transport/fetch-with-retry.js';
|
|
23
23
|
import { toTodoistRequestError } from '../transport/http-client.js';
|
|
24
24
|
import { camelCaseKeys } from './case-conversion.js';
|
|
25
|
+
import { mergeHeaders } from './headers.js';
|
|
25
26
|
/**
|
|
26
27
|
* Helper function to determine content-type from filename extension.
|
|
27
28
|
* @param fileName - The filename to analyze
|
|
@@ -199,18 +200,12 @@ function buildMultipartBody(args) {
|
|
|
199
200
|
* ```
|
|
200
201
|
*/
|
|
201
202
|
export async function uploadMultipartFile(args) {
|
|
202
|
-
const { baseUrl, authToken, endpoint, file, fileName, additionalFields, requestId, customFetch, } = args;
|
|
203
|
+
const { baseUrl, authToken, endpoint, file, fileName, additionalFields, requestId, customHeaders, customFetch, } = args;
|
|
203
204
|
// Capture original stack for better error reporting
|
|
204
205
|
const originalStack = new Error();
|
|
205
206
|
// Build the full URL
|
|
206
207
|
const url = `${baseUrl}${endpoint}`;
|
|
207
208
|
let body;
|
|
208
|
-
const headers = {
|
|
209
|
-
Authorization: `Bearer ${authToken}`,
|
|
210
|
-
};
|
|
211
|
-
if (requestId) {
|
|
212
|
-
headers['X-Request-Id'] = requestId;
|
|
213
|
-
}
|
|
214
209
|
// Resolve the file to something every `fetch` accepts as a body part: a
|
|
215
210
|
// Blob where the size is known up front, or a Node stream that gets piped
|
|
216
211
|
// through untouched.
|
|
@@ -251,9 +246,11 @@ export async function uploadMultipartFile(args) {
|
|
|
251
246
|
getContentTypeFromFileName(resolvedFileName),
|
|
252
247
|
additionalFields,
|
|
253
248
|
});
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
249
|
+
// Custom headers come first so they can never replace the SDK's own.
|
|
250
|
+
const headers = mergeHeaders(customHeaders, Object.assign(Object.assign({ Authorization: `Bearer ${authToken}` }, (requestId ? { 'X-Request-Id': requestId } : {})), {
|
|
251
|
+
// The boundary is ours, so Content-Type has to be set explicitly —
|
|
252
|
+
// `fetch` only fills it in for a `FormData` body.
|
|
253
|
+
'Content-Type': multipart.contentType }));
|
|
257
254
|
body = multipart.body;
|
|
258
255
|
// Make the request using fetch
|
|
259
256
|
let response;
|
|
@@ -4,7 +4,7 @@ import type { CustomFetch } from '../types/http.js';
|
|
|
4
4
|
* Internal base class for every domain sub-client (tasks, projects, …).
|
|
5
5
|
*
|
|
6
6
|
* Not exported from the package — sub-clients are an implementation detail
|
|
7
|
-
* of `TodoistApi`. Holds the
|
|
7
|
+
* of `TodoistApi`. Holds the pieces of HTTP identity every sub-client
|
|
8
8
|
* needs and exposes a typed accessor to feed the Sync API helper.
|
|
9
9
|
*
|
|
10
10
|
* The constructor takes a {@link SyncRequestContext} — the same record
|
|
@@ -17,6 +17,7 @@ export declare abstract class BaseClient {
|
|
|
17
17
|
protected readonly syncApiBase: string;
|
|
18
18
|
protected readonly apiRootBase: string;
|
|
19
19
|
protected readonly customFetch?: CustomFetch;
|
|
20
|
+
protected readonly customHeaders?: Record<string, string>;
|
|
20
21
|
constructor(context: SyncRequestContext);
|
|
21
22
|
protected get syncContext(): SyncRequestContext;
|
|
22
23
|
}
|
|
@@ -55,11 +55,18 @@ export type TodoistApiOptions = {
|
|
|
55
55
|
* Optional custom fetch function for alternative HTTP clients (e.g., Obsidian's requestUrl, React Native fetch)
|
|
56
56
|
*/
|
|
57
57
|
customFetch?: CustomFetch;
|
|
58
|
+
/**
|
|
59
|
+
* Optional headers sent with every API request, e.g. `{ 'Doist-Platform': 'cli' }` for client
|
|
60
|
+
* attribution. Cannot replace `Authorization` or `X-Request-Id`. Not sent on attachment
|
|
61
|
+
* downloads, which redirect to a third-party CDN.
|
|
62
|
+
*/
|
|
63
|
+
headers?: Record<string, string>;
|
|
58
64
|
};
|
|
59
65
|
export declare class TodoistApi {
|
|
60
66
|
private authToken;
|
|
61
67
|
private syncApiBase;
|
|
62
68
|
private customFetch?;
|
|
69
|
+
private customHeaders?;
|
|
63
70
|
private readonly taskClient;
|
|
64
71
|
private readonly projectClient;
|
|
65
72
|
private readonly sectionClient;
|
|
@@ -11,11 +11,12 @@ export type SyncRequestContext = {
|
|
|
11
11
|
authToken: string;
|
|
12
12
|
syncApiBase: string;
|
|
13
13
|
customFetch?: CustomFetch;
|
|
14
|
+
customHeaders?: Record<string, string>;
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* Makes a request to the Sync API and handles error checking.
|
|
17
18
|
*
|
|
18
|
-
* @param ctx - HTTP identity (auth token, sync API base URI, optional custom fetch).
|
|
19
|
+
* @param ctx - HTTP identity (auth token, sync API base URI, optional custom fetch and headers).
|
|
19
20
|
* @param syncRequest - The sync request payload.
|
|
20
21
|
* @param options - Optional request identifier and commands flag.
|
|
21
22
|
* @returns The sync response data.
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import type { DateFormat, DayOfWeek, TimeFormat } from '../user-preferences.js';
|
|
2
|
+
export type UserStatusEffectArgs = {
|
|
3
|
+
scope?: {
|
|
4
|
+
mode: string;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
/** The complete status to set. It replaces any existing status. */
|
|
8
|
+
export type UserStatusArgs = {
|
|
9
|
+
message: string;
|
|
10
|
+
emoji?: string;
|
|
11
|
+
/** Must be in the future; omit it for no expiry. A `Date` is sent as an ISO 8601 string. */
|
|
12
|
+
activeUntil?: Date | string;
|
|
13
|
+
effects?: {
|
|
14
|
+
pauseNotifications?: UserStatusEffectArgs;
|
|
15
|
+
pauseActivity?: UserStatusEffectArgs;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
2
18
|
export type UserUpdateArgs = {
|
|
3
19
|
fullName?: string;
|
|
4
20
|
autoReminder?: number;
|
|
@@ -9,6 +25,8 @@ export type UserUpdateArgs = {
|
|
|
9
25
|
themeId?: string;
|
|
10
26
|
timeFormat?: TimeFormat;
|
|
11
27
|
timezone?: string;
|
|
28
|
+
/** `null` clears the status; omitting it leaves the current status unchanged. */
|
|
29
|
+
status?: UserStatusArgs | null;
|
|
12
30
|
};
|
|
13
31
|
export type DeleteCollaboratorArgs = {
|
|
14
32
|
projectId: string;
|
|
@@ -5,6 +5,24 @@ export declare const CollaboratorSchema: z.ZodObject<{
|
|
|
5
5
|
fullName: z.ZodString;
|
|
6
6
|
timezone: z.ZodString;
|
|
7
7
|
imageId: z.ZodNullable<z.ZodString>;
|
|
8
|
+
/** The collaborator's shared status. Not related to {@link CollaboratorStatus}. */
|
|
9
|
+
status: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
10
|
+
message: z.ZodString;
|
|
11
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
12
|
+
activeUntil: z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>;
|
|
13
|
+
effects: z.ZodDefault<z.ZodObject<{
|
|
14
|
+
pauseNotifications: z.ZodOptional<z.ZodObject<{
|
|
15
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
16
|
+
mode: z.ZodString;
|
|
17
|
+
}, z.core.$loose>>;
|
|
18
|
+
}, z.core.$loose>>;
|
|
19
|
+
pauseActivity: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
mode: z.ZodString;
|
|
22
|
+
}, z.core.$loose>>;
|
|
23
|
+
}, z.core.$loose>>;
|
|
24
|
+
}, z.core.$loose>>;
|
|
25
|
+
}, z.core.$loose>>>;
|
|
8
26
|
}, z.core.$loose>;
|
|
9
27
|
export type Collaborator = z.infer<typeof CollaboratorSchema>;
|
|
10
28
|
/** Available collaborator statuses. */
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* `mode` stays a plain string and `scope` optional so that a new mode, or an effect another
|
|
4
|
+
* client stored without a scope, does not break parsing.
|
|
5
|
+
*/
|
|
6
|
+
export declare const UserStatusEffectSchema: z.ZodObject<{
|
|
7
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
8
|
+
mode: z.ZodString;
|
|
9
|
+
}, z.core.$loose>>;
|
|
10
|
+
}, z.core.$loose>;
|
|
11
|
+
export type UserStatusEffect = z.infer<typeof UserStatusEffectSchema>;
|
|
12
|
+
export declare const UserStatusEffectsSchema: z.ZodObject<{
|
|
13
|
+
pauseNotifications: z.ZodOptional<z.ZodObject<{
|
|
14
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
15
|
+
mode: z.ZodString;
|
|
16
|
+
}, z.core.$loose>>;
|
|
17
|
+
}, z.core.$loose>>;
|
|
18
|
+
pauseActivity: z.ZodOptional<z.ZodObject<{
|
|
19
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
mode: z.ZodString;
|
|
21
|
+
}, z.core.$loose>>;
|
|
22
|
+
}, z.core.$loose>>;
|
|
23
|
+
}, z.core.$loose>;
|
|
24
|
+
export type UserStatusEffects = z.infer<typeof UserStatusEffectsSchema>;
|
|
25
|
+
/**
|
|
26
|
+
* A user's status, shared across Todoist and Comms. The API returns `null` in its place
|
|
27
|
+
* when the user has no status or it has expired.
|
|
28
|
+
*/
|
|
29
|
+
export declare const UserStatusSchema: z.ZodObject<{
|
|
30
|
+
message: z.ZodString;
|
|
31
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
32
|
+
activeUntil: z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>;
|
|
33
|
+
effects: z.ZodDefault<z.ZodObject<{
|
|
34
|
+
pauseNotifications: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
mode: z.ZodString;
|
|
37
|
+
}, z.core.$loose>>;
|
|
38
|
+
}, z.core.$loose>>;
|
|
39
|
+
pauseActivity: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
41
|
+
mode: z.ZodString;
|
|
42
|
+
}, z.core.$loose>>;
|
|
43
|
+
}, z.core.$loose>>;
|
|
44
|
+
}, z.core.$loose>>;
|
|
45
|
+
}, z.core.$loose>;
|
|
46
|
+
export type UserStatus = z.infer<typeof UserStatusSchema>;
|
|
@@ -115,6 +115,23 @@ export declare const SyncUserSchema: z.ZodObject<{
|
|
|
115
115
|
sortOrder: z.ZodNumber;
|
|
116
116
|
startDay: z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>, z.ZodLiteral<6>, z.ZodLiteral<7>]>, z.ZodTransform<"Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday", 3 | 2 | 1 | 7 | 4 | 5 | 6>>;
|
|
117
117
|
startPage: z.ZodString;
|
|
118
|
+
status: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
119
|
+
message: z.ZodString;
|
|
120
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
121
|
+
activeUntil: z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>;
|
|
122
|
+
effects: z.ZodDefault<z.ZodObject<{
|
|
123
|
+
pauseNotifications: z.ZodOptional<z.ZodObject<{
|
|
124
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
125
|
+
mode: z.ZodString;
|
|
126
|
+
}, z.core.$loose>>;
|
|
127
|
+
}, z.core.$loose>>;
|
|
128
|
+
pauseActivity: z.ZodOptional<z.ZodObject<{
|
|
129
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
130
|
+
mode: z.ZodString;
|
|
131
|
+
}, z.core.$loose>>;
|
|
132
|
+
}, z.core.$loose>>;
|
|
133
|
+
}, z.core.$loose>>;
|
|
134
|
+
}, z.core.$loose>>>;
|
|
118
135
|
themeId: z.ZodString;
|
|
119
136
|
timeFormat: z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>]>, z.ZodTransform<"24h" | "12h", 0 | 1>>;
|
|
120
137
|
token: z.ZodOptional<z.ZodString>;
|
|
@@ -448,6 +448,23 @@ export declare const SyncResponseSchema: z.ZodObject<{
|
|
|
448
448
|
sortOrder: z.ZodNumber;
|
|
449
449
|
startDay: z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>, z.ZodLiteral<6>, z.ZodLiteral<7>]>, z.ZodTransform<"Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday", 3 | 2 | 1 | 7 | 4 | 5 | 6>>;
|
|
450
450
|
startPage: z.ZodString;
|
|
451
|
+
status: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
452
|
+
message: z.ZodString;
|
|
453
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
454
|
+
activeUntil: z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>;
|
|
455
|
+
effects: z.ZodDefault<z.ZodObject<{
|
|
456
|
+
pauseNotifications: z.ZodOptional<z.ZodObject<{
|
|
457
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
458
|
+
mode: z.ZodString;
|
|
459
|
+
}, z.core.$loose>>;
|
|
460
|
+
}, z.core.$loose>>;
|
|
461
|
+
pauseActivity: z.ZodOptional<z.ZodObject<{
|
|
462
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
463
|
+
mode: z.ZodString;
|
|
464
|
+
}, z.core.$loose>>;
|
|
465
|
+
}, z.core.$loose>>;
|
|
466
|
+
}, z.core.$loose>>;
|
|
467
|
+
}, z.core.$loose>>>;
|
|
451
468
|
themeId: z.ZodString;
|
|
452
469
|
timeFormat: z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>]>, z.ZodTransform<"24h" | "12h", 0 | 1>>;
|
|
453
470
|
token: z.ZodOptional<z.ZodString>;
|
|
@@ -492,6 +509,23 @@ export declare const SyncResponseSchema: z.ZodObject<{
|
|
|
492
509
|
fullName: z.ZodString;
|
|
493
510
|
timezone: z.ZodString;
|
|
494
511
|
imageId: z.ZodNullable<z.ZodString>;
|
|
512
|
+
status: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
513
|
+
message: z.ZodString;
|
|
514
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
515
|
+
activeUntil: z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>;
|
|
516
|
+
effects: z.ZodDefault<z.ZodObject<{
|
|
517
|
+
pauseNotifications: z.ZodOptional<z.ZodObject<{
|
|
518
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
519
|
+
mode: z.ZodString;
|
|
520
|
+
}, z.core.$loose>>;
|
|
521
|
+
}, z.core.$loose>>;
|
|
522
|
+
pauseActivity: z.ZodOptional<z.ZodObject<{
|
|
523
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
524
|
+
mode: z.ZodString;
|
|
525
|
+
}, z.core.$loose>>;
|
|
526
|
+
}, z.core.$loose>>;
|
|
527
|
+
}, z.core.$loose>>;
|
|
528
|
+
}, z.core.$loose>>>;
|
|
495
529
|
}, z.core.$loose>>>;
|
|
496
530
|
collaboratorStates: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
497
531
|
userId: z.ZodString;
|
|
@@ -99,6 +99,10 @@ export declare const taupe: {
|
|
|
99
99
|
readonly displayName: "Taupe";
|
|
100
100
|
readonly hexValue: "#ccac93";
|
|
101
101
|
};
|
|
102
|
+
/**
|
|
103
|
+
* Every color, in the order the apps show them. The keys mirror `TodoistColor` from
|
|
104
|
+
* `@doist/sdk-kmp/shared-todoist-all`; the display names and hex values are the SDK's own.
|
|
105
|
+
*/
|
|
102
106
|
export declare const colors: readonly [{
|
|
103
107
|
readonly key: "berry_red";
|
|
104
108
|
readonly displayName: "Berry Red";
|
|
@@ -5,3 +5,10 @@
|
|
|
5
5
|
* `CustomFetchResponse`).
|
|
6
6
|
*/
|
|
7
7
|
export declare function headersToRecord(headers: Headers): Record<string, string>;
|
|
8
|
+
/**
|
|
9
|
+
* Merges header records left to right. HTTP header names are case-insensitive,
|
|
10
|
+
* so a later record replaces any earlier header with the same name whatever
|
|
11
|
+
* its case. Without this, a caller's `authorization` would sit alongside the
|
|
12
|
+
* SDK's `Authorization` and `fetch` would join the two into one value.
|
|
13
|
+
*/
|
|
14
|
+
export declare function mergeHeaders(...sources: (Record<string, string> | undefined)[]): Record<string, string>;
|
|
@@ -7,6 +7,8 @@ type UploadMultipartFileArgs = {
|
|
|
7
7
|
fileName?: string;
|
|
8
8
|
additionalFields: Record<string, string | number | boolean>;
|
|
9
9
|
requestId?: string;
|
|
10
|
+
/** Extra headers sent with the upload. Cannot replace `Authorization`, `X-Request-Id` or `Content-Type`. */
|
|
11
|
+
customHeaders?: Record<string, string>;
|
|
10
12
|
customFetch?: CustomFetch;
|
|
11
13
|
};
|
|
12
14
|
/**
|
|
@@ -772,6 +772,29 @@ export declare const validateCollaborator: (input: unknown) => {
|
|
|
772
772
|
fullName: string;
|
|
773
773
|
timezone: string;
|
|
774
774
|
imageId: string | null;
|
|
775
|
+
status?: {
|
|
776
|
+
[x: string]: unknown;
|
|
777
|
+
message: string;
|
|
778
|
+
effects: {
|
|
779
|
+
[x: string]: unknown;
|
|
780
|
+
pauseNotifications?: {
|
|
781
|
+
[x: string]: unknown;
|
|
782
|
+
scope?: {
|
|
783
|
+
[x: string]: unknown;
|
|
784
|
+
mode: string;
|
|
785
|
+
} | undefined;
|
|
786
|
+
} | undefined;
|
|
787
|
+
pauseActivity?: {
|
|
788
|
+
[x: string]: unknown;
|
|
789
|
+
scope?: {
|
|
790
|
+
[x: string]: unknown;
|
|
791
|
+
mode: string;
|
|
792
|
+
} | undefined;
|
|
793
|
+
} | undefined;
|
|
794
|
+
};
|
|
795
|
+
emoji?: string | null | undefined;
|
|
796
|
+
activeUntil?: Date | null | undefined;
|
|
797
|
+
} | null | undefined;
|
|
775
798
|
}, validateCollaboratorArray: (input: unknown) => {
|
|
776
799
|
[x: string]: unknown;
|
|
777
800
|
id: string;
|
|
@@ -779,6 +802,29 @@ export declare const validateCollaborator: (input: unknown) => {
|
|
|
779
802
|
fullName: string;
|
|
780
803
|
timezone: string;
|
|
781
804
|
imageId: string | null;
|
|
805
|
+
status?: {
|
|
806
|
+
[x: string]: unknown;
|
|
807
|
+
message: string;
|
|
808
|
+
effects: {
|
|
809
|
+
[x: string]: unknown;
|
|
810
|
+
pauseNotifications?: {
|
|
811
|
+
[x: string]: unknown;
|
|
812
|
+
scope?: {
|
|
813
|
+
[x: string]: unknown;
|
|
814
|
+
mode: string;
|
|
815
|
+
} | undefined;
|
|
816
|
+
} | undefined;
|
|
817
|
+
pauseActivity?: {
|
|
818
|
+
[x: string]: unknown;
|
|
819
|
+
scope?: {
|
|
820
|
+
[x: string]: unknown;
|
|
821
|
+
mode: string;
|
|
822
|
+
} | undefined;
|
|
823
|
+
} | undefined;
|
|
824
|
+
};
|
|
825
|
+
emoji?: string | null | undefined;
|
|
826
|
+
activeUntil?: Date | null | undefined;
|
|
827
|
+
} | null | undefined;
|
|
782
828
|
}[];
|
|
783
829
|
export declare const validateCollaboratorState: (input: unknown) => {
|
|
784
830
|
[x: string]: unknown;
|
|
@@ -1472,6 +1518,29 @@ export declare const validateSyncUser: (input: unknown) => {
|
|
|
1472
1518
|
remaining: number;
|
|
1473
1519
|
resetDate: Date;
|
|
1474
1520
|
} | null | undefined;
|
|
1521
|
+
status?: {
|
|
1522
|
+
[x: string]: unknown;
|
|
1523
|
+
message: string;
|
|
1524
|
+
effects: {
|
|
1525
|
+
[x: string]: unknown;
|
|
1526
|
+
pauseNotifications?: {
|
|
1527
|
+
[x: string]: unknown;
|
|
1528
|
+
scope?: {
|
|
1529
|
+
[x: string]: unknown;
|
|
1530
|
+
mode: string;
|
|
1531
|
+
} | undefined;
|
|
1532
|
+
} | undefined;
|
|
1533
|
+
pauseActivity?: {
|
|
1534
|
+
[x: string]: unknown;
|
|
1535
|
+
scope?: {
|
|
1536
|
+
[x: string]: unknown;
|
|
1537
|
+
mode: string;
|
|
1538
|
+
} | undefined;
|
|
1539
|
+
} | undefined;
|
|
1540
|
+
};
|
|
1541
|
+
emoji?: string | null | undefined;
|
|
1542
|
+
activeUntil?: Date | null | undefined;
|
|
1543
|
+
} | null | undefined;
|
|
1475
1544
|
token?: string | undefined;
|
|
1476
1545
|
};
|
|
1477
1546
|
export declare const validateUserSettings: (input: unknown) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/todoist-sdk",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.6.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",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"fflate": "0.8.2"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@doist/sdk-kmp": "0.
|
|
49
|
+
"@doist/sdk-kmp": "0.5.0",
|
|
50
50
|
"camelcase": "6.3.0",
|
|
51
51
|
"emoji-regex": "10.6.0",
|
|
52
52
|
"ts-custom-error": "^3.2.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"msw": "2.13.2",
|
|
66
66
|
"npm-run-all2": "8.0.4",
|
|
67
67
|
"obsidian": "^1.10.2-1",
|
|
68
|
-
"oxfmt": "0.
|
|
68
|
+
"oxfmt": "0.73.0",
|
|
69
69
|
"oxlint": "1.57.0",
|
|
70
70
|
"rimraf": "6.1.3",
|
|
71
71
|
"semantic-release": "25.0.3",
|