@todoist/sdk 0.0.0-stage → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +308 -2
- package/dist/esm/authentication.js +307 -0
- package/dist/esm/clients/activity-client.js +60 -0
- package/dist/esm/clients/app-client.js +366 -0
- package/dist/esm/clients/backup-client.js +47 -0
- package/dist/esm/clients/base-client.js +29 -0
- package/dist/esm/clients/billing-client.js +160 -0
- package/dist/esm/clients/comment-client.js +92 -0
- package/dist/esm/clients/email-client.js +41 -0
- package/dist/esm/clients/filter-client.js +26 -0
- package/dist/esm/clients/folder-client.js +80 -0
- package/dist/esm/clients/id-mapping-client.js +37 -0
- package/dist/esm/clients/insights-client.js +89 -0
- package/dist/esm/clients/label-client.js +131 -0
- package/dist/esm/clients/productivity-client.js +24 -0
- package/dist/esm/clients/project-client.js +284 -0
- package/dist/esm/clients/reminder-client.js +204 -0
- package/dist/esm/clients/section-client.js +121 -0
- package/dist/esm/clients/task-client.js +264 -0
- package/dist/esm/clients/template-client.js +89 -0
- package/dist/esm/clients/ui-extension-client.js +110 -0
- package/dist/esm/clients/upload-client.js +153 -0
- package/dist/esm/clients/view-options-client.js +21 -0
- package/dist/esm/clients/workspace-client.js +384 -0
- package/dist/esm/consts/endpoints.js +193 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/test-utils/asserts.js +8 -0
- package/dist/esm/test-utils/msw-setup.js +88 -0
- package/dist/esm/test-utils/obsidian-fetch-adapter.js +51 -0
- package/dist/esm/test-utils/test-defaults.js +367 -0
- package/dist/esm/test-utils/transport-seam.js +15 -0
- package/dist/esm/test-utils/webhook-fixtures.js +26 -0
- package/dist/esm/todoist-api.js +1757 -0
- package/dist/esm/transport/fetch-with-retry.js +216 -0
- package/dist/esm/transport/http-client.js +140 -0
- package/dist/esm/transport/http-dispatcher.js +158 -0
- package/dist/esm/transport/sync-request.js +106 -0
- package/dist/esm/types/activity/index.js +2 -0
- package/dist/esm/types/activity/requests.js +1 -0
- package/dist/esm/types/activity/types.js +45 -0
- package/dist/esm/types/apps/index.js +2 -0
- package/dist/esm/types/apps/requests.js +1 -0
- package/dist/esm/types/apps/types.js +249 -0
- package/dist/esm/types/backups/index.js +2 -0
- package/dist/esm/types/backups/requests.js +1 -0
- package/dist/esm/types/backups/types.js +5 -0
- package/dist/esm/types/billing/index.js +2 -0
- package/dist/esm/types/billing/requests.js +1 -0
- package/dist/esm/types/billing/types.js +89 -0
- package/dist/esm/types/comments/index.js +2 -0
- package/dist/esm/types/comments/requests.js +1 -0
- package/dist/esm/types/comments/types.js +57 -0
- package/dist/esm/types/common.js +7 -0
- package/dist/esm/types/emails/index.js +1 -0
- package/dist/esm/types/emails/requests.js +2 -0
- package/dist/esm/types/errors.js +41 -0
- package/dist/esm/types/folders/index.js +1 -0
- package/dist/esm/types/folders/requests.js +1 -0
- package/dist/esm/types/http.js +20 -0
- package/dist/esm/types/id-mappings/index.js +2 -0
- package/dist/esm/types/id-mappings/requests.js +17 -0
- package/dist/esm/types/id-mappings/types.js +9 -0
- package/dist/esm/types/index.js +24 -0
- package/dist/esm/types/insights/index.js +2 -0
- package/dist/esm/types/insights/requests.js +1 -0
- package/dist/esm/types/insights/types.js +77 -0
- package/dist/esm/types/labels/index.js +2 -0
- package/dist/esm/types/labels/requests.js +1 -0
- package/dist/esm/types/labels/types.js +8 -0
- package/dist/esm/types/productivity/index.js +1 -0
- package/dist/esm/types/productivity/types.js +65 -0
- package/dist/esm/types/projects/index.js +2 -0
- package/dist/esm/types/projects/requests.js +1 -0
- package/dist/esm/types/projects/types.js +65 -0
- package/dist/esm/types/reminders/index.js +1 -0
- package/dist/esm/types/reminders/requests.js +92 -0
- package/dist/esm/types/sections/index.js +2 -0
- package/dist/esm/types/sections/requests.js +1 -0
- package/dist/esm/types/sections/types.js +23 -0
- package/dist/esm/types/sync/commands/calendars.js +1 -0
- package/dist/esm/types/sync/commands/filters.js +1 -0
- package/dist/esm/types/sync/commands/folders.js +1 -0
- package/dist/esm/types/sync/commands/index.js +18 -0
- package/dist/esm/types/sync/commands/labels.js +2 -0
- package/dist/esm/types/sync/commands/notes.js +1 -0
- package/dist/esm/types/sync/commands/notifications.js +1 -0
- package/dist/esm/types/sync/commands/others.js +1 -0
- package/dist/esm/types/sync/commands/project-view-options.js +1 -0
- package/dist/esm/types/sync/commands/projects.js +1 -0
- package/dist/esm/types/sync/commands/reminders.js +1 -0
- package/dist/esm/types/sync/commands/sections.js +1 -0
- package/dist/esm/types/sync/commands/shared.js +16 -0
- package/dist/esm/types/sync/commands/sharing.js +1 -0
- package/dist/esm/types/sync/commands/tasks.js +1 -0
- package/dist/esm/types/sync/commands/view-options.js +1 -0
- package/dist/esm/types/sync/commands/workspace-filters.js +1 -0
- package/dist/esm/types/sync/commands/workspaces.js +1 -0
- package/dist/esm/types/sync/index.js +6 -0
- package/dist/esm/types/sync/request.js +1 -0
- package/dist/esm/types/sync/resource-types.js +36 -0
- package/dist/esm/types/sync/resources/calendars.js +24 -0
- package/dist/esm/types/sync/resources/collaborators.js +21 -0
- package/dist/esm/types/sync/resources/completed-info.js +21 -0
- package/dist/esm/types/sync/resources/filters.js +12 -0
- package/dist/esm/types/sync/resources/folders.js +10 -0
- package/dist/esm/types/sync/resources/index.js +18 -0
- package/dist/esm/types/sync/resources/labels.js +7 -0
- package/dist/esm/types/sync/resources/live-notifications.js +35 -0
- package/dist/esm/types/sync/resources/notes.js +18 -0
- package/dist/esm/types/sync/resources/reminders.js +58 -0
- package/dist/esm/types/sync/resources/suggestions.js +33 -0
- package/dist/esm/types/sync/resources/tooltips.js +5 -0
- package/dist/esm/types/sync/resources/user-plan-limits.js +21 -0
- package/dist/esm/types/sync/resources/user-settings.js +41 -0
- package/dist/esm/types/sync/resources/user-status.js +22 -0
- package/dist/esm/types/sync/resources/user.js +109 -0
- package/dist/esm/types/sync/resources/view-options.js +128 -0
- package/dist/esm/types/sync/resources/workspace-filters.js +17 -0
- package/dist/esm/types/sync/resources/workspaces.js +69 -0
- package/dist/esm/types/sync/response.js +57 -0
- package/dist/esm/types/sync/user-preferences.js +68 -0
- package/dist/esm/types/tasks/index.js +2 -0
- package/dist/esm/types/tasks/requests.js +1 -0
- package/dist/esm/types/tasks/types.js +56 -0
- package/dist/esm/types/templates/index.js +1 -0
- package/dist/esm/types/templates/requests.js +1 -0
- package/dist/esm/types/ui-extensions/index.js +2 -0
- package/dist/esm/types/ui-extensions/requests.js +1 -0
- package/dist/esm/types/ui-extensions/types.js +74 -0
- package/dist/esm/types/uploads/index.js +1 -0
- package/dist/esm/types/uploads/requests.js +1 -0
- package/dist/esm/types/users/index.js +1 -0
- package/dist/esm/types/users/types.js +49 -0
- package/dist/esm/types/webhooks/comments.js +93 -0
- package/dist/esm/types/webhooks/envelope.js +23 -0
- package/dist/esm/types/webhooks/filters.js +27 -0
- package/dist/esm/types/webhooks/index.js +9 -0
- package/dist/esm/types/webhooks/labels.js +51 -0
- package/dist/esm/types/webhooks/projects.js +33 -0
- package/dist/esm/types/webhooks/reminders.js +32 -0
- package/dist/esm/types/webhooks/sections.js +50 -0
- package/dist/esm/types/webhooks/tasks.js +65 -0
- package/dist/esm/types/webhooks/types.js +52 -0
- package/dist/esm/types/workspaces/index.js +2 -0
- package/dist/esm/types/workspaces/requests.js +1 -0
- package/dist/esm/types/workspaces/types.js +151 -0
- package/dist/esm/utils/activity-helpers.js +53 -0
- package/dist/esm/utils/case-conversion.js +84 -0
- package/dist/esm/utils/colors.js +145 -0
- package/dist/esm/utils/file-response.js +29 -0
- package/dist/esm/utils/filter-queries.js +231 -0
- package/dist/esm/utils/filter-query-definitions.js +2789 -0
- package/dist/esm/utils/headers.js +42 -0
- package/dist/esm/utils/index.js +11 -0
- package/dist/esm/utils/multipart-upload.js +267 -0
- package/dist/esm/utils/person-names.js +61 -0
- package/dist/esm/utils/processing-helpers.js +12 -0
- package/dist/esm/utils/project-helpers.js +29 -0
- package/dist/esm/utils/request-helpers.js +43 -0
- package/dist/esm/utils/sanitization.js +131 -0
- package/dist/esm/utils/sync-helpers.js +19 -0
- package/dist/esm/utils/task-sorting.js +280 -0
- package/dist/esm/utils/uncompletable-helpers.js +54 -0
- package/dist/esm/utils/url-helpers.js +196 -0
- package/dist/esm/utils/validators.js +102 -0
- package/dist/esm/utils/view-options.js +15 -0
- package/dist/esm/utils/webhook-parser.js +56 -0
- package/dist/types/authentication.d.ts +262 -0
- package/dist/types/clients/activity-client.d.ts +12 -0
- package/dist/types/clients/app-client.d.ts +37 -0
- package/dist/types/clients/backup-client.d.ts +14 -0
- package/dist/types/clients/base-client.d.ts +23 -0
- package/dist/types/clients/billing-client.d.ts +22 -0
- package/dist/types/clients/comment-client.d.ts +15 -0
- package/dist/types/clients/email-client.d.ts +13 -0
- package/dist/types/clients/filter-client.d.ts +10 -0
- package/dist/types/clients/folder-client.d.ts +16 -0
- package/dist/types/clients/id-mapping-client.d.ts +13 -0
- package/dist/types/clients/insights-client.d.ts +18 -0
- package/dist/types/clients/label-client.d.ts +19 -0
- package/dist/types/clients/productivity-client.d.ts +12 -0
- package/dist/types/clients/project-client.d.ts +22 -0
- package/dist/types/clients/reminder-client.d.ts +25 -0
- package/dist/types/clients/section-client.d.ts +18 -0
- package/dist/types/clients/task-client.d.ts +25 -0
- package/dist/types/clients/template-client.d.ts +17 -0
- package/dist/types/clients/ui-extension-client.d.ts +18 -0
- package/dist/types/clients/upload-client.d.ts +17 -0
- package/dist/types/clients/view-options-client.d.ts +8 -0
- package/dist/types/clients/workspace-client.d.ts +43 -0
- package/dist/types/consts/endpoints.d.ts +120 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/test-utils/asserts.d.ts +1 -0
- package/dist/types/test-utils/msw-setup.d.ts +33 -0
- package/dist/types/test-utils/obsidian-fetch-adapter.d.ts +29 -0
- package/dist/types/test-utils/test-defaults.d.ts +286 -0
- package/dist/types/test-utils/transport-seam.d.ts +1 -0
- package/dist/types/test-utils/webhook-fixtures.d.ts +13 -0
- package/dist/types/todoist-api.d.ts +1437 -0
- package/dist/types/transport/fetch-with-retry.d.ts +12 -0
- package/dist/types/transport/http-client.d.ts +25 -0
- package/dist/types/transport/http-dispatcher.d.ts +65 -0
- package/dist/types/transport/sync-request.d.ts +31 -0
- package/dist/types/types/activity/index.d.ts +2 -0
- package/dist/types/types/activity/requests.d.ts +85 -0
- package/dist/types/types/activity/types.d.ts +56 -0
- package/dist/types/types/apps/index.d.ts +2 -0
- package/dist/types/types/apps/requests.d.ts +89 -0
- package/dist/types/types/apps/types.d.ts +418 -0
- package/dist/types/types/backups/index.d.ts +2 -0
- package/dist/types/types/backups/requests.d.ts +16 -0
- package/dist/types/types/backups/types.d.ts +7 -0
- package/dist/types/types/billing/index.d.ts +2 -0
- package/dist/types/types/billing/requests.d.ts +62 -0
- package/dist/types/types/billing/types.d.ts +207 -0
- package/dist/types/types/comments/index.d.ts +2 -0
- package/dist/types/types/comments/requests.d.ts +64 -0
- package/dist/types/types/comments/types.d.ts +141 -0
- package/dist/types/types/common.d.ts +13 -0
- package/dist/types/types/emails/index.d.ts +1 -0
- package/dist/types/types/emails/requests.d.ts +30 -0
- package/dist/types/types/errors.d.ts +29 -0
- package/dist/types/types/folders/index.d.ts +1 -0
- package/dist/types/types/folders/requests.d.ts +20 -0
- package/dist/types/types/http.d.ts +104 -0
- package/dist/types/types/id-mappings/index.d.ts +2 -0
- package/dist/types/types/id-mappings/requests.d.ts +28 -0
- package/dist/types/types/id-mappings/types.d.ts +13 -0
- package/dist/types/types/index.d.ts +24 -0
- package/dist/types/types/insights/index.d.ts +2 -0
- package/dist/types/types/insights/requests.d.ts +26 -0
- package/dist/types/types/insights/types.d.ts +167 -0
- package/dist/types/types/labels/index.d.ts +2 -0
- package/dist/types/types/labels/requests.d.ts +75 -0
- package/dist/types/types/labels/types.d.ts +13 -0
- package/dist/types/types/productivity/index.d.ts +1 -0
- package/dist/types/types/productivity/types.d.ts +115 -0
- package/dist/types/types/projects/index.d.ts +2 -0
- package/dist/types/types/projects/requests.d.ts +206 -0
- package/dist/types/types/projects/types.d.ts +286 -0
- package/dist/types/types/reminders/index.d.ts +1 -0
- package/dist/types/types/reminders/requests.d.ts +205 -0
- package/dist/types/types/sections/index.d.ts +2 -0
- package/dist/types/types/sections/requests.d.ts +49 -0
- package/dist/types/types/sections/types.d.ts +70 -0
- package/dist/types/types/sync/commands/calendars.d.ts +14 -0
- package/dist/types/types/sync/commands/filters.d.ts +24 -0
- package/dist/types/types/sync/commands/folders.d.ts +20 -0
- package/dist/types/types/sync/commands/index.d.ts +167 -0
- package/dist/types/types/sync/commands/labels.d.ts +32 -0
- package/dist/types/types/sync/commands/notes.d.ts +27 -0
- package/dist/types/types/sync/commands/notifications.d.ts +10 -0
- package/dist/types/types/sync/commands/others.d.ts +61 -0
- package/dist/types/types/sync/commands/project-view-options.d.ts +13 -0
- package/dist/types/types/sync/commands/projects.d.ts +96 -0
- package/dist/types/types/sync/commands/reminders.d.ts +51 -0
- package/dist/types/types/sync/commands/sections.d.ts +36 -0
- package/dist/types/types/sync/commands/shared.d.ts +51 -0
- package/dist/types/types/sync/commands/sharing.d.ts +16 -0
- package/dist/types/types/sync/commands/tasks.d.ts +78 -0
- package/dist/types/types/sync/commands/view-options.d.ts +18 -0
- package/dist/types/types/sync/commands/workspace-filters.d.ts +25 -0
- package/dist/types/types/sync/commands/workspaces.d.ts +82 -0
- package/dist/types/types/sync/index.d.ts +6 -0
- package/dist/types/types/sync/request.d.ts +7 -0
- package/dist/types/types/sync/resource-types.d.ts +5 -0
- package/dist/types/types/sync/resources/calendars.d.ts +38 -0
- package/dist/types/types/sync/resources/collaborators.d.ts +45 -0
- package/dist/types/types/sync/resources/completed-info.d.ts +33 -0
- package/dist/types/types/sync/resources/filters.d.ts +13 -0
- package/dist/types/types/sync/resources/folders.d.ts +11 -0
- package/dist/types/types/sync/resources/index.d.ts +18 -0
- package/dist/types/types/sync/resources/labels.d.ts +12 -0
- package/dist/types/types/sync/resources/live-notifications.d.ts +32 -0
- package/dist/types/types/sync/resources/notes.d.ts +34 -0
- package/dist/types/types/sync/resources/reminders.d.ts +213 -0
- package/dist/types/types/sync/resources/suggestions.d.ts +96 -0
- package/dist/types/types/sync/resources/tooltips.d.ts +6 -0
- package/dist/types/types/sync/resources/user-plan-limits.d.ts +47 -0
- package/dist/types/types/sync/resources/user-settings.d.ts +40 -0
- package/dist/types/types/sync/resources/user-status.d.ts +46 -0
- package/dist/types/types/sync/resources/user.d.ts +151 -0
- package/dist/types/types/sync/resources/view-options.d.ts +157 -0
- package/dist/types/types/sync/resources/workspace-filters.d.ts +18 -0
- package/dist/types/types/sync/resources/workspaces.d.ts +142 -0
- package/dist/types/types/sync/response.d.ts +930 -0
- package/dist/types/types/sync/user-preferences.d.ts +39 -0
- package/dist/types/types/tasks/index.d.ts +2 -0
- package/dist/types/types/tasks/requests.d.ts +197 -0
- package/dist/types/types/tasks/types.d.ts +162 -0
- package/dist/types/types/templates/index.d.ts +1 -0
- package/dist/types/types/templates/requests.d.ts +92 -0
- package/dist/types/types/ui-extensions/index.d.ts +2 -0
- package/dist/types/types/ui-extensions/requests.d.ts +108 -0
- package/dist/types/types/ui-extensions/types.d.ts +185 -0
- package/dist/types/types/uploads/index.d.ts +1 -0
- package/dist/types/types/uploads/requests.d.ts +32 -0
- package/dist/types/types/users/index.d.ts +1 -0
- package/dist/types/types/users/types.d.ts +67 -0
- package/dist/types/types/webhooks/comments.d.ts +1600 -0
- package/dist/types/types/webhooks/envelope.d.ts +34 -0
- package/dist/types/types/webhooks/filters.d.ts +99 -0
- package/dist/types/types/webhooks/index.d.ts +9 -0
- package/dist/types/types/webhooks/labels.d.ts +160 -0
- package/dist/types/types/webhooks/projects.d.ts +365 -0
- package/dist/types/types/webhooks/reminders.d.ts +82 -0
- package/dist/types/types/webhooks/sections.d.ts +372 -0
- package/dist/types/types/webhooks/tasks.d.ts +981 -0
- package/dist/types/types/webhooks/types.d.ts +2606 -0
- package/dist/types/types/workspaces/index.d.ts +2 -0
- package/dist/types/types/workspaces/requests.d.ts +260 -0
- package/dist/types/types/workspaces/types.d.ts +266 -0
- package/dist/types/utils/activity-helpers.d.ts +28 -0
- package/dist/types/utils/case-conversion.d.ts +20 -0
- package/dist/types/utils/colors.d.ts +201 -0
- package/dist/types/utils/file-response.d.ts +15 -0
- package/dist/types/utils/filter-queries.d.ts +42 -0
- package/dist/types/utils/filter-query-definitions.d.ts +27 -0
- package/dist/types/utils/headers.d.ts +20 -0
- package/dist/types/utils/index.d.ts +15 -0
- package/dist/types/utils/multipart-upload.d.ts +58 -0
- package/dist/types/utils/person-names.d.ts +52 -0
- package/dist/types/utils/processing-helpers.d.ts +1 -0
- package/dist/types/utils/project-helpers.d.ts +21 -0
- package/dist/types/utils/request-helpers.d.ts +33 -0
- package/dist/types/utils/sanitization.d.ts +52 -0
- package/dist/types/utils/sync-helpers.d.ts +17 -0
- package/dist/types/utils/task-sorting.d.ts +46 -0
- package/dist/types/utils/uncompletable-helpers.d.ts +30 -0
- package/dist/types/utils/url-helpers.d.ts +120 -0
- package/dist/types/utils/validators.d.ts +1917 -0
- package/dist/types/utils/view-options.d.ts +11 -0
- package/dist/types/utils/webhook-parser.d.ts +48 -0
- package/package.json +88 -5
|
@@ -0,0 +1,280 @@
|
|
|
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
|
+
default:
|
|
236
|
+
// MANUAL, LABEL, and fields added after this SDK version keep the default order.
|
|
237
|
+
return 0;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function defaultSortOrder(sortedBy) {
|
|
241
|
+
return sortedBy === 'PRIORITY' ? 'DESC' : 'ASC';
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Sorts the supplied tasks using Todoist view-ordering rules.
|
|
245
|
+
*
|
|
246
|
+
* The function performs no I/O and always returns a new array. Exact project,
|
|
247
|
+
* workspace, assignee, localized text, and due-time ordering requires the
|
|
248
|
+
* corresponding context. Callers must sort each independent view section or
|
|
249
|
+
* group separately and preserve any subtask structure they render.
|
|
250
|
+
*
|
|
251
|
+
* This function sorts only the tasks supplied to it. Fetch every page first
|
|
252
|
+
* when globally correct ordering is required for a paginated query.
|
|
253
|
+
*
|
|
254
|
+
* @see isDateDrivenQuery
|
|
255
|
+
*/
|
|
256
|
+
export function sortTasks(tasks, options, context = {}) {
|
|
257
|
+
var _a, _b, _c;
|
|
258
|
+
const locale = Array.isArray(context.locale)
|
|
259
|
+
? [...context.locale]
|
|
260
|
+
: ((_a = context.locale) !== null && _a !== void 0 ? _a : DEFAULT_LOCALE);
|
|
261
|
+
const collator = new Intl.Collator(locale, { sensitivity: 'base', numeric: true });
|
|
262
|
+
const formatter = createDateTimeFormatter((_b = context.timezone) !== null && _b !== void 0 ? _b : DEFAULT_TIMEZONE);
|
|
263
|
+
const sortedBy = options.sortedBy;
|
|
264
|
+
const prepared = prepareTasks(tasks, context, {
|
|
265
|
+
formatter,
|
|
266
|
+
resolveAssignee: sortedBy === 'ASSIGNEE',
|
|
267
|
+
});
|
|
268
|
+
const direction = sortedBy && sortedBy !== 'MANUAL' ? ((_c = options.sortOrder) !== null && _c !== void 0 ? _c : defaultSortOrder(sortedBy)) : null;
|
|
269
|
+
const directionMultiplier = direction === 'DESC' ? -1 : 1;
|
|
270
|
+
return prepared
|
|
271
|
+
.sort((a, b) => {
|
|
272
|
+
if (sortedBy && sortedBy !== 'MANUAL') {
|
|
273
|
+
const primary = comparePrimary({ sortedBy, a, b, collator }) * directionMultiplier;
|
|
274
|
+
if (primary !== 0)
|
|
275
|
+
return primary;
|
|
276
|
+
}
|
|
277
|
+
return compareDefault(a, b, options.defaultOrder) || compareNumber(a.index, b.index);
|
|
278
|
+
})
|
|
279
|
+
.map(({ task }) => task);
|
|
280
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const UNCOMPLETABLE_PREFIX = '* ';
|
|
2
|
+
/**
|
|
3
|
+
* Adds the uncompletable prefix (* ) to task content if not already present
|
|
4
|
+
* @param content - The task content
|
|
5
|
+
* @returns Content with uncompletable prefix added
|
|
6
|
+
*/
|
|
7
|
+
export function addUncompletablePrefix(content) {
|
|
8
|
+
if (content.startsWith(UNCOMPLETABLE_PREFIX)) {
|
|
9
|
+
return content;
|
|
10
|
+
}
|
|
11
|
+
return UNCOMPLETABLE_PREFIX + content;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Removes the uncompletable prefix (* ) from task content if present
|
|
15
|
+
* @param content - The task content
|
|
16
|
+
* @returns Content with uncompletable prefix removed
|
|
17
|
+
*/
|
|
18
|
+
export function removeUncompletablePrefix(content) {
|
|
19
|
+
if (content.startsWith(UNCOMPLETABLE_PREFIX)) {
|
|
20
|
+
return content.slice(UNCOMPLETABLE_PREFIX.length);
|
|
21
|
+
}
|
|
22
|
+
return content;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Checks if task content has the uncompletable prefix (* )
|
|
26
|
+
* @param content - The task content
|
|
27
|
+
* @returns True if content starts with uncompletable prefix
|
|
28
|
+
*/
|
|
29
|
+
export function hasUncompletablePrefix(content) {
|
|
30
|
+
return content.startsWith(UNCOMPLETABLE_PREFIX);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Processes task content based on isUncompletable flag, with content prefix taking precedence
|
|
34
|
+
* @param content - The original task content
|
|
35
|
+
* @param isUncompletable - Optional flag to make task uncompletable
|
|
36
|
+
* @returns Processed content
|
|
37
|
+
*
|
|
38
|
+
* Logic:
|
|
39
|
+
* - If content already has * prefix, task is uncompletable regardless of flag
|
|
40
|
+
* - If content doesn't have * prefix and isUncompletable is true, add the prefix
|
|
41
|
+
* - If isUncompletable is undefined or false (and no prefix), leave content unchanged
|
|
42
|
+
*/
|
|
43
|
+
export function processTaskContent(content, isUncompletable) {
|
|
44
|
+
// Content prefix takes precedence - if already has prefix, keep it
|
|
45
|
+
if (hasUncompletablePrefix(content)) {
|
|
46
|
+
return content;
|
|
47
|
+
}
|
|
48
|
+
// If content doesn't have prefix and user wants uncompletable, add it
|
|
49
|
+
if (isUncompletable === true) {
|
|
50
|
+
return addUncompletablePrefix(content);
|
|
51
|
+
}
|
|
52
|
+
// Otherwise, leave content unchanged
|
|
53
|
+
return content;
|
|
54
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { LinkEnvironment } from '@doist/sdk-kmp/common';
|
|
2
|
+
import { parseTodoistLink, todoistFilterUrl, todoistLabelUrl, todoistProjectCommentsUrl, todoistProjectCommentUrl, todoistProjectUrl, todoistSectionUrl, todoistTaskCommentsUrl, todoistTaskCommentUrl, todoistTaskUrl, todoistWorkspaceFilterUrl, todoistWorkspaceUrl, } from '@doist/sdk-kmp/todoist';
|
|
3
|
+
import { TODOIST_WEB_URI } from '../consts/endpoints.js';
|
|
4
|
+
/**
|
|
5
|
+
* Formats a Date object to YYYY-MM-DD string format.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
* @param date The Date object to format.
|
|
9
|
+
* @returns The formatted date string in YYYY-MM-DD format.
|
|
10
|
+
*/
|
|
11
|
+
export function formatDateToYYYYMMDD(date) {
|
|
12
|
+
const year = date.getFullYear();
|
|
13
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
14
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
15
|
+
return `${year}-${month}-${day}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds a URL, falling back to a bare-id URL when the link builder rejects the
|
|
19
|
+
* given id. These helpers are called while parsing API responses, so generating
|
|
20
|
+
* a URL must never fail the parse.
|
|
21
|
+
*
|
|
22
|
+
* @param build Builds the URL.
|
|
23
|
+
* @param fallbackPath The path to fall back to, relative to the Todoist web app.
|
|
24
|
+
* @returns The built URL, or a bare-id URL if the id was rejected.
|
|
25
|
+
*/
|
|
26
|
+
function buildUrl(build, fallbackPath) {
|
|
27
|
+
try {
|
|
28
|
+
return build();
|
|
29
|
+
}
|
|
30
|
+
catch (_a) {
|
|
31
|
+
return `${TODOIST_WEB_URI}/${fallbackPath}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate the URL for a given task.
|
|
36
|
+
*
|
|
37
|
+
* @param taskId The ID of the task.
|
|
38
|
+
* @param content The content of the task.
|
|
39
|
+
* @returns The URL string for the task view.
|
|
40
|
+
*/
|
|
41
|
+
export function getTaskUrl(taskId, content) {
|
|
42
|
+
return buildUrl(() => todoistTaskUrl(taskId, content !== null && content !== void 0 ? content : '', LinkEnvironment.Production), `task/${taskId}`);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Generate the URL for a given project.
|
|
46
|
+
*
|
|
47
|
+
* @param projectId The ID of the project.
|
|
48
|
+
* @param name The name of the project.
|
|
49
|
+
* @returns The URL string for the project view.
|
|
50
|
+
*/
|
|
51
|
+
export function getProjectUrl(projectId, name) {
|
|
52
|
+
return buildUrl(() => todoistProjectUrl(projectId, name !== null && name !== void 0 ? name : '', LinkEnvironment.Production), `project/${projectId}`);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate the URL for a given section.
|
|
56
|
+
*
|
|
57
|
+
* @param sectionId The ID of the section.
|
|
58
|
+
* @param name The name of the section.
|
|
59
|
+
* @returns The URL string for the section view.
|
|
60
|
+
*/
|
|
61
|
+
export function getSectionUrl(sectionId, name) {
|
|
62
|
+
return buildUrl(() => todoistSectionUrl(sectionId, name !== null && name !== void 0 ? name : '', LinkEnvironment.Production), `section/${sectionId}`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate the URL for a given label.
|
|
66
|
+
*
|
|
67
|
+
* @param labelId The ID of the label.
|
|
68
|
+
* @param name The name of the label.
|
|
69
|
+
* @returns The URL string for the label view.
|
|
70
|
+
*/
|
|
71
|
+
export function getLabelUrl(labelId, name) {
|
|
72
|
+
return buildUrl(() => todoistLabelUrl(labelId, name !== null && name !== void 0 ? name : '', LinkEnvironment.Production), `label/${labelId}`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Generate the URL for a given filter.
|
|
76
|
+
*
|
|
77
|
+
* @param filterId The ID of the filter.
|
|
78
|
+
* @param name The name of the filter.
|
|
79
|
+
* @returns The URL string for the filter view.
|
|
80
|
+
*/
|
|
81
|
+
export function getFilterUrl(filterId, name) {
|
|
82
|
+
return buildUrl(() => todoistFilterUrl(filterId, name !== null && name !== void 0 ? name : '', LinkEnvironment.Production), `filter/${filterId}`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate the URL for a filter belonging to a workspace.
|
|
86
|
+
*
|
|
87
|
+
* @param workspaceId The ID of the workspace the filter belongs to.
|
|
88
|
+
* @param filterId The ID of the filter.
|
|
89
|
+
* @param name The name of the filter.
|
|
90
|
+
* @returns The URL string for the workspace filter view.
|
|
91
|
+
*/
|
|
92
|
+
export function getWorkspaceFilterUrl(workspaceId, filterId, name) {
|
|
93
|
+
return buildUrl(() => todoistWorkspaceFilterUrl(workspaceId, filterId, name !== null && name !== void 0 ? name : '', LinkEnvironment.Production), `${workspaceId}/filter/${filterId}`);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Generate the URL for a given workspace.
|
|
97
|
+
*
|
|
98
|
+
* @param workspaceId The ID of the workspace.
|
|
99
|
+
* @returns The URL string for the workspace view.
|
|
100
|
+
*/
|
|
101
|
+
export function getWorkspaceUrl(workspaceId) {
|
|
102
|
+
return buildUrl(() => todoistWorkspaceUrl(workspaceId, LinkEnvironment.Production), workspaceId);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate the URL for the comments on a given task.
|
|
106
|
+
*
|
|
107
|
+
* @param taskId The ID of the task.
|
|
108
|
+
* @param content The content of the task.
|
|
109
|
+
* @returns The URL string for the task's comments.
|
|
110
|
+
*/
|
|
111
|
+
export function getTaskCommentsUrl(taskId, content) {
|
|
112
|
+
return buildUrl(() => todoistTaskCommentsUrl(taskId, content !== null && content !== void 0 ? content : '', LinkEnvironment.Production), `task/${taskId}/comments`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate the URL for the comments on a given project.
|
|
116
|
+
*
|
|
117
|
+
* @param projectId The ID of the project.
|
|
118
|
+
* @param name The name of the project.
|
|
119
|
+
* @returns The URL string for the project's comments.
|
|
120
|
+
*/
|
|
121
|
+
export function getProjectCommentsUrl(projectId, name) {
|
|
122
|
+
return buildUrl(() => todoistProjectCommentsUrl(projectId, name !== null && name !== void 0 ? name : '', LinkEnvironment.Production), `project/${projectId}/comments`);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Generate the URL for a single comment on a given task.
|
|
126
|
+
*
|
|
127
|
+
* @param taskId The ID of the task.
|
|
128
|
+
* @param commentId The ID of the comment.
|
|
129
|
+
* @param content The content of the task.
|
|
130
|
+
* @returns The URL string for the comment.
|
|
131
|
+
*/
|
|
132
|
+
export function getTaskCommentUrl(taskId, commentId, content) {
|
|
133
|
+
return buildUrl(() => todoistTaskCommentUrl(taskId, content !== null && content !== void 0 ? content : '', commentId, LinkEnvironment.Production), `task/${taskId}#comment-${commentId}`);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Generate the URL for a single comment on a given project.
|
|
137
|
+
*
|
|
138
|
+
* @param projectId The ID of the project.
|
|
139
|
+
* @param commentId The ID of the comment.
|
|
140
|
+
* @param name The name of the project.
|
|
141
|
+
* @returns The URL string for the comment.
|
|
142
|
+
*/
|
|
143
|
+
export function getProjectCommentUrl(projectId, commentId, name) {
|
|
144
|
+
return buildUrl(() => todoistProjectCommentUrl(projectId, name !== null && name !== void 0 ? name : '', commentId, LinkEnvironment.Production), `project/${projectId}#comment-${commentId}`);
|
|
145
|
+
}
|
|
146
|
+
/** The kinds of Todoist entity a URL can point at. */
|
|
147
|
+
export const TODOIST_LINK_TYPES = [
|
|
148
|
+
'task',
|
|
149
|
+
'project',
|
|
150
|
+
'filter',
|
|
151
|
+
'label',
|
|
152
|
+
'section',
|
|
153
|
+
'workspace',
|
|
154
|
+
'template',
|
|
155
|
+
'comment',
|
|
156
|
+
'label_by_name',
|
|
157
|
+
];
|
|
158
|
+
/**
|
|
159
|
+
* Maps the link parser's type names onto the types this SDK exposes. A name
|
|
160
|
+
* that is missing here is one this SDK does not know about, and is treated as
|
|
161
|
+
* an unrecognised URL rather than surfaced as a value outside the union.
|
|
162
|
+
*/
|
|
163
|
+
const LINK_TYPE_BY_PARSED_NAME = {
|
|
164
|
+
Task: 'task',
|
|
165
|
+
Project: 'project',
|
|
166
|
+
Filter: 'filter',
|
|
167
|
+
Label: 'label',
|
|
168
|
+
Section: 'section',
|
|
169
|
+
Workspace: 'workspace',
|
|
170
|
+
Template: 'template',
|
|
171
|
+
Comment: 'comment',
|
|
172
|
+
LabelByName: 'label_by_name',
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Parse a Todoist URL into the entity it points at.
|
|
176
|
+
*
|
|
177
|
+
* @param url The URL to parse.
|
|
178
|
+
* @returns The entity the URL points at, or `null` if it is not a Todoist URL.
|
|
179
|
+
*/
|
|
180
|
+
export function parseTodoistUrl(url) {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
const link = parseTodoistLink(url);
|
|
183
|
+
if (!link) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
const type = LINK_TYPE_BY_PARSED_NAME[link.type.name];
|
|
187
|
+
if (!type) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
type,
|
|
192
|
+
id: link.id,
|
|
193
|
+
workspaceId: (_a = link.workspaceId) !== null && _a !== void 0 ? _a : null,
|
|
194
|
+
commentId: (_b = link.commentId) !== null && _b !== void 0 ? _b : null,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ActivityEventSchema } from '../types/activity/types.js';
|
|
3
|
+
import { AppSchema, AppWithUserCountSchema, AppSecretsSchema, AppVerificationTokenSchema, AppTestTokenSchema, AppDistributionTokenSchema, AppByDistributionTokenSchema, AppWebhookSchema, AppInstallationSchema, UserAuthorizationSchema, } from '../types/apps/types.js';
|
|
4
|
+
import { BackupSchema } from '../types/backups/types.js';
|
|
5
|
+
import { SubscriptionInfoSchema, ProPlanDetailsSchema, PricesResponseSchema, PricingResponseSchema, } from '../types/billing/types.js';
|
|
6
|
+
import { AttachmentSchema, CommentSchema } from '../types/comments/types.js';
|
|
7
|
+
import { IdMappingSchema, MovedIdSchema } from '../types/id-mappings/types.js';
|
|
8
|
+
import { ProjectActivityStatsSchema, ProjectHealthSchema, ProjectHealthContextSchema, ProjectProgressSchema, WorkspaceInsightsSchema, } from '../types/insights/types.js';
|
|
9
|
+
import { LabelSchema } from '../types/labels/types.js';
|
|
10
|
+
import { ProductivityStatsSchema } from '../types/productivity/types.js';
|
|
11
|
+
import { WorkspaceProjectSchema, ProjectSchema } from '../types/projects/types.js';
|
|
12
|
+
import { SectionSchema } from '../types/sections/types.js';
|
|
13
|
+
import { SyncResponseSchema } from '../types/sync/response.js';
|
|
14
|
+
import { TaskSchema } from '../types/tasks/types.js';
|
|
15
|
+
import { UiExtensionSchema } from '../types/ui-extensions/types.js';
|
|
16
|
+
import { UserSchema, CurrentUserSchema } from '../types/users/types.js';
|
|
17
|
+
import { WorkspaceUserSchema, WorkspaceInvitationSchema, WorkspacePlanDetailsSchema, JoinWorkspaceResultSchema, WorkspaceSchema, MemberActivityInfoSchema, WorkspaceUserTaskSchema, } from '../types/workspaces/types.js';
|
|
18
|
+
import { FilterSchema, CollaboratorSchema, CollaboratorStateSchema, FolderSchema, NoteSchema, TooltipsSchema, WorkspaceFilterSchema, CalendarSchema, CalendarAccountSchema, ReminderSchema, LocationReminderSchema, CompletedInfoSchema, ViewOptionsSchema, ProjectViewOptionsDefaultsSchema, UserPlanLimitsSchema, LiveNotificationSchema, SyncWorkspaceSchema, SyncUserSchema, UserSettingsSchema, SuggestionSchema, } from '../types/sync/resources/index.js';
|
|
19
|
+
function createValidator(schema) {
|
|
20
|
+
return {
|
|
21
|
+
validate: (input) => schema.parse(input),
|
|
22
|
+
validateArray: (input) => z.array(schema).parse(input),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const TMP_ID_MESSAGE = 'This looks like a client-side placeholder — wait for sync to complete before calling the API.';
|
|
26
|
+
export const IdSchema = z
|
|
27
|
+
.string()
|
|
28
|
+
.min(1)
|
|
29
|
+
.refine((id) => !id.startsWith('tmp-'), { message: TMP_ID_MESSAGE });
|
|
30
|
+
// Entity validators
|
|
31
|
+
export const { validate: validateTask, validateArray: validateTaskArray } = createValidator(TaskSchema);
|
|
32
|
+
/**
|
|
33
|
+
* Validates and parses a project input.
|
|
34
|
+
* @param input The input to validate
|
|
35
|
+
* @returns A validated project (either PersonalProject or WorkspaceProject)
|
|
36
|
+
*/
|
|
37
|
+
export const { validate: validateProject, validateArray: validateProjectArray } = createValidator(ProjectSchema);
|
|
38
|
+
export const { validate: validateWorkspaceProject, validateArray: validateWorkspaceProjectArray } = createValidator(WorkspaceProjectSchema);
|
|
39
|
+
export const { validate: validateSection, validateArray: validateSectionArray } = createValidator(SectionSchema);
|
|
40
|
+
export const { validate: validateLabel, validateArray: validateLabelArray } = createValidator(LabelSchema);
|
|
41
|
+
export const { validate: validateComment, validateArray: validateCommentArray } = createValidator(CommentSchema);
|
|
42
|
+
export const { validate: validateUser, validateArray: validateUserArray } = createValidator(UserSchema);
|
|
43
|
+
export const { validate: validateProductivityStats } = createValidator(ProductivityStatsSchema);
|
|
44
|
+
export const { validate: validateCurrentUser } = createValidator(CurrentUserSchema);
|
|
45
|
+
export const { validate: validateActivityEvent, validateArray: validateActivityEventArray } = createValidator(ActivityEventSchema);
|
|
46
|
+
export const { validate: validateAttachment } = createValidator(AttachmentSchema);
|
|
47
|
+
export const { validate: validateWorkspaceUser, validateArray: validateWorkspaceUserArray } = createValidator(WorkspaceUserSchema);
|
|
48
|
+
export const { validate: validateWorkspaceInvitation, validateArray: validateWorkspaceInvitationArray, } = createValidator(WorkspaceInvitationSchema);
|
|
49
|
+
export const { validate: validateWorkspacePlanDetails } = createValidator(WorkspacePlanDetailsSchema);
|
|
50
|
+
export const { validate: validateJoinWorkspaceResult } = createValidator(JoinWorkspaceResultSchema);
|
|
51
|
+
export const { validate: validateWorkspace, validateArray: validateWorkspaceArray } = createValidator(WorkspaceSchema);
|
|
52
|
+
export const { validate: validateMemberActivityInfo, validateArray: validateMemberActivityInfoArray, } = createValidator(MemberActivityInfoSchema);
|
|
53
|
+
export const { validate: validateWorkspaceUserTask, validateArray: validateWorkspaceUserTaskArray, } = createValidator(WorkspaceUserTaskSchema);
|
|
54
|
+
export const { validate: validateProjectActivityStats } = createValidator(ProjectActivityStatsSchema);
|
|
55
|
+
export const { validate: validateProjectHealth } = createValidator(ProjectHealthSchema);
|
|
56
|
+
export const { validate: validateProjectHealthContext } = createValidator(ProjectHealthContextSchema);
|
|
57
|
+
export const { validate: validateProjectProgress } = createValidator(ProjectProgressSchema);
|
|
58
|
+
export const { validate: validateWorkspaceInsights } = createValidator(WorkspaceInsightsSchema);
|
|
59
|
+
export const { validate: validateBackup, validateArray: validateBackupArray } = createValidator(BackupSchema);
|
|
60
|
+
export const { validate: validateIdMapping, validateArray: validateIdMappingArray } = createValidator(IdMappingSchema);
|
|
61
|
+
export const { validate: validateMovedId, validateArray: validateMovedIdArray } = createValidator(MovedIdSchema);
|
|
62
|
+
// Sync resource validators
|
|
63
|
+
export const { validate: validateFilter, validateArray: validateFilterArray } = createValidator(FilterSchema);
|
|
64
|
+
export const { validate: validateCollaborator, validateArray: validateCollaboratorArray } = createValidator(CollaboratorSchema);
|
|
65
|
+
export const { validate: validateCollaboratorState, validateArray: validateCollaboratorStateArray, } = createValidator(CollaboratorStateSchema);
|
|
66
|
+
export const { validate: validateFolder, validateArray: validateFolderArray } = createValidator(FolderSchema);
|
|
67
|
+
// Billing validators
|
|
68
|
+
export const { validate: validateSubscriptionInfo } = createValidator(SubscriptionInfoSchema);
|
|
69
|
+
export const { validate: validateProPlanDetails } = createValidator(ProPlanDetailsSchema);
|
|
70
|
+
export const { validate: validatePrices } = createValidator(PricesResponseSchema);
|
|
71
|
+
export const { validate: validatePricing } = createValidator(PricingResponseSchema);
|
|
72
|
+
export const { validate: validateNote, validateArray: validateNoteArray } = createValidator(NoteSchema);
|
|
73
|
+
export const { validate: validateTooltips } = createValidator(TooltipsSchema);
|
|
74
|
+
export const { validate: validateWorkspaceFilter, validateArray: validateWorkspaceFilterArray } = createValidator(WorkspaceFilterSchema);
|
|
75
|
+
export const { validate: validateCalendar, validateArray: validateCalendarArray } = createValidator(CalendarSchema);
|
|
76
|
+
export const { validate: validateCalendarAccount, validateArray: validateCalendarAccountArray } = createValidator(CalendarAccountSchema);
|
|
77
|
+
export const { validate: validateReminder, validateArray: validateReminderArray } = createValidator(ReminderSchema);
|
|
78
|
+
export const { validate: validateLocationReminder, validateArray: validateLocationReminderArray } = createValidator(LocationReminderSchema);
|
|
79
|
+
export const { validate: validateCompletedInfo, validateArray: validateCompletedInfoArray } = createValidator(CompletedInfoSchema);
|
|
80
|
+
export const { validate: validateViewOptions, validateArray: validateViewOptionsArray } = createValidator(ViewOptionsSchema);
|
|
81
|
+
export const { validate: validateProjectViewOptionsDefaults, validateArray: validateProjectViewOptionsDefaultsArray, } = createValidator(ProjectViewOptionsDefaultsSchema);
|
|
82
|
+
export const { validate: validateUserPlanLimits } = createValidator(UserPlanLimitsSchema);
|
|
83
|
+
export const { validate: validateLiveNotification, validateArray: validateLiveNotificationArray } = createValidator(LiveNotificationSchema);
|
|
84
|
+
export const { validate: validateSyncWorkspace, validateArray: validateSyncWorkspaceArray } = createValidator(SyncWorkspaceSchema);
|
|
85
|
+
export const { validate: validateSyncUser } = createValidator(SyncUserSchema);
|
|
86
|
+
export const { validate: validateUserSettings } = createValidator(UserSettingsSchema);
|
|
87
|
+
export const { validate: validateSuggestion, validateArray: validateSuggestionArray } = createValidator(SuggestionSchema);
|
|
88
|
+
export function parseSyncResponse(raw) {
|
|
89
|
+
return SyncResponseSchema.parse(raw);
|
|
90
|
+
}
|
|
91
|
+
// App management validators
|
|
92
|
+
export const { validate: validateApp, validateArray: validateAppArray } = createValidator(AppSchema);
|
|
93
|
+
export const { validate: validateAppWithUserCount } = createValidator(AppWithUserCountSchema);
|
|
94
|
+
export const { validate: validateAppSecrets } = createValidator(AppSecretsSchema);
|
|
95
|
+
export const { validate: validateAppVerificationToken } = createValidator(AppVerificationTokenSchema);
|
|
96
|
+
export const { validate: validateAppTestToken } = createValidator(AppTestTokenSchema);
|
|
97
|
+
export const { validate: validateAppDistributionToken } = createValidator(AppDistributionTokenSchema);
|
|
98
|
+
export const { validate: validateAppByDistributionToken } = createValidator(AppByDistributionTokenSchema);
|
|
99
|
+
export const { validate: validateAppWebhook } = createValidator(AppWebhookSchema);
|
|
100
|
+
export const { validate: validateAppInstallation, validateArray: validateAppInstallationArray } = createValidator(AppInstallationSchema);
|
|
101
|
+
export const { validate: validateUserAuthorization, validateArray: validateUserAuthorizationArray, } = createValidator(UserAuthorizationSchema);
|
|
102
|
+
export const { validate: validateUiExtension, validateArray: validateUiExtensionArray } = createValidator(UiExtensionSchema);
|
|
@@ -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.some((viewType) => viewType === entry.viewType);
|
|
14
|
+
});
|
|
15
|
+
}
|