@todoist/sdk 0.0.1 → 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.
Files changed (335) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +293 -29
  3. package/dist/esm/authentication.js +307 -0
  4. package/dist/esm/clients/activity-client.js +60 -0
  5. package/dist/esm/clients/app-client.js +366 -0
  6. package/dist/esm/clients/backup-client.js +47 -0
  7. package/dist/esm/clients/base-client.js +29 -0
  8. package/dist/esm/clients/billing-client.js +160 -0
  9. package/dist/esm/clients/comment-client.js +92 -0
  10. package/dist/esm/clients/email-client.js +41 -0
  11. package/dist/esm/clients/filter-client.js +26 -0
  12. package/dist/esm/clients/folder-client.js +80 -0
  13. package/dist/esm/clients/id-mapping-client.js +37 -0
  14. package/dist/esm/clients/insights-client.js +89 -0
  15. package/dist/esm/clients/label-client.js +131 -0
  16. package/dist/esm/clients/productivity-client.js +24 -0
  17. package/dist/esm/clients/project-client.js +284 -0
  18. package/dist/esm/clients/reminder-client.js +204 -0
  19. package/dist/esm/clients/section-client.js +121 -0
  20. package/dist/esm/clients/task-client.js +264 -0
  21. package/dist/esm/clients/template-client.js +89 -0
  22. package/dist/esm/clients/ui-extension-client.js +110 -0
  23. package/dist/esm/clients/upload-client.js +153 -0
  24. package/dist/esm/clients/view-options-client.js +21 -0
  25. package/dist/esm/clients/workspace-client.js +384 -0
  26. package/dist/esm/consts/endpoints.js +193 -0
  27. package/dist/esm/index.js +5 -0
  28. package/dist/esm/test-utils/asserts.js +8 -0
  29. package/dist/esm/test-utils/msw-setup.js +88 -0
  30. package/dist/esm/test-utils/obsidian-fetch-adapter.js +51 -0
  31. package/dist/esm/test-utils/test-defaults.js +367 -0
  32. package/dist/esm/test-utils/transport-seam.js +15 -0
  33. package/dist/esm/test-utils/webhook-fixtures.js +26 -0
  34. package/dist/esm/todoist-api.js +1757 -0
  35. package/dist/esm/transport/fetch-with-retry.js +216 -0
  36. package/dist/esm/transport/http-client.js +140 -0
  37. package/dist/esm/transport/http-dispatcher.js +158 -0
  38. package/dist/esm/transport/sync-request.js +106 -0
  39. package/dist/esm/types/activity/index.js +2 -0
  40. package/dist/esm/types/activity/requests.js +1 -0
  41. package/dist/esm/types/activity/types.js +45 -0
  42. package/dist/esm/types/apps/index.js +2 -0
  43. package/dist/esm/types/apps/requests.js +1 -0
  44. package/dist/esm/types/apps/types.js +249 -0
  45. package/dist/esm/types/backups/index.js +2 -0
  46. package/dist/esm/types/backups/requests.js +1 -0
  47. package/dist/esm/types/backups/types.js +5 -0
  48. package/dist/esm/types/billing/index.js +2 -0
  49. package/dist/esm/types/billing/requests.js +1 -0
  50. package/dist/esm/types/billing/types.js +89 -0
  51. package/dist/esm/types/comments/index.js +2 -0
  52. package/dist/esm/types/comments/requests.js +1 -0
  53. package/dist/esm/types/comments/types.js +57 -0
  54. package/dist/esm/types/common.js +7 -0
  55. package/dist/esm/types/emails/index.js +1 -0
  56. package/dist/esm/types/emails/requests.js +2 -0
  57. package/dist/esm/types/errors.js +41 -0
  58. package/dist/esm/types/folders/index.js +1 -0
  59. package/dist/esm/types/folders/requests.js +1 -0
  60. package/dist/esm/types/http.js +20 -0
  61. package/dist/esm/types/id-mappings/index.js +2 -0
  62. package/dist/esm/types/id-mappings/requests.js +17 -0
  63. package/dist/esm/types/id-mappings/types.js +9 -0
  64. package/dist/esm/types/index.js +24 -0
  65. package/dist/esm/types/insights/index.js +2 -0
  66. package/dist/esm/types/insights/requests.js +1 -0
  67. package/dist/esm/types/insights/types.js +77 -0
  68. package/dist/esm/types/labels/index.js +2 -0
  69. package/dist/esm/types/labels/requests.js +1 -0
  70. package/dist/esm/types/labels/types.js +8 -0
  71. package/dist/esm/types/productivity/index.js +1 -0
  72. package/dist/esm/types/productivity/types.js +65 -0
  73. package/dist/esm/types/projects/index.js +2 -0
  74. package/dist/esm/types/projects/requests.js +1 -0
  75. package/dist/esm/types/projects/types.js +65 -0
  76. package/dist/esm/types/reminders/index.js +1 -0
  77. package/dist/esm/types/reminders/requests.js +92 -0
  78. package/dist/esm/types/sections/index.js +2 -0
  79. package/dist/esm/types/sections/requests.js +1 -0
  80. package/dist/esm/types/sections/types.js +23 -0
  81. package/dist/esm/types/sync/commands/calendars.js +1 -0
  82. package/dist/esm/types/sync/commands/filters.js +1 -0
  83. package/dist/esm/types/sync/commands/folders.js +1 -0
  84. package/dist/esm/types/sync/commands/index.js +18 -0
  85. package/dist/esm/types/sync/commands/labels.js +2 -0
  86. package/dist/esm/types/sync/commands/notes.js +1 -0
  87. package/dist/esm/types/sync/commands/notifications.js +1 -0
  88. package/dist/esm/types/sync/commands/others.js +1 -0
  89. package/dist/esm/types/sync/commands/project-view-options.js +1 -0
  90. package/dist/esm/types/sync/commands/projects.js +1 -0
  91. package/dist/esm/types/sync/commands/reminders.js +1 -0
  92. package/dist/esm/types/sync/commands/sections.js +1 -0
  93. package/dist/esm/types/sync/commands/shared.js +16 -0
  94. package/dist/esm/types/sync/commands/sharing.js +1 -0
  95. package/dist/esm/types/sync/commands/tasks.js +1 -0
  96. package/dist/esm/types/sync/commands/view-options.js +1 -0
  97. package/dist/esm/types/sync/commands/workspace-filters.js +1 -0
  98. package/dist/esm/types/sync/commands/workspaces.js +1 -0
  99. package/dist/esm/types/sync/index.js +6 -0
  100. package/dist/esm/types/sync/request.js +1 -0
  101. package/dist/esm/types/sync/resource-types.js +36 -0
  102. package/dist/esm/types/sync/resources/calendars.js +24 -0
  103. package/dist/esm/types/sync/resources/collaborators.js +21 -0
  104. package/dist/esm/types/sync/resources/completed-info.js +21 -0
  105. package/dist/esm/types/sync/resources/filters.js +12 -0
  106. package/dist/esm/types/sync/resources/folders.js +10 -0
  107. package/dist/esm/types/sync/resources/index.js +18 -0
  108. package/dist/esm/types/sync/resources/labels.js +7 -0
  109. package/dist/esm/types/sync/resources/live-notifications.js +35 -0
  110. package/dist/esm/types/sync/resources/notes.js +18 -0
  111. package/dist/esm/types/sync/resources/reminders.js +58 -0
  112. package/dist/esm/types/sync/resources/suggestions.js +33 -0
  113. package/dist/esm/types/sync/resources/tooltips.js +5 -0
  114. package/dist/esm/types/sync/resources/user-plan-limits.js +21 -0
  115. package/dist/esm/types/sync/resources/user-settings.js +41 -0
  116. package/dist/esm/types/sync/resources/user-status.js +22 -0
  117. package/dist/esm/types/sync/resources/user.js +109 -0
  118. package/dist/esm/types/sync/resources/view-options.js +128 -0
  119. package/dist/esm/types/sync/resources/workspace-filters.js +17 -0
  120. package/dist/esm/types/sync/resources/workspaces.js +69 -0
  121. package/dist/esm/types/sync/response.js +57 -0
  122. package/dist/esm/types/sync/user-preferences.js +68 -0
  123. package/dist/esm/types/tasks/index.js +2 -0
  124. package/dist/esm/types/tasks/requests.js +1 -0
  125. package/dist/esm/types/tasks/types.js +56 -0
  126. package/dist/esm/types/templates/index.js +1 -0
  127. package/dist/esm/types/templates/requests.js +1 -0
  128. package/dist/esm/types/ui-extensions/index.js +2 -0
  129. package/dist/esm/types/ui-extensions/requests.js +1 -0
  130. package/dist/esm/types/ui-extensions/types.js +74 -0
  131. package/dist/esm/types/uploads/index.js +1 -0
  132. package/dist/esm/types/uploads/requests.js +1 -0
  133. package/dist/esm/types/users/index.js +1 -0
  134. package/dist/esm/types/users/types.js +49 -0
  135. package/dist/esm/types/webhooks/comments.js +93 -0
  136. package/dist/esm/types/webhooks/envelope.js +23 -0
  137. package/dist/esm/types/webhooks/filters.js +27 -0
  138. package/dist/esm/types/webhooks/index.js +9 -0
  139. package/dist/esm/types/webhooks/labels.js +51 -0
  140. package/dist/esm/types/webhooks/projects.js +33 -0
  141. package/dist/esm/types/webhooks/reminders.js +32 -0
  142. package/dist/esm/types/webhooks/sections.js +50 -0
  143. package/dist/esm/types/webhooks/tasks.js +65 -0
  144. package/dist/esm/types/webhooks/types.js +52 -0
  145. package/dist/esm/types/workspaces/index.js +2 -0
  146. package/dist/esm/types/workspaces/requests.js +1 -0
  147. package/dist/esm/types/workspaces/types.js +151 -0
  148. package/dist/esm/utils/activity-helpers.js +53 -0
  149. package/dist/esm/utils/case-conversion.js +84 -0
  150. package/dist/esm/utils/colors.js +145 -0
  151. package/dist/esm/utils/file-response.js +29 -0
  152. package/dist/esm/utils/filter-queries.js +231 -0
  153. package/dist/esm/utils/filter-query-definitions.js +2789 -0
  154. package/dist/esm/utils/headers.js +42 -0
  155. package/dist/esm/utils/index.js +11 -0
  156. package/dist/esm/utils/multipart-upload.js +267 -0
  157. package/dist/esm/utils/person-names.js +61 -0
  158. package/dist/esm/utils/processing-helpers.js +12 -0
  159. package/dist/esm/utils/project-helpers.js +29 -0
  160. package/dist/esm/utils/request-helpers.js +43 -0
  161. package/dist/esm/utils/sanitization.js +131 -0
  162. package/dist/esm/utils/sync-helpers.js +19 -0
  163. package/dist/esm/utils/task-sorting.js +280 -0
  164. package/dist/esm/utils/uncompletable-helpers.js +54 -0
  165. package/dist/esm/utils/url-helpers.js +196 -0
  166. package/dist/esm/utils/validators.js +102 -0
  167. package/dist/esm/utils/view-options.js +15 -0
  168. package/dist/esm/utils/webhook-parser.js +56 -0
  169. package/dist/types/authentication.d.ts +262 -0
  170. package/dist/types/clients/activity-client.d.ts +12 -0
  171. package/dist/types/clients/app-client.d.ts +37 -0
  172. package/dist/types/clients/backup-client.d.ts +14 -0
  173. package/dist/types/clients/base-client.d.ts +23 -0
  174. package/dist/types/clients/billing-client.d.ts +22 -0
  175. package/dist/types/clients/comment-client.d.ts +15 -0
  176. package/dist/types/clients/email-client.d.ts +13 -0
  177. package/dist/types/clients/filter-client.d.ts +10 -0
  178. package/dist/types/clients/folder-client.d.ts +16 -0
  179. package/dist/types/clients/id-mapping-client.d.ts +13 -0
  180. package/dist/types/clients/insights-client.d.ts +18 -0
  181. package/dist/types/clients/label-client.d.ts +19 -0
  182. package/dist/types/clients/productivity-client.d.ts +12 -0
  183. package/dist/types/clients/project-client.d.ts +22 -0
  184. package/dist/types/clients/reminder-client.d.ts +25 -0
  185. package/dist/types/clients/section-client.d.ts +18 -0
  186. package/dist/types/clients/task-client.d.ts +25 -0
  187. package/dist/types/clients/template-client.d.ts +17 -0
  188. package/dist/types/clients/ui-extension-client.d.ts +18 -0
  189. package/dist/types/clients/upload-client.d.ts +17 -0
  190. package/dist/types/clients/view-options-client.d.ts +8 -0
  191. package/dist/types/clients/workspace-client.d.ts +43 -0
  192. package/dist/types/consts/endpoints.d.ts +120 -0
  193. package/dist/types/index.d.ts +6 -0
  194. package/dist/types/test-utils/asserts.d.ts +1 -0
  195. package/dist/types/test-utils/msw-setup.d.ts +33 -0
  196. package/dist/types/test-utils/obsidian-fetch-adapter.d.ts +29 -0
  197. package/dist/types/test-utils/test-defaults.d.ts +286 -0
  198. package/dist/types/test-utils/transport-seam.d.ts +1 -0
  199. package/dist/types/test-utils/webhook-fixtures.d.ts +13 -0
  200. package/dist/types/todoist-api.d.ts +1437 -0
  201. package/dist/types/transport/fetch-with-retry.d.ts +12 -0
  202. package/dist/types/transport/http-client.d.ts +25 -0
  203. package/dist/types/transport/http-dispatcher.d.ts +65 -0
  204. package/dist/types/transport/sync-request.d.ts +31 -0
  205. package/dist/types/types/activity/index.d.ts +2 -0
  206. package/dist/types/types/activity/requests.d.ts +85 -0
  207. package/dist/types/types/activity/types.d.ts +56 -0
  208. package/dist/types/types/apps/index.d.ts +2 -0
  209. package/dist/types/types/apps/requests.d.ts +89 -0
  210. package/dist/types/types/apps/types.d.ts +418 -0
  211. package/dist/types/types/backups/index.d.ts +2 -0
  212. package/dist/types/types/backups/requests.d.ts +16 -0
  213. package/dist/types/types/backups/types.d.ts +7 -0
  214. package/dist/types/types/billing/index.d.ts +2 -0
  215. package/dist/types/types/billing/requests.d.ts +62 -0
  216. package/dist/types/types/billing/types.d.ts +207 -0
  217. package/dist/types/types/comments/index.d.ts +2 -0
  218. package/dist/types/types/comments/requests.d.ts +64 -0
  219. package/dist/types/types/comments/types.d.ts +141 -0
  220. package/dist/types/types/common.d.ts +13 -0
  221. package/dist/types/types/emails/index.d.ts +1 -0
  222. package/dist/types/types/emails/requests.d.ts +30 -0
  223. package/dist/types/types/errors.d.ts +29 -0
  224. package/dist/types/types/folders/index.d.ts +1 -0
  225. package/dist/types/types/folders/requests.d.ts +20 -0
  226. package/dist/types/types/http.d.ts +104 -0
  227. package/dist/types/types/id-mappings/index.d.ts +2 -0
  228. package/dist/types/types/id-mappings/requests.d.ts +28 -0
  229. package/dist/types/types/id-mappings/types.d.ts +13 -0
  230. package/dist/types/types/index.d.ts +24 -0
  231. package/dist/types/types/insights/index.d.ts +2 -0
  232. package/dist/types/types/insights/requests.d.ts +26 -0
  233. package/dist/types/types/insights/types.d.ts +167 -0
  234. package/dist/types/types/labels/index.d.ts +2 -0
  235. package/dist/types/types/labels/requests.d.ts +75 -0
  236. package/dist/types/types/labels/types.d.ts +13 -0
  237. package/dist/types/types/productivity/index.d.ts +1 -0
  238. package/dist/types/types/productivity/types.d.ts +115 -0
  239. package/dist/types/types/projects/index.d.ts +2 -0
  240. package/dist/types/types/projects/requests.d.ts +206 -0
  241. package/dist/types/types/projects/types.d.ts +286 -0
  242. package/dist/types/types/reminders/index.d.ts +1 -0
  243. package/dist/types/types/reminders/requests.d.ts +205 -0
  244. package/dist/types/types/sections/index.d.ts +2 -0
  245. package/dist/types/types/sections/requests.d.ts +49 -0
  246. package/dist/types/types/sections/types.d.ts +70 -0
  247. package/dist/types/types/sync/commands/calendars.d.ts +14 -0
  248. package/dist/types/types/sync/commands/filters.d.ts +24 -0
  249. package/dist/types/types/sync/commands/folders.d.ts +20 -0
  250. package/dist/types/types/sync/commands/index.d.ts +167 -0
  251. package/dist/types/types/sync/commands/labels.d.ts +32 -0
  252. package/dist/types/types/sync/commands/notes.d.ts +27 -0
  253. package/dist/types/types/sync/commands/notifications.d.ts +10 -0
  254. package/dist/types/types/sync/commands/others.d.ts +61 -0
  255. package/dist/types/types/sync/commands/project-view-options.d.ts +13 -0
  256. package/dist/types/types/sync/commands/projects.d.ts +96 -0
  257. package/dist/types/types/sync/commands/reminders.d.ts +51 -0
  258. package/dist/types/types/sync/commands/sections.d.ts +36 -0
  259. package/dist/types/types/sync/commands/shared.d.ts +51 -0
  260. package/dist/types/types/sync/commands/sharing.d.ts +16 -0
  261. package/dist/types/types/sync/commands/tasks.d.ts +78 -0
  262. package/dist/types/types/sync/commands/view-options.d.ts +18 -0
  263. package/dist/types/types/sync/commands/workspace-filters.d.ts +25 -0
  264. package/dist/types/types/sync/commands/workspaces.d.ts +82 -0
  265. package/dist/types/types/sync/index.d.ts +6 -0
  266. package/dist/types/types/sync/request.d.ts +7 -0
  267. package/dist/types/types/sync/resource-types.d.ts +5 -0
  268. package/dist/types/types/sync/resources/calendars.d.ts +38 -0
  269. package/dist/types/types/sync/resources/collaborators.d.ts +45 -0
  270. package/dist/types/types/sync/resources/completed-info.d.ts +33 -0
  271. package/dist/types/types/sync/resources/filters.d.ts +13 -0
  272. package/dist/types/types/sync/resources/folders.d.ts +11 -0
  273. package/dist/types/types/sync/resources/index.d.ts +18 -0
  274. package/dist/types/types/sync/resources/labels.d.ts +12 -0
  275. package/dist/types/types/sync/resources/live-notifications.d.ts +32 -0
  276. package/dist/types/types/sync/resources/notes.d.ts +34 -0
  277. package/dist/types/types/sync/resources/reminders.d.ts +213 -0
  278. package/dist/types/types/sync/resources/suggestions.d.ts +96 -0
  279. package/dist/types/types/sync/resources/tooltips.d.ts +6 -0
  280. package/dist/types/types/sync/resources/user-plan-limits.d.ts +47 -0
  281. package/dist/types/types/sync/resources/user-settings.d.ts +40 -0
  282. package/dist/types/types/sync/resources/user-status.d.ts +46 -0
  283. package/dist/types/types/sync/resources/user.d.ts +151 -0
  284. package/dist/types/types/sync/resources/view-options.d.ts +157 -0
  285. package/dist/types/types/sync/resources/workspace-filters.d.ts +18 -0
  286. package/dist/types/types/sync/resources/workspaces.d.ts +142 -0
  287. package/dist/types/types/sync/response.d.ts +930 -0
  288. package/dist/types/types/sync/user-preferences.d.ts +39 -0
  289. package/dist/types/types/tasks/index.d.ts +2 -0
  290. package/dist/types/types/tasks/requests.d.ts +197 -0
  291. package/dist/types/types/tasks/types.d.ts +162 -0
  292. package/dist/types/types/templates/index.d.ts +1 -0
  293. package/dist/types/types/templates/requests.d.ts +92 -0
  294. package/dist/types/types/ui-extensions/index.d.ts +2 -0
  295. package/dist/types/types/ui-extensions/requests.d.ts +108 -0
  296. package/dist/types/types/ui-extensions/types.d.ts +185 -0
  297. package/dist/types/types/uploads/index.d.ts +1 -0
  298. package/dist/types/types/uploads/requests.d.ts +32 -0
  299. package/dist/types/types/users/index.d.ts +1 -0
  300. package/dist/types/types/users/types.d.ts +67 -0
  301. package/dist/types/types/webhooks/comments.d.ts +1600 -0
  302. package/dist/types/types/webhooks/envelope.d.ts +34 -0
  303. package/dist/types/types/webhooks/filters.d.ts +99 -0
  304. package/dist/types/types/webhooks/index.d.ts +9 -0
  305. package/dist/types/types/webhooks/labels.d.ts +160 -0
  306. package/dist/types/types/webhooks/projects.d.ts +365 -0
  307. package/dist/types/types/webhooks/reminders.d.ts +82 -0
  308. package/dist/types/types/webhooks/sections.d.ts +372 -0
  309. package/dist/types/types/webhooks/tasks.d.ts +981 -0
  310. package/dist/types/types/webhooks/types.d.ts +2606 -0
  311. package/dist/types/types/workspaces/index.d.ts +2 -0
  312. package/dist/types/types/workspaces/requests.d.ts +260 -0
  313. package/dist/types/types/workspaces/types.d.ts +266 -0
  314. package/dist/types/utils/activity-helpers.d.ts +28 -0
  315. package/dist/types/utils/case-conversion.d.ts +20 -0
  316. package/dist/types/utils/colors.d.ts +201 -0
  317. package/dist/types/utils/file-response.d.ts +15 -0
  318. package/dist/types/utils/filter-queries.d.ts +42 -0
  319. package/dist/types/utils/filter-query-definitions.d.ts +27 -0
  320. package/dist/types/utils/headers.d.ts +20 -0
  321. package/dist/types/utils/index.d.ts +15 -0
  322. package/dist/types/utils/multipart-upload.d.ts +58 -0
  323. package/dist/types/utils/person-names.d.ts +52 -0
  324. package/dist/types/utils/processing-helpers.d.ts +1 -0
  325. package/dist/types/utils/project-helpers.d.ts +21 -0
  326. package/dist/types/utils/request-helpers.d.ts +33 -0
  327. package/dist/types/utils/sanitization.d.ts +52 -0
  328. package/dist/types/utils/sync-helpers.d.ts +17 -0
  329. package/dist/types/utils/task-sorting.d.ts +46 -0
  330. package/dist/types/utils/uncompletable-helpers.d.ts +30 -0
  331. package/dist/types/utils/url-helpers.d.ts +120 -0
  332. package/dist/types/utils/validators.d.ts +1917 -0
  333. package/dist/types/utils/view-options.d.ts +11 -0
  334. package/dist/types/utils/webhook-parser.d.ts +48 -0
  335. package/package.json +87 -8
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Doist
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,45 +1,309 @@
1
- # @todoist/sdk
1
+ # Todoist SDK
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ The official TypeScript SDK for the Todoist REST API.
4
4
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
5
+ ## Installation
6
6
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
7
+ Requires Node 20.18.1+.
8
8
 
9
- ## Purpose
9
+ ```
10
+ npm install @todoist/sdk
11
+ ```
10
12
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@todoist/sdk`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
13
+ Previously published as `@doist/todoist-sdk`.
15
14
 
16
- ## What is OIDC Trusted Publishing?
15
+ ### Usage
17
16
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
17
+ An example of initializing the API client and fetching a user's tasks:
19
18
 
20
- ## Setup Instructions
19
+ ```typescript
20
+ import { TodoistApi } from '@todoist/sdk'
21
21
 
22
- To properly configure OIDC trusted publishing for this package:
22
+ const api = new TodoistApi('YOURTOKEN')
23
23
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
24
+ api.getTasks()
25
+ .then((tasks) => console.log(tasks))
26
+ .catch((error) => console.log(error))
27
+ ```
28
28
 
29
- ## DO NOT USE THIS PACKAGE
29
+ ### Documentation
30
30
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
31
+ For more detailed reference documentation, have a look at the [Todoist API v1 Documentation](https://todoist.com/api/v1/docs).
36
32
 
37
- ## More Information
33
+ ### Migration Guide
38
34
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
35
+ If you're migrating from an older version of the Todoist API (v9), please refer to the [official migration guide](https://todoist.com/api/v1/docs#tag/Migrating-from-v9) for detailed information about the changes and breaking updates.
42
36
 
43
- ---
37
+ Key changes in v1 include:
44
38
 
45
- **Maintained for OIDC setup purposes only**
39
+ - Updated endpoint structure
40
+ - New pagination system
41
+ - Unified error response format
42
+ - Object renames (e.g., items → tasks, notes → comments)
43
+ - URL renames and endpoint signature changes
44
+
45
+ ## Custom Headers
46
+
47
+ Pass `headers` to send extra headers with every API request, for example to tell the backend which client is calling:
48
+
49
+ ```typescript
50
+ const api = new TodoistApi('YOURTOKEN', {
51
+ headers: { 'Doist-Platform': 'cli' },
52
+ })
53
+ ```
54
+
55
+ For values that change between requests, pass a function instead. The SDK calls it once per request, and a retried request reuses its result:
56
+
57
+ ```typescript
58
+ import { randomUUID } from 'node:crypto'
59
+
60
+ const api = new TodoistApi('YOURTOKEN', {
61
+ headers: () => ({ 'Doist-Platform': 'cli', 'Request-Id': randomUUID() }),
62
+ })
63
+ ```
64
+
65
+ These headers cannot replace `Authorization`, `X-Request-Id` or the multipart `Content-Type`; the SDK's own values always win. They are not sent on attachment downloads (`viewAttachment`), which redirect to a third-party CDN. The OAuth helpers (`getAuthToken`, `refreshAuthToken`, `revokeToken`, …) take their own options and do not send them.
66
+
67
+ ## Custom HTTP Clients
68
+
69
+ The Todoist API client supports custom HTTP implementations to enable usage in environments with specific networking requirements, such as:
70
+
71
+ - **Obsidian plugins** - Desktop app with strict CORS policies
72
+ - **Browser extensions** - Custom HTTP APIs with different security models
73
+ - **Electron apps** - Requests routed through IPC layer
74
+ - **React Native** - Different networking stack
75
+ - **Enterprise environments** - Proxy configuration, custom headers, or certificate handling
76
+
77
+ ### Basic Usage
78
+
79
+ ```typescript
80
+ import { TodoistApi } from '@todoist/sdk'
81
+
82
+ // Using the new options-based constructor
83
+ const api = new TodoistApi('YOURTOKEN', {
84
+ baseUrl: 'https://custom-api.example.com', // optional
85
+ customFetch: myCustomFetch, // your custom fetch implementation
86
+ })
87
+
88
+ // Legacy constructor (deprecated but supported)
89
+ const apiLegacy = new TodoistApi('YOURTOKEN', 'https://custom-api.example.com')
90
+ ```
91
+
92
+ ### Custom Fetch Interface
93
+
94
+ Your custom fetch function must implement this interface:
95
+
96
+ ```typescript
97
+ type CustomFetch = (
98
+ url: string,
99
+ options?: RequestInit & { timeout?: number },
100
+ ) => Promise<CustomFetchResponse>
101
+
102
+ type CustomFetchResponse = {
103
+ ok: boolean
104
+ status: number
105
+ statusText: string
106
+ headers: Record<string, string>
107
+ text(): Promise<string>
108
+ json(): Promise<unknown>
109
+ }
110
+ ```
111
+
112
+ ### OAuth with Custom Fetch
113
+
114
+ OAuth authentication functions (`getAuthToken`, `revokeAuthToken`, `revokeToken`) support custom fetch through an options object:
115
+
116
+ ```typescript
117
+ // New options-based usage
118
+ const { accessToken } = await getAuthToken(args, {
119
+ baseUrl: 'https://custom-auth.example.com',
120
+ customFetch: myCustomFetch,
121
+ })
122
+
123
+ await revokeToken(args, {
124
+ customFetch: myCustomFetch,
125
+ })
126
+
127
+ // Legacy usage (deprecated)
128
+ const { accessToken } = await getAuthToken(args, baseUrl)
129
+ ```
130
+
131
+ When the authorization server issues a `refreshToken`, use `refreshAuthToken`
132
+ to obtain a new access token once the current one expires, without sending the
133
+ user back through the authorization flow:
134
+
135
+ ```typescript
136
+ const refreshed = await refreshAuthToken({
137
+ clientId: 'your-client-id',
138
+ clientSecret: 'your-client-secret',
139
+ refreshToken: storedRefreshToken,
140
+ })
141
+
142
+ // The server may rotate the refresh token — persist refreshed.refreshToken
143
+ // when present, otherwise keep using the previous one.
144
+ ```
145
+
146
+ > **Note:** Refresh tokens are only issued to OAuth apps that have them enabled
147
+ > (the default for new apps). Apps without them receive a long-lived access
148
+ > token, so `getAuthToken` returns no `refreshToken` and there is nothing to
149
+ > refresh. For public clients (`tokenEndpointAuthMethod: 'none'`), omit
150
+ > `clientSecret` when calling `refreshAuthToken`.
151
+
152
+ ### Keeping Proxy Support and Response Decompression
153
+
154
+ On Node, the SDK's default transport reads the proxy environment variables (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) and decodes compressed response bodies. Supplying a `customFetch` replaces that transport, so a custom implementation that still wants both can borrow it with `getDefaultTransport`:
155
+
156
+ ```typescript
157
+ import { type CustomFetch, getDefaultTransport, TodoistApi } from '@todoist/sdk'
158
+
159
+ const customFetch: CustomFetch = async (url, options) => {
160
+ const transport = await getDefaultTransport()
161
+ // undici's `fetch` and the global one are the same call at runtime but
162
+ // carry different types, so settle on one signature.
163
+ const fetchImpl = (transport?.fetch ?? fetch) as typeof fetch
164
+
165
+ const response = await fetchImpl(url, {
166
+ ...options,
167
+ headers: {
168
+ ...(options?.headers as Record<string, string> | undefined),
169
+ 'x-my-header': 'value',
170
+ },
171
+ // `dispatcher` is a Node fetch option that the DOM types don't declare.
172
+ dispatcher: transport?.dispatcher,
173
+ } as RequestInit)
174
+
175
+ // `CustomFetchResponse` wants plain-object headers, not a `Headers`.
176
+ const headers: Record<string, string> = {}
177
+ response.headers.forEach((value, key) => {
178
+ headers[key] = value
179
+ })
180
+
181
+ return {
182
+ ok: response.ok,
183
+ status: response.status,
184
+ statusText: response.statusText,
185
+ headers,
186
+ text: () => response.text(),
187
+ json: () => response.json(),
188
+ arrayBuffer: () => response.arrayBuffer(),
189
+ }
190
+ }
191
+
192
+ const api = new TodoistApi('YOURTOKEN', { customFetch })
193
+ ```
194
+
195
+ `getDefaultTransport` returns the dispatcher and the `fetch` it must be used with as a single value, and both halves have to be used together. The dispatcher decompresses the response body itself, so pairing it with a `fetch` from a different undici build — including the runtime's global `fetch` on Node 26 — decodes the body twice and the request fails mid-stream with `terminated`. A `fetch` of `undefined` means the global `fetch` is the correct partner; the whole value is `undefined` outside Node, where no dispatcher applies.
196
+
197
+ ### Important Notes
198
+
199
+ - All existing transforms (snake_case ↔ camelCase) work automatically with custom fetch
200
+ - Retry logic and error handling are preserved
201
+ - File uploads work with custom fetch implementations
202
+ - File upload bodies are a `Blob`, or a `ReadableStream` when uploading from a stream — a custom fetch must pass them through unchanged
203
+ - Timeout parameter is optional and up to your custom implementation
204
+
205
+ ## Filter Queries
206
+
207
+ Use `escapeFilterToken` for user-provided search text, handling validation and trimming in your code. Pass complete filter queries directly to `getTasksByFilter`.
208
+
209
+ ```typescript
210
+ await api.getTasksByFilter({
211
+ query: `search: ${escapeFilterToken(searchText)}`,
212
+ })
213
+ ```
214
+
215
+ ## Development and Testing
216
+
217
+ Instead of having an example app in the repository to assist development and testing, we have included [ts-node](https://github.com/TypeStrong/ts-node) as a dev dependency. This allows us to have a scratch file locally that can import and utilize the API while developing or reviewing pull requests without having to manage a separate app project.
218
+
219
+ - `npm install`
220
+ - Add a file named `scratch.ts` in the `src` folder.
221
+ - Configure your IDE to run the scratch file with `ts-node` (instructions for [VSCode](https://medium.com/@dupski/debug-typescript-in-vs-code-without-compiling-using-ts-node-9d1f4f9a94a), [WebStorm](https://www.jetbrains.com/help/webstorm/running-and-debugging-typescript.html#ws_ts_run_debug_server_side_ts_node)), or you can optionally run ts-node in a terminal using instructions [here](https://github.com/TypeStrong/ts-node) (`npx ts-node ./src/scratch.ts` should be enough).
222
+ - Import and call the relevant modules and run the scratch file.
223
+
224
+ Example scratch.ts file:
225
+
226
+ ```
227
+ /* eslint-disable no-console */
228
+ import { TodoistApi } from './todoist-api'
229
+
230
+ const token = 'YOURTOKEN'
231
+ const api = new TodoistApi(token)
232
+
233
+ api.getProjects()
234
+ .then((projects) => {
235
+ console.log(projects)
236
+ })
237
+ .catch((error) => console.error(error))
238
+ ```
239
+
240
+ ### Local API Requests With .env
241
+
242
+ For live API verification, you can run raw requests with a local token:
243
+
244
+ 1. Copy `.env.example` to `.env`.
245
+ 2. Set `TODOIST_API_TOKEN` in `.env`.
246
+ 3. Run requests with `npm run api:request -- ...`.
247
+ 4. Optional: set `TODOIST_API_BASE_URL` in `.env` (defaults to `https://api.todoist.com`).
248
+
249
+ Examples:
250
+
251
+ ```bash
252
+ npm run api:request -- --path /api/v1/tasks
253
+ npm run api:request -- --method POST --path /api/v1/tasks --body '{"content":"API smoke test"}'
254
+ npm run api:request -- --method POST --path /api/v1/tasks/123 --body '{"due_string":"no date"}'
255
+ npm run api:request -- --path /api/v1/tasks --query '{"project_id":"123","limit":10}'
256
+ ```
257
+
258
+ To see all options:
259
+
260
+ ```bash
261
+ npm run api:request -- --help
262
+ ```
263
+
264
+ ## Releases
265
+
266
+ This project uses [Release Please](https://github.com/googleapis/release-please) to automate releases. Releases are created automatically based on [Conventional Commits](https://www.conventionalcommits.org/).
267
+
268
+ ### For Contributors
269
+
270
+ When making changes, use conventional commit messages:
271
+
272
+ - `feat:` - New features (triggers a minor version bump)
273
+ - `fix:` - Bug fixes (triggers a patch version bump)
274
+ - `feat!:` or `BREAKING CHANGE:` - Breaking changes (triggers a major version bump)
275
+ - `chore:`, `docs:`, `refactor:`, `perf:` - Other changes (included in changelog)
276
+
277
+ Example:
278
+
279
+ ```
280
+ feat: add support for recurring tasks
281
+ fix: resolve issue with date parsing
282
+ feat!: remove deprecated getTask method
283
+ ```
284
+
285
+ ### For Maintainers
286
+
287
+ The release process is fully automated:
288
+
289
+ 1. **Automatic PR Creation**: When commits are merged to `main`, Release Please automatically creates or updates a release PR with:
290
+ - Updated version in `package.json`
291
+ - Updated `CHANGELOG.md`
292
+ - Aggregated changes since the last release
293
+
294
+ 2. **Review and Merge**: Review the release PR to ensure the version bump and changelog are correct, then merge it.
295
+
296
+ 3. **Automatic Release**: Upon merging the release PR:
297
+ - A GitHub release is automatically created with the new version tag
298
+ - The `publish.yml` workflow is triggered by the tag
299
+ - The package is automatically published to NPM
300
+
301
+ Users of the API client can then update to the new version in their `package.json`.
302
+
303
+ ### Feedback
304
+
305
+ Any feedback, such as bugs, questions, comments, etc. can be reported as _Issues_ in this repository, and will be handled by us in Todoist.
306
+
307
+ ### Contributions
308
+
309
+ We would also love contributions in the form of _Pull requests_ in this repository.
@@ -0,0 +1,307 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { v4 as uuid } from 'uuid';
13
+ import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, ENDPOINT_REGISTER, ENDPOINT_REST_ACCESS_TOKENS_MIGRATE, } from './consts/endpoints.js';
14
+ import { request, isSuccess } from './transport/http-client.js';
15
+ import { TodoistRequestError } from './types/index.js';
16
+ /** Available OAuth2 permission scopes. */
17
+ export const PERMISSIONS = [
18
+ 'task:add',
19
+ 'data:read',
20
+ 'data:read_write',
21
+ 'data:delete',
22
+ 'project:delete',
23
+ 'backups:read',
24
+ 'billing:read',
25
+ 'billing:read_write',
26
+ 'dev:app_console',
27
+ ];
28
+ /** Supported token endpoint authentication methods for dynamic client registration. */
29
+ export const TOKEN_ENDPOINT_AUTH_METHODS = [
30
+ 'client_secret_post',
31
+ 'client_secret_basic',
32
+ 'none',
33
+ ];
34
+ /**
35
+ * Creates a Basic Authentication header value from client credentials.
36
+ * @param clientId - The OAuth client ID
37
+ * @param clientSecret - The OAuth client secret
38
+ * @returns The Basic Auth header value (without the 'Basic ' prefix)
39
+ */
40
+ function createBasicAuthHeader(clientId, clientSecret) {
41
+ const credentials = `${clientId}:${clientSecret}`;
42
+ return Buffer.from(credentials).toString('base64');
43
+ }
44
+ /**
45
+ * Generates a random state parameter for OAuth2 authorization.
46
+ * The state parameter helps prevent CSRF attacks.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const state = getAuthStateParameter()
51
+ * // Store state in session
52
+ * const authUrl = getAuthorizationUrl(clientId, ['data:read'], state)
53
+ * ```
54
+ *
55
+ * @returns A random UUID v4 string
56
+ */
57
+ export function getAuthStateParameter() {
58
+ return uuid();
59
+ }
60
+ /**
61
+ * Generates the authorization URL for the OAuth2 flow.
62
+ *
63
+ * The `clientId` can be either a traditional client ID string (e.g. from
64
+ * {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
65
+ * as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const url = getAuthorizationUrl({
70
+ * clientId: 'your-client-id',
71
+ * permissions: ['data:read', 'task:add'],
72
+ * state,
73
+ * })
74
+ * // Redirect user to url
75
+ * ```
76
+ *
77
+ * @returns The full authorization URL to redirect users to
78
+ * @see https://developer.todoist.com/api/v1/#tag/Authorization/OAuth
79
+ */
80
+ export function getAuthorizationUrl({ clientId, permissions, state, baseUrl, }) {
81
+ if (!(permissions === null || permissions === void 0 ? void 0 : permissions.length)) {
82
+ throw new Error('At least one scope value should be passed for permissions.');
83
+ }
84
+ const scope = permissions.join(',');
85
+ return `${getAuthBaseUri(baseUrl)}${ENDPOINT_AUTHORIZATION}?client_id=${encodeURIComponent(clientId)}&scope=${scope}&state=${state}`;
86
+ }
87
+ /**
88
+ * Exchanges an authorization code for an access token.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const { accessToken } = await getAuthToken({
93
+ * clientId: 'your-client-id',
94
+ * clientSecret: 'your-client-secret',
95
+ * code: authCode
96
+ * })
97
+ * ```
98
+ *
99
+ * @returns The access token response
100
+ * @throws {@link TodoistRequestError} If the token exchange fails
101
+ */
102
+ /**
103
+ * Posts a payload to the OAuth token endpoint and returns the token response,
104
+ * mapping any failure to a {@link TodoistRequestError} with `errorMessage`.
105
+ * Shared by {@link getAuthToken} and {@link refreshAuthToken}.
106
+ */
107
+ async function requestAuthToken(payload, errorMessage, options) {
108
+ var _a;
109
+ try {
110
+ const response = await request({
111
+ httpMethod: 'POST',
112
+ baseUri: getAuthBaseUri(options === null || options === void 0 ? void 0 : options.baseUrl),
113
+ relativePath: ENDPOINT_GET_TOKEN,
114
+ apiToken: undefined,
115
+ payload,
116
+ customFetch: options === null || options === void 0 ? void 0 : options.customFetch,
117
+ });
118
+ if (response.status !== 200 || !((_a = response.data) === null || _a === void 0 ? void 0 : _a.accessToken)) {
119
+ throw new TodoistRequestError(errorMessage, response.status, response.data);
120
+ }
121
+ return response.data;
122
+ }
123
+ catch (error) {
124
+ // Re-throw with custom message for authentication failures
125
+ const err = error;
126
+ throw new TodoistRequestError(errorMessage, err.httpStatusCode, err.responseData);
127
+ }
128
+ }
129
+ export async function getAuthToken(args, options) {
130
+ if (typeof options === 'string') {
131
+ throw new TypeError('Passing baseUrl as a string is no longer supported. Use an options object instead: getAuthToken(args, { baseUrl })');
132
+ }
133
+ return requestAuthToken(Object.assign({}, args), 'Authentication token exchange failed.', options);
134
+ }
135
+ /**
136
+ * Exchanges a refresh token for a new access token using the OAuth2
137
+ * `refresh_token` grant.
138
+ *
139
+ * Only relevant for OAuth apps that have refresh tokens enabled (the default for
140
+ * new apps). Apps without them never receive a `refreshToken` from
141
+ * {@link getAuthToken}, so they have nothing to pass here — their access tokens
142
+ * are long-lived instead.
143
+ *
144
+ * Omit `clientSecret` for public clients registered with
145
+ * `tokenEndpointAuthMethod: 'none'`.
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const { accessToken, refreshToken } = await refreshAuthToken({
150
+ * clientId: 'your-client-id',
151
+ * clientSecret: 'your-client-secret',
152
+ * refreshToken: storedRefreshToken,
153
+ * })
154
+ * ```
155
+ *
156
+ * @returns The refreshed token. The server rotates the refresh token, so the
157
+ * response carries a new `refreshToken` — persist it in place of the old one.
158
+ * @throws {@link TodoistRequestError} If the refresh fails
159
+ */
160
+ export async function refreshAuthToken(args, options) {
161
+ const payload = {
162
+ clientId: args.clientId,
163
+ refreshToken: args.refreshToken,
164
+ grantType: 'refresh_token',
165
+ };
166
+ if (args.clientSecret !== undefined) {
167
+ payload.clientSecret = args.clientSecret;
168
+ }
169
+ return requestAuthToken(payload, 'Authentication token refresh failed.', options);
170
+ }
171
+ /**
172
+ * Revokes a token using the RFC 7009 OAuth 2.0 Token Revocation standard.
173
+ *
174
+ * This function uses HTTP Basic Authentication with client credentials and follows
175
+ * the RFC 7009 specification for token revocation.
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * await revokeToken({
180
+ * clientId: 'your-client-id',
181
+ * clientSecret: 'your-client-secret',
182
+ * token: 'access-token-to-revoke'
183
+ * })
184
+ * ```
185
+ *
186
+ * @returns True if revocation was successful
187
+ * @see https://datatracker.ietf.org/doc/html/rfc7009
188
+ * @see https://developer.todoist.com/api/v1/#tag/Authorization
189
+ */
190
+ export async function revokeToken(args, options) {
191
+ if (typeof options === 'string') {
192
+ throw new TypeError('Passing baseUrl as a string is no longer supported. Use an options object instead: revokeToken(args, { baseUrl })');
193
+ }
194
+ const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
195
+ const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
196
+ const { clientId, clientSecret, token } = args;
197
+ // Create Basic Auth header as per RFC 7009
198
+ const basicAuth = createBasicAuthHeader(clientId, clientSecret);
199
+ const customHeaders = {
200
+ Authorization: `Basic ${basicAuth}`,
201
+ };
202
+ // Request body only contains the token and optional token_type_hint
203
+ const requestBody = {
204
+ token,
205
+ token_type_hint: 'access_token',
206
+ };
207
+ const response = await request({
208
+ httpMethod: 'POST',
209
+ baseUri: getSyncBaseUri(baseUrl),
210
+ relativePath: ENDPOINT_REVOKE,
211
+ apiToken: undefined,
212
+ payload: requestBody,
213
+ requestId: undefined,
214
+ hasSyncCommands: false,
215
+ customHeaders: customHeaders,
216
+ customFetch,
217
+ });
218
+ return isSuccess(response);
219
+ }
220
+ /**
221
+ * Migrates a personal API token to an OAuth access token.
222
+ *
223
+ * This allows applications to transition users from personal API tokens
224
+ * to proper OAuth tokens without requiring the user to go through the
225
+ * full OAuth authorization flow.
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * const { accessToken } = await migratePersonalToken({
230
+ * clientId: 'your-client-id',
231
+ * clientSecret: 'your-client-secret',
232
+ * personalToken: 'user-personal-token',
233
+ * scope: 'data:read_write,data:delete'
234
+ * })
235
+ * ```
236
+ *
237
+ * @returns The new OAuth token response
238
+ * @throws {@link TodoistRequestError} If the migration fails
239
+ */
240
+ export async function migratePersonalToken(args, options) {
241
+ var _a;
242
+ const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
243
+ const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
244
+ try {
245
+ const response = await request({
246
+ httpMethod: 'POST',
247
+ baseUri: getSyncBaseUri(baseUrl),
248
+ relativePath: ENDPOINT_REST_ACCESS_TOKENS_MIGRATE,
249
+ apiToken: undefined,
250
+ payload: Object.assign(Object.assign({}, args), { scope: args.scope.join(',') }),
251
+ customFetch,
252
+ });
253
+ if (response.status !== 200 || !((_a = response.data) === null || _a === void 0 ? void 0 : _a.accessToken)) {
254
+ throw new TodoistRequestError('Personal token migration failed.', response.status, response.data);
255
+ }
256
+ return response.data;
257
+ }
258
+ catch (error) {
259
+ const err = error;
260
+ throw new TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
261
+ }
262
+ }
263
+ /**
264
+ * Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * const client = await registerClient({
269
+ * redirectUris: ['https://example.com/callback'],
270
+ * clientName: 'My App',
271
+ * scope: ['data:read_write', 'task:add'],
272
+ * })
273
+ * // Use client.clientId and client.clientSecret for OAuth flows
274
+ * ```
275
+ *
276
+ * @returns The registered client details
277
+ * @throws {@link TodoistRequestError} If the registration fails
278
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
279
+ */
280
+ export async function registerClient(args, options) {
281
+ var _a, _b;
282
+ const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
283
+ const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
284
+ try {
285
+ const response = await request({
286
+ httpMethod: 'POST',
287
+ baseUri: getAuthBaseUri(baseUrl),
288
+ relativePath: ENDPOINT_REGISTER,
289
+ apiToken: undefined,
290
+ payload: Object.assign(Object.assign({}, args), { scope: (_a = args.scope) === null || _a === void 0 ? void 0 : _a.join(' ') }),
291
+ customFetch,
292
+ });
293
+ if (!isSuccess(response) || !((_b = response.data) === null || _b === void 0 ? void 0 : _b.clientId)) {
294
+ throw new TodoistRequestError('Dynamic client registration failed.', response.status, response.data);
295
+ }
296
+ const _c = response.data, { clientIdIssuedAt, clientSecretExpiresAt, scope } = _c, rest = __rest(_c, ["clientIdIssuedAt", "clientSecretExpiresAt", "scope"]);
297
+ return Object.assign(Object.assign({}, rest), { scope: scope ? scope.split(' ') : undefined, clientIdIssuedAt: clientIdIssuedAt !== undefined ? new Date(clientIdIssuedAt * 1000) : undefined, clientSecretExpiresAt: clientSecretExpiresAt === undefined
298
+ ? undefined
299
+ : clientSecretExpiresAt === 0
300
+ ? null
301
+ : new Date(clientSecretExpiresAt * 1000) });
302
+ }
303
+ catch (error) {
304
+ const err = error;
305
+ throw new TodoistRequestError('Dynamic client registration failed.', err.httpStatusCode, err.responseData);
306
+ }
307
+ }