@doist/todoist-sdk 14.0.1 → 14.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.
@@ -0,0 +1,277 @@
1
+ /** Todoist's default task-ordering hierarchies. */
2
+ export const DEFAULT_TASK_ORDERS = ['PRIORITY_FIRST', 'DATE_FIRST'];
3
+ const DEFAULT_TIMEZONE = 'UTC';
4
+ const DEFAULT_LOCALE = 'en';
5
+ const DATE_ONLY_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
6
+ const DATE_TIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?$/;
7
+ const EXPLICIT_TIMEZONE_PATTERN = /(?:Z|[+-]\d{2}:?\d{2})$/i;
8
+ const DATE_TIME_FORMATTERS = new Map();
9
+ function compareNumber(a, b) {
10
+ if (a === b)
11
+ return 0;
12
+ return a < b ? -1 : 1;
13
+ }
14
+ function isValidDateParts(year, month, day) {
15
+ const date = new Date(0);
16
+ date.setUTCHours(0, 0, 0, 0);
17
+ date.setUTCFullYear(year, month - 1, day);
18
+ return (date.getUTCFullYear() === year &&
19
+ date.getUTCMonth() === month - 1 &&
20
+ date.getUTCDate() === day);
21
+ }
22
+ function dateSortValue({ year, month, day, hour = 0, minute = 0, second = 0, millisecond = 0, isAllDay = false, }) {
23
+ if (!isValidDateParts(year, month, day) ||
24
+ hour < 0 ||
25
+ hour > 23 ||
26
+ minute < 0 ||
27
+ minute > 59 ||
28
+ second < 0 ||
29
+ second > 59 ||
30
+ millisecond < 0 ||
31
+ millisecond > 999) {
32
+ return null;
33
+ }
34
+ return {
35
+ day: year * 10000 + month * 100 + day,
36
+ kind: isAllDay ? 0 : 1,
37
+ time: ((hour * 60 + minute) * 60 + second) * 1000 + millisecond,
38
+ };
39
+ }
40
+ function parseDateOnly(value) {
41
+ const match = DATE_ONLY_PATTERN.exec(value);
42
+ if (!match)
43
+ return null;
44
+ return dateSortValue({
45
+ year: Number(match[1]),
46
+ month: Number(match[2]),
47
+ day: Number(match[3]),
48
+ isAllDay: true,
49
+ });
50
+ }
51
+ function parseDateTimeComponents(value) {
52
+ var _a, _b;
53
+ const match = DATE_TIME_PATTERN.exec(value);
54
+ if (!match)
55
+ return null;
56
+ const milliseconds = Number(((_a = match[7]) !== null && _a !== void 0 ? _a : '').padEnd(3, '0').slice(0, 3));
57
+ const components = {
58
+ year: Number(match[1]),
59
+ month: Number(match[2]),
60
+ day: Number(match[3]),
61
+ hour: Number(match[4]),
62
+ minute: Number(match[5]),
63
+ second: Number((_b = match[6]) !== null && _b !== void 0 ? _b : 0),
64
+ millisecond: milliseconds,
65
+ };
66
+ return dateSortValue(components) === null ? null : components;
67
+ }
68
+ function createDateTimeFormatter(timezone, fallback) {
69
+ const cached = DATE_TIME_FORMATTERS.get(timezone);
70
+ if (cached)
71
+ return cached;
72
+ try {
73
+ const formatter = new Intl.DateTimeFormat('en-US', {
74
+ timeZone: timezone,
75
+ calendar: 'iso8601',
76
+ numberingSystem: 'latn',
77
+ year: 'numeric',
78
+ month: '2-digit',
79
+ day: '2-digit',
80
+ hour: '2-digit',
81
+ minute: '2-digit',
82
+ second: '2-digit',
83
+ hourCycle: 'h23',
84
+ });
85
+ DATE_TIME_FORMATTERS.set(timezone, formatter);
86
+ return formatter;
87
+ }
88
+ catch (_a) {
89
+ return fallback !== null && fallback !== void 0 ? fallback : createDateTimeFormatter(DEFAULT_TIMEZONE);
90
+ }
91
+ }
92
+ function componentsAt(timestamp, formatter) {
93
+ const parts = formatter.formatToParts(new Date(timestamp));
94
+ function part(type) {
95
+ var _a;
96
+ return Number((_a = parts.find((entry) => entry.type === type)) === null || _a === void 0 ? void 0 : _a.value);
97
+ }
98
+ return {
99
+ year: part('year'),
100
+ month: part('month'),
101
+ day: part('day'),
102
+ hour: part('hour'),
103
+ minute: part('minute'),
104
+ second: part('second'),
105
+ millisecond: new Date(timestamp).getUTCMilliseconds(),
106
+ };
107
+ }
108
+ function componentsAsUtcTimestamp({ year, month, day, hour = 0, minute = 0, second = 0, millisecond = 0, }) {
109
+ const date = new Date(0);
110
+ date.setUTCFullYear(year, month - 1, day);
111
+ date.setUTCHours(hour, minute, second, millisecond);
112
+ return date.getTime();
113
+ }
114
+ /** Resolves a zoned wall clock to an instant, including daylight-saving offsets. */
115
+ function timestampForWallClock(components, formatter) {
116
+ const target = componentsAsUtcTimestamp(components);
117
+ let timestamp = target;
118
+ for (let attempt = 0; attempt < 4; attempt += 1) {
119
+ const adjustment = target - componentsAsUtcTimestamp(componentsAt(timestamp, formatter));
120
+ if (adjustment === 0)
121
+ return timestamp;
122
+ timestamp += adjustment;
123
+ }
124
+ return null;
125
+ }
126
+ function dateSortValueAt(timestamp, formatter) {
127
+ const value = dateSortValue(componentsAt(timestamp, formatter));
128
+ return value ? Object.assign(Object.assign({}, value), { time: timestamp }) : null;
129
+ }
130
+ function parseFixedDateTime(value, formatter) {
131
+ if (parseDateTimeComponents(value.replace(EXPLICIT_TIMEZONE_PATTERN, '')) === null)
132
+ return null;
133
+ const timestamp = Date.parse(value);
134
+ return Number.isNaN(timestamp) ? null : dateSortValueAt(timestamp, formatter);
135
+ }
136
+ function parseZonedFloatingDateTime(value, sourceFormatter, accountFormatter) {
137
+ const components = parseDateTimeComponents(value);
138
+ if (!components)
139
+ return null;
140
+ const timestamp = timestampForWallClock(components, sourceFormatter);
141
+ return timestamp === null ? null : dateSortValueAt(timestamp, accountFormatter);
142
+ }
143
+ function parseTaskDate(value, formatter, timezone) {
144
+ var _a;
145
+ return ((_a = parseDateOnly(value)) !== null && _a !== void 0 ? _a : (EXPLICIT_TIMEZONE_PATTERN.test(value)
146
+ ? parseFixedDateTime(value, formatter)
147
+ : parseZonedFloatingDateTime(value, timezone ? createDateTimeFormatter(timezone, formatter) : formatter, formatter)));
148
+ }
149
+ function compareNullable(a, b, compare) {
150
+ if (a === null || b === null) {
151
+ if (a === b)
152
+ return 0;
153
+ return a === null ? 1 : -1;
154
+ }
155
+ return compare(a, b);
156
+ }
157
+ function compareDateValues(left, right) {
158
+ return (compareNumber(left.day, right.day) ||
159
+ compareNumber(left.kind, right.kind) ||
160
+ compareNumber(left.time, right.time));
161
+ }
162
+ function compareDate(a, b) {
163
+ return compareNullable(a, b, compareDateValues);
164
+ }
165
+ function compareOptionalNumber(a, b) {
166
+ return compareNullable(a, b, compareNumber);
167
+ }
168
+ function compareOptionalText(a, b, collator) {
169
+ return compareNullable(a, b, (left, right) => collator.compare(left, right));
170
+ }
171
+ function prepareTasks(tasks, context, { formatter, resolveAssignee }) {
172
+ return tasks.map((task, index) => {
173
+ var _a, _b, _c, _d, _e, _f, _g;
174
+ const due = task.due
175
+ ? parseTaskDate((_a = task.due.datetime) !== null && _a !== void 0 ? _a : task.due.date, formatter, task.due.timezone)
176
+ : null;
177
+ const deadline = task.deadline ? parseTaskDate(task.deadline.date, formatter) : null;
178
+ return {
179
+ task,
180
+ index,
181
+ due,
182
+ deadline,
183
+ schedule: due !== null && due !== void 0 ? due : deadline,
184
+ added: task.addedAt && !Number.isNaN(task.addedAt.getTime())
185
+ ? task.addedAt.getTime()
186
+ : null,
187
+ project: (_c = (_b = context.projectOrder) === null || _b === void 0 ? void 0 : _b.get(task.projectId)) !== null && _c !== void 0 ? _c : null,
188
+ workspace: (_e = (_d = context.workspaceOrder) === null || _d === void 0 ? void 0 : _d.get(task.projectId)) !== null && _e !== void 0 ? _e : null,
189
+ assignee: resolveAssignee ? ((_g = (_f = context.assigneeName) === null || _f === void 0 ? void 0 : _f.call(context, task)) !== null && _g !== void 0 ? _g : null) : null,
190
+ };
191
+ });
192
+ }
193
+ function comparePriorityFirst(a, b) {
194
+ const common = compareNumber(b.task.priority, a.task.priority) ||
195
+ compareDate(a.due, b.due) ||
196
+ compareDate(a.deadline, b.deadline);
197
+ if (common !== 0)
198
+ return common;
199
+ const project = compareOptionalNumber(a.project, b.project);
200
+ if (project !== 0)
201
+ return project;
202
+ if (a.task.projectId === b.task.projectId) {
203
+ return compareNumber(a.task.childOrder, b.task.childOrder);
204
+ }
205
+ return 0;
206
+ }
207
+ function compareDateFirst(a, b) {
208
+ return (compareDate(a.schedule, b.schedule) ||
209
+ compareNumber(b.task.priority, a.task.priority) ||
210
+ compareDate(a.deadline, b.deadline) ||
211
+ compareNumber(a.task.dayOrder, b.task.dayOrder) ||
212
+ compareOptionalNumber(a.added, b.added));
213
+ }
214
+ function compareDefault(a, b, defaultOrder) {
215
+ return defaultOrder === 'DATE_FIRST' ? compareDateFirst(a, b) : comparePriorityFirst(a, b);
216
+ }
217
+ function comparePrimary({ sortedBy, a, b, collator, }) {
218
+ switch (sortedBy) {
219
+ case 'ALPHABETICALLY':
220
+ return collator.compare(a.task.content, b.task.content);
221
+ case 'ASSIGNEE':
222
+ return compareOptionalText(a.assignee, b.assignee, collator);
223
+ case 'DUE_DATE':
224
+ return compareDate(a.due, b.due);
225
+ case 'DEADLINE':
226
+ return compareDate(a.deadline, b.deadline);
227
+ case 'ADDED_DATE':
228
+ return compareOptionalNumber(a.added, b.added);
229
+ case 'PRIORITY':
230
+ return compareNumber(a.task.priority, b.task.priority);
231
+ case 'PROJECT':
232
+ return compareOptionalNumber(a.project, b.project);
233
+ case 'WORKSPACE':
234
+ return compareOptionalNumber(a.workspace, b.workspace);
235
+ case 'MANUAL':
236
+ return 0;
237
+ }
238
+ }
239
+ function defaultSortOrder(sortedBy) {
240
+ return sortedBy === 'PRIORITY' ? 'DESC' : 'ASC';
241
+ }
242
+ /**
243
+ * Sorts the supplied tasks using Todoist view-ordering rules.
244
+ *
245
+ * The function performs no I/O and always returns a new array. Exact project,
246
+ * workspace, assignee, localized text, and due-time ordering requires the
247
+ * corresponding context. Callers must sort each independent view section or
248
+ * group separately and preserve any subtask structure they render.
249
+ *
250
+ * This function sorts only the tasks supplied to it. Fetch every page first
251
+ * when globally correct ordering is required for a paginated query.
252
+ */
253
+ export function sortTasks(tasks, options, context = {}) {
254
+ var _a, _b, _c;
255
+ const locale = Array.isArray(context.locale)
256
+ ? [...context.locale]
257
+ : ((_a = context.locale) !== null && _a !== void 0 ? _a : DEFAULT_LOCALE);
258
+ const collator = new Intl.Collator(locale, { sensitivity: 'base', numeric: true });
259
+ const formatter = createDateTimeFormatter((_b = context.timezone) !== null && _b !== void 0 ? _b : DEFAULT_TIMEZONE);
260
+ const sortedBy = options.sortedBy;
261
+ const prepared = prepareTasks(tasks, context, {
262
+ formatter,
263
+ resolveAssignee: sortedBy === 'ASSIGNEE',
264
+ });
265
+ const direction = sortedBy && sortedBy !== 'MANUAL' ? ((_c = options.sortOrder) !== null && _c !== void 0 ? _c : defaultSortOrder(sortedBy)) : null;
266
+ const directionMultiplier = direction === 'DESC' ? -1 : 1;
267
+ return prepared
268
+ .sort((a, b) => {
269
+ if (sortedBy && sortedBy !== 'MANUAL') {
270
+ const primary = comparePrimary({ sortedBy, a, b, collator }) * directionMultiplier;
271
+ if (primary !== 0)
272
+ return primary;
273
+ }
274
+ return compareDefault(a, b, options.defaultOrder) || compareNumber(a.index, b.index);
275
+ })
276
+ .map(({ task }) => task);
277
+ }
@@ -0,0 +1,15 @@
1
+ /** Returns whether saved view options are active rather than a deletion tombstone. */
2
+ export function isActiveViewOption(options) {
3
+ return options.isDeleted !== true;
4
+ }
5
+ /** Finds the active saved options for one logical view. */
6
+ export function findViewOptions(options, args) {
7
+ var _a;
8
+ const targetObjectId = (_a = args.objectId) !== null && _a !== void 0 ? _a : null;
9
+ return options.find((entry) => {
10
+ var _a;
11
+ return isActiveViewOption(entry) &&
12
+ ((_a = entry.objectId) !== null && _a !== void 0 ? _a : null) === targetObjectId &&
13
+ args.viewTypes.includes(entry.viewType);
14
+ });
15
+ }
@@ -0,0 +1,8 @@
1
+ import type { ViewOptions, ViewOptionsDeleteArgs, ViewOptionsSetArgs } from '../types/sync/index.js';
2
+ import { BaseClient } from './base-client.js';
3
+ /** Internal sub-client for saved view-option reads and writes. */
4
+ export declare class ViewOptionsClient extends BaseClient {
5
+ getViewOptions(): Promise<ViewOptions[]>;
6
+ setViewOptions(args: ViewOptionsSetArgs, requestId?: string): Promise<void>;
7
+ deleteViewOptions(args: ViewOptionsDeleteArgs, requestId?: string): Promise<void>;
8
+ }
@@ -14,6 +14,7 @@ import { ProductivityStats } from './types/productivity/index.js';
14
14
  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';
15
15
  import { AddReminderArgs, UpdateReminderArgs, AddLocationReminderArgs, UpdateLocationReminderArgs, GetRemindersArgs, GetRemindersResponse, GetLocationRemindersArgs, GetLocationRemindersResponse } from './types/reminders/index.js';
16
16
  import { Section, AddSectionArgs, UpdateSectionArgs, GetSectionsArgs, SearchSectionsArgs, GetSectionsResponse } from './types/sections/index.js';
17
+ import type { SyncRequest, SyncResponse, ViewOptions, ViewOptionsDeleteArgs, ViewOptionsSetArgs } from './types/sync/index.js';
17
18
  import type { Folder } from './types/sync/resources/folders.js';
18
19
  import { Task, AddTaskArgs, GetTasksArgs, GetTasksByFilterArgs, UpdateTaskArgs, QuickAddTaskArgs, type MoveTaskArgs, GetCompletedTasksByCompletionDateArgs, GetCompletedTasksByDueDateArgs, GetCompletedTasksResponse, SearchCompletedTasksArgs, GetTasksResponse, GetAllCompletedTasksArgs, GetAllCompletedTasksResponse } from './types/tasks/index.js';
19
20
  import { ExportTemplateFileArgs, ExportTemplateUrlArgs, ExportTemplateUrlResponse, CreateProjectFromTemplateArgs, CreateProjectFromTemplateResponse, ImportTemplateIntoProjectArgs, ImportTemplateFromIdArgs, ImportTemplateResponse } from './types/templates/index.js';
@@ -21,7 +22,6 @@ import type { AddUiExtensionArgs, UiExtension, UpdateUiExtensionArgs, UploadUiEx
21
22
  import { UploadFileArgs, DeleteUploadArgs } from './types/uploads/index.js';
22
23
  import { CurrentUser } from './types/users/index.js';
23
24
  import { WorkspaceInvitation, WorkspacePlanDetails, JoinWorkspaceResult, Workspace, AddWorkspaceArgs, UpdateWorkspaceArgs, GetWorkspaceMembersActivityArgs, GetWorkspaceMembersActivityResponse, GetWorkspaceUserTasksArgs, GetWorkspaceUserTasksResponse, InviteWorkspaceUsersArgs, InviteWorkspaceUsersResponse, UpdateWorkspaceUserArgs, RemoveWorkspaceUserArgs, GetWorkspaceInvitationsArgs, DeleteWorkspaceInvitationArgs, WorkspaceInvitationActionArgs, JoinWorkspaceArgs, WorkspaceLogoArgs, GetWorkspacePlanDetailsArgs, GetWorkspaceUsersArgs, GetWorkspaceUsersResponse, GetWorkspaceProjectsArgs, WorkspaceInvitationsResponse, AllWorkspaceInvitationsResponse, WorkspaceLogoResponse } from './types/workspaces/index.js';
24
- import { type SyncResponse, type SyncRequest } from './types/sync/index.js';
25
25
  /**
26
26
  * A client for interacting with the Todoist API v1.
27
27
  * This class provides methods to manage tasks, projects, sections, labels, and comments in Todoist.
@@ -79,6 +79,7 @@ export declare class TodoistApi {
79
79
  private readonly billingClient;
80
80
  private readonly appClient;
81
81
  private readonly uiExtensionClient;
82
+ private readonly viewOptionsClient;
82
83
  constructor(
83
84
  /**
84
85
  * Your Todoist API token.
@@ -113,6 +114,28 @@ export declare class TodoistApi {
113
114
  * ```
114
115
  */
115
116
  sync(syncRequest: SyncRequest, requestId?: string): Promise<SyncResponse>;
117
+ /**
118
+ * Retrieves the authenticated user's active saved view options.
119
+ *
120
+ * @returns A promise that resolves to the active saved view options.
121
+ */
122
+ getViewOptions(): Promise<ViewOptions[]>;
123
+ /**
124
+ * Sets saved options for a view.
125
+ *
126
+ * @param args - The saved view options to set.
127
+ * @param requestId - Optional custom identifier for the request.
128
+ * @returns A promise that resolves when the view options are saved.
129
+ */
130
+ setViewOptions(args: ViewOptionsSetArgs, requestId?: string): Promise<void>;
131
+ /**
132
+ * Deletes the saved options for a view.
133
+ *
134
+ * @param args - The view whose saved options to delete.
135
+ * @param requestId - Optional custom identifier for the request.
136
+ * @returns A promise that resolves when the view options are deleted.
137
+ */
138
+ deleteViewOptions(args: ViewOptionsDeleteArgs, requestId?: string): Promise<void>;
116
139
  /**
117
140
  * Retrieves information about the authenticated user.
118
141
  *
@@ -1,7 +1,4 @@
1
- import type { ViewMode, GroupedBy, SortedBy, SortOrder, CalendarLayout } from '../resources/view-options.js';
2
- export type CalendarSettings = {
3
- layout?: CalendarLayout;
4
- };
1
+ import type { CalendarSettings, ViewMode, GroupedBy, SortedBy, SortOrder } from '../resources/view-options.js';
5
2
  export type ProjectViewOptionsDefaultsSetArgs = {
6
3
  projectId: string;
7
4
  viewMode?: ViewMode | null;
@@ -1,4 +1,4 @@
1
- import type { ViewType, ViewMode, GroupedBy, SortedBy, SortOrder } from '../resources/view-options.js';
1
+ import type { CalendarSettings, GroupedBy, SortedBy, SortOrder, ViewMode, ViewType } from '../resources/view-options.js';
2
2
  export type ViewOptionsSetArgs = {
3
3
  viewType: ViewType;
4
4
  objectId?: string;
@@ -8,6 +8,7 @@ export type ViewOptionsSetArgs = {
8
8
  showCompletedTasks?: boolean;
9
9
  sortedBy?: SortedBy | null;
10
10
  sortOrder?: SortOrder | null;
11
+ calendarSettings?: CalendarSettings | null;
11
12
  };
12
13
  export type ViewOptionsDeleteArgs = {
13
14
  viewType: ViewType;
@@ -10,19 +10,19 @@ import { z } from 'zod';
10
10
  export declare const LiveNotificationSchema: z.ZodObject<{
11
11
  id: z.ZodString;
12
12
  createdAt: z.ZodCoercedDate<unknown>;
13
- fromUid: z.ZodString;
13
+ fromUid: z.ZodOptional<z.ZodString>;
14
14
  notificationType: z.ZodString;
15
15
  isUnread: z.ZodBoolean;
16
16
  projectId: z.ZodOptional<z.ZodString>;
17
17
  invitationId: z.ZodOptional<z.ZodString>;
18
18
  itemId: z.ZodOptional<z.ZodString>;
19
19
  itemContent: z.ZodOptional<z.ZodString>;
20
- responsibleUid: z.ZodOptional<z.ZodString>;
21
- assignedByUid: z.ZodOptional<z.ZodString>;
20
+ responsibleUid: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
+ assignedByUid: z.ZodOptional<z.ZodNullable<z.ZodString>>;
22
22
  fromUser: z.ZodOptional<z.ZodObject<{
23
23
  email: z.ZodString;
24
24
  fullName: z.ZodString;
25
- id: z.ZodString;
25
+ id: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
26
26
  imageId: z.ZodNullable<z.ZodString>;
27
27
  }, z.core.$strip>>;
28
28
  projectName: z.ZodOptional<z.ZodString>;
@@ -68,12 +68,23 @@ export declare const SortOrderSchema: z.ZodNullable<z.ZodEnum<{
68
68
  export declare const CALENDAR_LAYOUTS: readonly ["WEEK", "MONTH"];
69
69
  /** Calendar layout mode. */
70
70
  export type CalendarLayout = (typeof CALENDAR_LAYOUTS)[number];
71
+ /** Available task color sources for calendar views. */
72
+ export declare const CALENDAR_COLORS: readonly ["PRIORITY", "LABEL", "PROJECT"];
73
+ /** Task color source for a calendar view. */
74
+ export type CalendarColor = (typeof CALENDAR_COLORS)[number];
71
75
  export declare const CalendarSettingsSchema: z.ZodObject<{
72
- layout: z.ZodOptional<z.ZodEnum<{
76
+ layout: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
73
77
  WEEK: "WEEK";
74
78
  MONTH: "MONTH";
75
- }>>;
79
+ }>>>;
80
+ visibleDayCount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<3>, z.ZodLiteral<7>]>>>;
81
+ color: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
82
+ PROJECT: "PROJECT";
83
+ LABEL: "LABEL";
84
+ PRIORITY: "PRIORITY";
85
+ }>>>;
76
86
  }, z.core.$loose>;
87
+ export type CalendarSettings = z.infer<typeof CalendarSettingsSchema>;
77
88
  export declare const ViewOptionsSchema: z.ZodObject<{
78
89
  viewType: z.ZodEnum<{
79
90
  PROJECT: "PROJECT";
@@ -90,7 +101,7 @@ export declare const ViewOptionsSchema: z.ZodObject<{
90
101
  OVERDUE: "OVERDUE";
91
102
  WORKSPACE_OVERVIEW: "WORKSPACE_OVERVIEW";
92
103
  }>;
93
- objectId: z.ZodOptional<z.ZodString>;
104
+ objectId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
94
105
  groupedBy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
95
106
  PROJECT: "PROJECT";
96
107
  LABEL: "LABEL";
@@ -102,11 +113,11 @@ export declare const ViewOptionsSchema: z.ZodObject<{
102
113
  WORKSPACE: "WORKSPACE";
103
114
  }>>>;
104
115
  filteredBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
105
- viewMode: z.ZodOptional<z.ZodEnum<{
116
+ viewMode: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
106
117
  LIST: "LIST";
107
118
  BOARD: "BOARD";
108
119
  CALENDAR: "CALENDAR";
109
- }>>;
120
+ }>>>;
110
121
  showCompletedTasks: z.ZodOptional<z.ZodBoolean>;
111
122
  sortedBy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
112
123
  PROJECT: "PROJECT";
@@ -123,6 +134,19 @@ export declare const ViewOptionsSchema: z.ZodObject<{
123
134
  ASC: "ASC";
124
135
  DESC: "DESC";
125
136
  }>>>;
137
+ calendarSettings: z.ZodOptional<z.ZodNullable<z.ZodObject<{
138
+ layout: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
139
+ WEEK: "WEEK";
140
+ MONTH: "MONTH";
141
+ }>>>;
142
+ visibleDayCount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<3>, z.ZodLiteral<7>]>>>;
143
+ color: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
144
+ PROJECT: "PROJECT";
145
+ LABEL: "LABEL";
146
+ PRIORITY: "PRIORITY";
147
+ }>>>;
148
+ }, z.core.$loose>>>;
149
+ isDeleted: z.ZodOptional<z.ZodBoolean>;
126
150
  }, z.core.$loose>;
127
151
  export type ViewOptions = z.infer<typeof ViewOptionsSchema>;
128
152
  export declare const ProjectViewOptionsDefaultsSchema: z.ZodObject<{
@@ -160,10 +184,16 @@ export declare const ProjectViewOptionsDefaultsSchema: z.ZodObject<{
160
184
  showCompletedTasks: z.ZodOptional<z.ZodBoolean>;
161
185
  filteredBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
162
186
  calendarSettings: z.ZodOptional<z.ZodNullable<z.ZodObject<{
163
- layout: z.ZodOptional<z.ZodEnum<{
187
+ layout: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
164
188
  WEEK: "WEEK";
165
189
  MONTH: "MONTH";
166
- }>>;
190
+ }>>>;
191
+ visibleDayCount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<3>, z.ZodLiteral<7>]>>>;
192
+ color: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
193
+ PROJECT: "PROJECT";
194
+ LABEL: "LABEL";
195
+ PRIORITY: "PRIORITY";
196
+ }>>>;
167
197
  }, z.core.$loose>>>;
168
198
  }, z.core.$loose>;
169
199
  export type ProjectViewOptionsDefaults = z.infer<typeof ProjectViewOptionsDefaultsSchema>;
@@ -465,19 +465,19 @@ export declare const SyncResponseSchema: z.ZodObject<{
465
465
  liveNotifications: z.ZodOptional<z.ZodArray<z.ZodObject<{
466
466
  id: z.ZodString;
467
467
  createdAt: z.ZodCoercedDate<unknown>;
468
- fromUid: z.ZodString;
468
+ fromUid: z.ZodOptional<z.ZodString>;
469
469
  notificationType: z.ZodString;
470
470
  isUnread: z.ZodBoolean;
471
471
  projectId: z.ZodOptional<z.ZodString>;
472
472
  invitationId: z.ZodOptional<z.ZodString>;
473
473
  itemId: z.ZodOptional<z.ZodString>;
474
474
  itemContent: z.ZodOptional<z.ZodString>;
475
- responsibleUid: z.ZodOptional<z.ZodString>;
476
- assignedByUid: z.ZodOptional<z.ZodString>;
475
+ responsibleUid: z.ZodOptional<z.ZodNullable<z.ZodString>>;
476
+ assignedByUid: z.ZodOptional<z.ZodNullable<z.ZodString>>;
477
477
  fromUser: z.ZodOptional<z.ZodObject<{
478
478
  email: z.ZodString;
479
479
  fullName: z.ZodString;
480
- id: z.ZodString;
480
+ id: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
481
481
  imageId: z.ZodNullable<z.ZodString>;
482
482
  }, z.core.$strip>>;
483
483
  projectName: z.ZodOptional<z.ZodString>;
@@ -751,7 +751,7 @@ export declare const SyncResponseSchema: z.ZodObject<{
751
751
  OVERDUE: "OVERDUE";
752
752
  WORKSPACE_OVERVIEW: "WORKSPACE_OVERVIEW";
753
753
  }>;
754
- objectId: z.ZodOptional<z.ZodString>;
754
+ objectId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
755
755
  groupedBy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
756
756
  PROJECT: "PROJECT";
757
757
  LABEL: "LABEL";
@@ -763,11 +763,11 @@ export declare const SyncResponseSchema: z.ZodObject<{
763
763
  WORKSPACE: "WORKSPACE";
764
764
  }>>>;
765
765
  filteredBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
766
- viewMode: z.ZodOptional<z.ZodEnum<{
766
+ viewMode: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
767
767
  LIST: "LIST";
768
768
  BOARD: "BOARD";
769
769
  CALENDAR: "CALENDAR";
770
- }>>;
770
+ }>>>;
771
771
  showCompletedTasks: z.ZodOptional<z.ZodBoolean>;
772
772
  sortedBy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
773
773
  PROJECT: "PROJECT";
@@ -784,6 +784,19 @@ export declare const SyncResponseSchema: z.ZodObject<{
784
784
  ASC: "ASC";
785
785
  DESC: "DESC";
786
786
  }>>>;
787
+ calendarSettings: z.ZodOptional<z.ZodNullable<z.ZodObject<{
788
+ layout: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
789
+ WEEK: "WEEK";
790
+ MONTH: "MONTH";
791
+ }>>>;
792
+ visibleDayCount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<3>, z.ZodLiteral<7>]>>>;
793
+ color: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
794
+ PROJECT: "PROJECT";
795
+ LABEL: "LABEL";
796
+ PRIORITY: "PRIORITY";
797
+ }>>>;
798
+ }, z.core.$loose>>>;
799
+ isDeleted: z.ZodOptional<z.ZodBoolean>;
787
800
  }, z.core.$loose>>>;
788
801
  projectViewOptionsDefaults: z.ZodOptional<z.ZodArray<z.ZodObject<{
789
802
  projectId: z.ZodString;
@@ -820,10 +833,16 @@ export declare const SyncResponseSchema: z.ZodObject<{
820
833
  showCompletedTasks: z.ZodOptional<z.ZodBoolean>;
821
834
  filteredBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
822
835
  calendarSettings: z.ZodOptional<z.ZodNullable<z.ZodObject<{
823
- layout: z.ZodOptional<z.ZodEnum<{
836
+ layout: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
824
837
  WEEK: "WEEK";
825
838
  MONTH: "MONTH";
826
- }>>;
839
+ }>>>;
840
+ visibleDayCount: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<3>, z.ZodLiteral<7>]>>>;
841
+ color: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
842
+ PROJECT: "PROJECT";
843
+ LABEL: "LABEL";
844
+ PRIORITY: "PRIORITY";
845
+ }>>>;
827
846
  }, z.core.$loose>>>;
828
847
  }, z.core.$loose>>>;
829
848
  roleActions: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
@@ -3,5 +3,7 @@ export * from './sanitization.js';
3
3
  export { getTaskUrl, getProjectUrl, getSectionUrl } from './url-helpers.js';
4
4
  export { createCommand } from './sync-helpers.js';
5
5
  export * from './project-helpers.js';
6
+ export * from './task-sorting.js';
7
+ export * from './view-options.js';
6
8
  export { parseWebhookPayload, verifyWebhookSignature } from './webhook-parser.js';
7
9
  export type { VerifyWebhookSignatureArgs } from './webhook-parser.js';
@@ -0,0 +1,38 @@
1
+ import type { SortOrder, SortedBy } from '../types/sync/index.js';
2
+ import type { Task } from '../types/tasks/index.js';
3
+ /** Todoist's default task-ordering hierarchies. */
4
+ export declare const DEFAULT_TASK_ORDERS: readonly ["PRIORITY_FIRST", "DATE_FIRST"];
5
+ /** Default hierarchy used when a view has no named sorting. */
6
+ export type DefaultTaskOrder = (typeof DEFAULT_TASK_ORDERS)[number];
7
+ export type TaskSortOptions = {
8
+ /** Saved or requested sort field. Null and MANUAL use defaultOrder. */
9
+ sortedBy?: SortedBy | null;
10
+ /** Saved or requested direction. Defaults by field when absent. */
11
+ sortOrder?: SortOrder | null;
12
+ /** Default hierarchy for this view or filter query. */
13
+ defaultOrder: DefaultTaskOrder;
14
+ };
15
+ export type TaskSortContext = {
16
+ /** Project ID to its visible order. */
17
+ projectOrder?: ReadonlyMap<string, number>;
18
+ /** Project ID to the visible order of its workspace bucket. */
19
+ workspaceOrder?: ReadonlyMap<string, number>;
20
+ /** Resolves the display name used for assignee sorting. */
21
+ assigneeName?: (task: Task) => string | null | undefined;
22
+ /** Account IANA timezone. Defaults to UTC for deterministic behavior. */
23
+ timezone?: string;
24
+ /** Locale used for text comparisons. Defaults to English. */
25
+ locale?: string | readonly string[];
26
+ };
27
+ /**
28
+ * Sorts the supplied tasks using Todoist view-ordering rules.
29
+ *
30
+ * The function performs no I/O and always returns a new array. Exact project,
31
+ * workspace, assignee, localized text, and due-time ordering requires the
32
+ * corresponding context. Callers must sort each independent view section or
33
+ * group separately and preserve any subtask structure they render.
34
+ *
35
+ * This function sorts only the tasks supplied to it. Fetch every page first
36
+ * when globally correct ordering is required for a paginated query.
37
+ */
38
+ export declare function sortTasks(tasks: readonly Task[], options: TaskSortOptions, context?: TaskSortContext): Task[];