@doist/todoist-api-typescript 6.1.12 → 6.2.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.
@@ -79,6 +79,7 @@ exports.DEFAULT_TASK = {
79
79
  noteCount: DEFAULT_NOTE_COUNT,
80
80
  dayOrder: exports.DEFAULT_ORDER,
81
81
  isCollapsed: DEFAULT_IS_COLLAPSED,
82
+ isUncompletable: false,
82
83
  url: DEFAULT_TASK_URL,
83
84
  };
84
85
  exports.INVALID_TASK = Object.assign(Object.assign({}, exports.DEFAULT_TASK), { due: '2020-01-31' });
@@ -106,6 +107,7 @@ exports.TASK_WITH_OPTIONALS_AS_NULL = {
106
107
  description: exports.DEFAULT_TASK_DESCRIPTION,
107
108
  dayOrder: exports.DEFAULT_ORDER,
108
109
  isCollapsed: DEFAULT_IS_COLLAPSED,
110
+ isUncompletable: false,
109
111
  noteCount: DEFAULT_NOTE_COUNT,
110
112
  url: DEFAULT_TASK_URL,
111
113
  };
@@ -7,6 +7,7 @@ const validators_1 = require("./utils/validators");
7
7
  const url_helpers_1 = require("./utils/url-helpers");
8
8
  const multipart_upload_1 = require("./utils/multipart-upload");
9
9
  const activity_helpers_1 = require("./utils/activity-helpers");
10
+ const uncompletable_helpers_1 = require("./utils/uncompletable-helpers");
10
11
  const zod_1 = require("zod");
11
12
  const uuid_1 = require("uuid");
12
13
  const types_1 = require("./types");
@@ -185,13 +186,15 @@ class TodoistApi {
185
186
  * @returns A promise that resolves to the created task.
186
187
  */
187
188
  async addTask(args, requestId) {
189
+ // Process content based on isUncompletable flag
190
+ const processedArgs = Object.assign(Object.assign({}, args), { content: (0, uncompletable_helpers_1.processTaskContent)(args.content, args.isUncompletable) });
188
191
  const response = await (0, rest_client_1.request)({
189
192
  httpMethod: 'POST',
190
193
  baseUri: this.syncApiBase,
191
194
  relativePath: endpoints_1.ENDPOINT_REST_TASKS,
192
195
  apiToken: this.authToken,
193
196
  customFetch: this.customFetch,
194
- payload: args,
197
+ payload: processedArgs,
195
198
  requestId: requestId,
196
199
  });
197
200
  return (0, validators_1.validateTask)(response.data);
@@ -203,13 +206,15 @@ class TodoistApi {
203
206
  * @returns A promise that resolves to the created task.
204
207
  */
205
208
  async quickAddTask(args) {
209
+ // Process text based on isUncompletable flag
210
+ const processedArgs = Object.assign(Object.assign({}, args), { text: (0, uncompletable_helpers_1.processTaskContent)(args.text, args.isUncompletable) });
206
211
  const response = await (0, rest_client_1.request)({
207
212
  httpMethod: 'POST',
208
213
  baseUri: this.syncApiBase,
209
214
  relativePath: endpoints_1.ENDPOINT_SYNC_QUICK_ADD,
210
215
  apiToken: this.authToken,
211
216
  customFetch: this.customFetch,
212
- payload: args,
217
+ payload: processedArgs,
213
218
  });
214
219
  return (0, validators_1.validateTask)(response.data);
215
220
  }
@@ -223,13 +228,16 @@ class TodoistApi {
223
228
  */
224
229
  async updateTask(id, args, requestId) {
225
230
  zod_1.z.string().parse(id);
231
+ // Process content if both content and isUncompletable are provided
232
+ const processedArgs = args.content && args.isUncompletable !== undefined
233
+ ? Object.assign(Object.assign({}, args), { content: (0, uncompletable_helpers_1.processTaskContent)(args.content, args.isUncompletable) }) : args;
226
234
  const response = await (0, rest_client_1.request)({
227
235
  httpMethod: 'POST',
228
236
  baseUri: this.syncApiBase,
229
237
  relativePath: generatePath(endpoints_1.ENDPOINT_REST_TASKS, id),
230
238
  apiToken: this.authToken,
231
239
  customFetch: this.customFetch,
232
- payload: args,
240
+ payload: processedArgs,
233
241
  requestId: requestId,
234
242
  });
235
243
  return (0, validators_1.validateTask)(response.data);
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.JoinWorkspaceResultSchema = exports.WorkspacePlanDetailsSchema = exports.FormattedPriceListingSchema = exports.PlanPriceSchema = exports.WorkspaceInvitationSchema = exports.WorkspaceUserSchema = exports.WorkspaceRoleSchema = exports.WORKSPACE_ROLES = exports.ActivityEventSchema = exports.ActivityEventExtraDataSchema = exports.ColorSchema = exports.ProductivityStatsSchema = exports.CurrentUserSchema = exports.TimezoneInfoSchema = exports.UserSchema = exports.CommentSchema = exports.RawCommentSchema = exports.AttachmentSchema = exports.LabelSchema = exports.SectionSchema = exports.WorkspaceProjectSchema = exports.PersonalProjectSchema = exports.BaseProjectSchema = exports.TaskSchema = exports.DeadlineSchema = exports.DurationSchema = exports.DueDateSchema = void 0;
15
15
  const zod_1 = require("zod");
16
16
  const url_helpers_1 = require("../utils/url-helpers");
17
+ const uncompletable_helpers_1 = require("../utils/uncompletable-helpers");
17
18
  exports.DueDateSchema = zod_1.z
18
19
  .object({
19
20
  isRecurring: zod_1.z.boolean(),
@@ -59,9 +60,12 @@ exports.TaskSchema = zod_1.z
59
60
  noteCount: zod_1.z.number().int(),
60
61
  dayOrder: zod_1.z.number().int(),
61
62
  isCollapsed: zod_1.z.boolean(),
63
+ isUncompletable: zod_1.z.boolean().default(false),
62
64
  })
63
65
  .transform((data) => {
64
- return Object.assign(Object.assign({}, data), { url: (0, url_helpers_1.getTaskUrl)(data.id, data.content) });
66
+ // Auto-detect uncompletable status from content prefix
67
+ const isUncompletable = (0, uncompletable_helpers_1.hasUncompletablePrefix)(data.content);
68
+ return Object.assign(Object.assign({}, data), { isUncompletable, url: (0, url_helpers_1.getTaskUrl)(data.id, data.content) });
65
69
  });
66
70
  /**
67
71
  * Base schema for all project types in Todoist.
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addUncompletablePrefix = addUncompletablePrefix;
4
+ exports.removeUncompletablePrefix = removeUncompletablePrefix;
5
+ exports.hasUncompletablePrefix = hasUncompletablePrefix;
6
+ exports.processTaskContent = processTaskContent;
7
+ const UNCOMPLETABLE_PREFIX = '* ';
8
+ /**
9
+ * Adds the uncompletable prefix (* ) to task content if not already present
10
+ * @param content - The task content
11
+ * @returns Content with uncompletable prefix added
12
+ */
13
+ function addUncompletablePrefix(content) {
14
+ if (content.startsWith(UNCOMPLETABLE_PREFIX)) {
15
+ return content;
16
+ }
17
+ return UNCOMPLETABLE_PREFIX + content;
18
+ }
19
+ /**
20
+ * Removes the uncompletable prefix (* ) from task content if present
21
+ * @param content - The task content
22
+ * @returns Content with uncompletable prefix removed
23
+ */
24
+ function removeUncompletablePrefix(content) {
25
+ if (content.startsWith(UNCOMPLETABLE_PREFIX)) {
26
+ return content.slice(UNCOMPLETABLE_PREFIX.length);
27
+ }
28
+ return content;
29
+ }
30
+ /**
31
+ * Checks if task content has the uncompletable prefix (* )
32
+ * @param content - The task content
33
+ * @returns True if content starts with uncompletable prefix
34
+ */
35
+ function hasUncompletablePrefix(content) {
36
+ return content.startsWith(UNCOMPLETABLE_PREFIX);
37
+ }
38
+ /**
39
+ * Processes task content based on isUncompletable flag, with content prefix taking precedence
40
+ * @param content - The original task content
41
+ * @param isUncompletable - Optional flag to make task uncompletable
42
+ * @returns Processed content
43
+ *
44
+ * Logic:
45
+ * - If content already has * prefix, task is uncompletable regardless of flag
46
+ * - If content doesn't have * prefix and isUncompletable is true, add the prefix
47
+ * - If isUncompletable is undefined or false (and no prefix), leave content unchanged
48
+ */
49
+ function processTaskContent(content, isUncompletable) {
50
+ // Content prefix takes precedence - if already has prefix, keep it
51
+ if (hasUncompletablePrefix(content)) {
52
+ return content;
53
+ }
54
+ // If content doesn't have prefix and user wants uncompletable, add it
55
+ if (isUncompletable === true) {
56
+ return addUncompletablePrefix(content);
57
+ }
58
+ // Otherwise, leave content unchanged
59
+ return content;
60
+ }
@@ -76,6 +76,7 @@ export const DEFAULT_TASK = {
76
76
  noteCount: DEFAULT_NOTE_COUNT,
77
77
  dayOrder: DEFAULT_ORDER,
78
78
  isCollapsed: DEFAULT_IS_COLLAPSED,
79
+ isUncompletable: false,
79
80
  url: DEFAULT_TASK_URL,
80
81
  };
81
82
  export const INVALID_TASK = Object.assign(Object.assign({}, DEFAULT_TASK), { due: '2020-01-31' });
@@ -103,6 +104,7 @@ export const TASK_WITH_OPTIONALS_AS_NULL = {
103
104
  description: DEFAULT_TASK_DESCRIPTION,
104
105
  dayOrder: DEFAULT_ORDER,
105
106
  isCollapsed: DEFAULT_IS_COLLAPSED,
107
+ isUncompletable: false,
106
108
  noteCount: DEFAULT_NOTE_COUNT,
107
109
  url: DEFAULT_TASK_URL,
108
110
  };
@@ -4,6 +4,7 @@ import { validateAttachment, validateComment, validateCommentArray, validateCurr
4
4
  import { formatDateToYYYYMMDD } from './utils/url-helpers.js';
5
5
  import { uploadMultipartFile } from './utils/multipart-upload.js';
6
6
  import { normalizeObjectTypeForApi, denormalizeObjectTypeFromApi } from './utils/activity-helpers.js';
7
+ import { processTaskContent } from './utils/uncompletable-helpers.js';
7
8
  import { z } from 'zod';
8
9
  import { v4 as uuidv4 } from 'uuid';
9
10
  import { TodoistRequestError } from './types/index.js';
@@ -182,13 +183,15 @@ export class TodoistApi {
182
183
  * @returns A promise that resolves to the created task.
183
184
  */
184
185
  async addTask(args, requestId) {
186
+ // Process content based on isUncompletable flag
187
+ const processedArgs = Object.assign(Object.assign({}, args), { content: processTaskContent(args.content, args.isUncompletable) });
185
188
  const response = await request({
186
189
  httpMethod: 'POST',
187
190
  baseUri: this.syncApiBase,
188
191
  relativePath: ENDPOINT_REST_TASKS,
189
192
  apiToken: this.authToken,
190
193
  customFetch: this.customFetch,
191
- payload: args,
194
+ payload: processedArgs,
192
195
  requestId: requestId,
193
196
  });
194
197
  return validateTask(response.data);
@@ -200,13 +203,15 @@ export class TodoistApi {
200
203
  * @returns A promise that resolves to the created task.
201
204
  */
202
205
  async quickAddTask(args) {
206
+ // Process text based on isUncompletable flag
207
+ const processedArgs = Object.assign(Object.assign({}, args), { text: processTaskContent(args.text, args.isUncompletable) });
203
208
  const response = await request({
204
209
  httpMethod: 'POST',
205
210
  baseUri: this.syncApiBase,
206
211
  relativePath: ENDPOINT_SYNC_QUICK_ADD,
207
212
  apiToken: this.authToken,
208
213
  customFetch: this.customFetch,
209
- payload: args,
214
+ payload: processedArgs,
210
215
  });
211
216
  return validateTask(response.data);
212
217
  }
@@ -220,13 +225,16 @@ export class TodoistApi {
220
225
  */
221
226
  async updateTask(id, args, requestId) {
222
227
  z.string().parse(id);
228
+ // Process content if both content and isUncompletable are provided
229
+ const processedArgs = args.content && args.isUncompletable !== undefined
230
+ ? Object.assign(Object.assign({}, args), { content: processTaskContent(args.content, args.isUncompletable) }) : args;
223
231
  const response = await request({
224
232
  httpMethod: 'POST',
225
233
  baseUri: this.syncApiBase,
226
234
  relativePath: generatePath(ENDPOINT_REST_TASKS, id),
227
235
  apiToken: this.authToken,
228
236
  customFetch: this.customFetch,
229
- payload: args,
237
+ payload: processedArgs,
230
238
  requestId: requestId,
231
239
  });
232
240
  return validateTask(response.data);
@@ -11,6 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { z } from 'zod';
13
13
  import { getProjectUrl, getTaskUrl, getSectionUrl } from '../utils/url-helpers.js';
14
+ import { hasUncompletablePrefix } from '../utils/uncompletable-helpers.js';
14
15
  export const DueDateSchema = z
15
16
  .object({
16
17
  isRecurring: z.boolean(),
@@ -56,9 +57,12 @@ export const TaskSchema = z
56
57
  noteCount: z.number().int(),
57
58
  dayOrder: z.number().int(),
58
59
  isCollapsed: z.boolean(),
60
+ isUncompletable: z.boolean().default(false),
59
61
  })
60
62
  .transform((data) => {
61
- return Object.assign(Object.assign({}, data), { url: getTaskUrl(data.id, data.content) });
63
+ // Auto-detect uncompletable status from content prefix
64
+ const isUncompletable = hasUncompletablePrefix(data.content);
65
+ return Object.assign(Object.assign({}, data), { isUncompletable, url: getTaskUrl(data.id, data.content) });
62
66
  });
63
67
  /**
64
68
  * Base schema for all project types in Todoist.
@@ -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
+ }
@@ -22,6 +22,7 @@ export declare const DEFAULT_DEADLINE: Deadline;
22
22
  export declare const DEFAULT_TASK: Task;
23
23
  export declare const INVALID_TASK: {
24
24
  due: string;
25
+ isUncompletable: boolean;
25
26
  url: string;
26
27
  id: string;
27
28
  userId: string;
@@ -73,7 +73,9 @@ export declare const TaskSchema: z.ZodPipe<z.ZodObject<{
73
73
  noteCount: z.ZodNumber;
74
74
  dayOrder: z.ZodNumber;
75
75
  isCollapsed: z.ZodBoolean;
76
+ isUncompletable: z.ZodDefault<z.ZodBoolean>;
76
77
  }, z.core.$strip>, z.ZodTransform<{
78
+ isUncompletable: boolean;
77
79
  url: string;
78
80
  id: string;
79
81
  userId: string;
@@ -150,6 +152,7 @@ export declare const TaskSchema: z.ZodPipe<z.ZodObject<{
150
152
  noteCount: number;
151
153
  dayOrder: number;
152
154
  isCollapsed: boolean;
155
+ isUncompletable: boolean;
153
156
  }>>;
154
157
  /**
155
158
  * Represents a task in Todoist.
@@ -18,6 +18,7 @@ export type AddTaskArgs = {
18
18
  dueLang?: string;
19
19
  deadlineLang?: string;
20
20
  deadlineDate?: string;
21
+ isUncompletable?: boolean;
21
22
  } & RequireOneOrNone<{
22
23
  dueDate?: string;
23
24
  dueDatetime?: string;
@@ -118,6 +119,7 @@ export type UpdateTaskArgs = {
118
119
  assigneeId?: string | null;
119
120
  deadlineDate?: string | null;
120
121
  deadlineLang?: string | null;
122
+ isUncompletable?: boolean;
121
123
  } & RequireOneOrNone<{
122
124
  dueDate?: string;
123
125
  dueDatetime?: string;
@@ -135,6 +137,7 @@ export type QuickAddTaskArgs = {
135
137
  reminder?: string;
136
138
  autoReminder?: boolean;
137
139
  meta?: boolean;
140
+ isUncompletable?: boolean;
138
141
  };
139
142
  /**
140
143
  * Response from quick adding a task.
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Adds the uncompletable prefix (* ) to task content if not already present
3
+ * @param content - The task content
4
+ * @returns Content with uncompletable prefix added
5
+ */
6
+ export declare function addUncompletablePrefix(content: string): string;
7
+ /**
8
+ * Removes the uncompletable prefix (* ) from task content if present
9
+ * @param content - The task content
10
+ * @returns Content with uncompletable prefix removed
11
+ */
12
+ export declare function removeUncompletablePrefix(content: string): string;
13
+ /**
14
+ * Checks if task content has the uncompletable prefix (* )
15
+ * @param content - The task content
16
+ * @returns True if content starts with uncompletable prefix
17
+ */
18
+ export declare function hasUncompletablePrefix(content: string): boolean;
19
+ /**
20
+ * Processes task content based on isUncompletable flag, with content prefix taking precedence
21
+ * @param content - The original task content
22
+ * @param isUncompletable - Optional flag to make task uncompletable
23
+ * @returns Processed content
24
+ *
25
+ * Logic:
26
+ * - If content already has * prefix, task is uncompletable regardless of flag
27
+ * - If content doesn't have * prefix and isUncompletable is true, add the prefix
28
+ * - If isUncompletable is undefined or false (and no prefix), leave content unchanged
29
+ */
30
+ export declare function processTaskContent(content: string, isUncompletable?: boolean): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/todoist-api-typescript",
3
- "version": "6.1.12",
3
+ "version": "6.2.0",
4
4
  "description": "A typescript wrapper for the Todoist REST API.",
5
5
  "author": "Doist developers",
6
6
  "repository": "https://github.com/Doist/todoist-api-typescript",