@doist/todoist-sdk 9.1.0-next.2 → 9.1.1

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 (70) hide show
  1. package/dist/cjs/authentication.js +1 -0
  2. package/dist/cjs/clients/app-client.js +347 -0
  3. package/dist/cjs/clients/base-client.js +1 -0
  4. package/dist/cjs/clients/ui-extension-client.js +109 -0
  5. package/dist/cjs/consts/endpoints.js +70 -6
  6. package/dist/cjs/test-utils/test-defaults.js +75 -23
  7. package/dist/cjs/todoist-api.js +269 -33
  8. package/dist/cjs/transport/http-client.js +1 -0
  9. package/dist/cjs/types/apps/types.js +253 -0
  10. package/dist/cjs/types/index.js +2 -1
  11. package/dist/cjs/types/sync/commands/index.js +0 -1
  12. package/dist/cjs/types/sync/resource-types.js +0 -1
  13. package/dist/cjs/types/sync/response.js +10 -12
  14. package/dist/cjs/types/ui-extensions/index.js +18 -0
  15. package/dist/cjs/types/ui-extensions/types.js +77 -0
  16. package/dist/cjs/utils/validators.js +45 -33
  17. package/dist/esm/authentication.js +1 -0
  18. package/dist/esm/clients/app-client.js +343 -0
  19. package/dist/esm/clients/base-client.js +1 -0
  20. package/dist/esm/clients/ui-extension-client.js +105 -0
  21. package/dist/esm/consts/endpoints.js +54 -5
  22. package/dist/esm/test-utils/test-defaults.js +73 -22
  23. package/dist/esm/todoist-api.js +269 -33
  24. package/dist/esm/transport/http-client.js +1 -0
  25. package/dist/esm/types/apps/types.js +248 -0
  26. package/dist/esm/types/index.js +2 -1
  27. package/dist/esm/types/sync/commands/index.js +0 -1
  28. package/dist/esm/types/sync/resource-types.js +0 -1
  29. package/dist/esm/types/sync/response.js +0 -2
  30. package/dist/esm/types/ui-extensions/types.js +74 -0
  31. package/dist/esm/utils/validators.js +14 -2
  32. package/dist/types/authentication.d.ts +1 -1
  33. package/dist/types/clients/app-client.d.ts +37 -0
  34. package/dist/types/clients/base-client.d.ts +1 -0
  35. package/dist/types/clients/ui-extension-client.d.ts +18 -0
  36. package/dist/types/consts/endpoints.d.ts +25 -5
  37. package/dist/types/test-utils/test-defaults.d.ts +16 -4
  38. package/dist/types/todoist-api.d.ts +202 -12
  39. package/dist/types/types/apps/index.d.ts +2 -0
  40. package/dist/types/types/apps/requests.d.ts +89 -0
  41. package/dist/types/types/apps/types.d.ts +414 -0
  42. package/dist/types/types/http.d.ts +1 -1
  43. package/dist/types/types/index.d.ts +2 -1
  44. package/dist/types/types/sync/commands/index.d.ts +0 -9
  45. package/dist/types/types/sync/resource-types.d.ts +1 -1
  46. package/dist/types/types/sync/resources/user.d.ts +2 -2
  47. package/dist/types/types/sync/resources/view-options.d.ts +6 -6
  48. package/dist/types/types/sync/response.d.ts +6 -31
  49. package/dist/types/types/sync/user-preferences.d.ts +1 -1
  50. package/dist/types/types/tasks/requests.d.ts +0 -1
  51. package/dist/types/types/ui-extensions/index.d.ts +2 -0
  52. package/dist/types/types/ui-extensions/requests.d.ts +108 -0
  53. package/dist/types/types/ui-extensions/types.d.ts +185 -0
  54. package/dist/types/utils/validators.d.ts +231 -55
  55. package/package.json +1 -1
  56. package/dist/cjs/clients/goals-client.js +0 -145
  57. package/dist/cjs/types/goals/types.js +0 -56
  58. package/dist/esm/clients/goals-client.js +0 -141
  59. package/dist/esm/types/goals/types.js +0 -53
  60. package/dist/types/clients/goals-client.d.ts +0 -20
  61. package/dist/types/types/goals/requests.d.ts +0 -33
  62. package/dist/types/types/goals/types.d.ts +0 -51
  63. package/dist/types/types/sync/commands/goals.d.ts +0 -33
  64. /package/dist/cjs/types/{goals → apps}/index.js +0 -0
  65. /package/dist/cjs/types/{goals → apps}/requests.js +0 -0
  66. /package/dist/cjs/types/{sync/commands/goals.js → ui-extensions/requests.js} +0 -0
  67. /package/dist/esm/types/{goals → apps}/index.js +0 -0
  68. /package/dist/esm/types/{goals → apps}/requests.js +0 -0
  69. /package/dist/{types/types/goals/index.d.ts → esm/types/ui-extensions/index.js} +0 -0
  70. /package/dist/esm/types/{sync/commands/goals.js → ui-extensions/requests.js} +0 -0
@@ -1,9 +1,9 @@
1
1
  import { ActivityClient } from './clients/activity-client.js';
2
+ import { AppClient } from './clients/app-client.js';
2
3
  import { BackupClient } from './clients/backup-client.js';
3
4
  import { CommentClient } from './clients/comment-client.js';
4
5
  import { EmailClient } from './clients/email-client.js';
5
6
  import { FolderClient } from './clients/folder-client.js';
6
- import { GoalsClient } from './clients/goals-client.js';
7
7
  import { IdMappingClient } from './clients/id-mapping-client.js';
8
8
  import { InsightsClient } from './clients/insights-client.js';
9
9
  import { LabelClient } from './clients/label-client.js';
@@ -13,6 +13,7 @@ import { ReminderClient } from './clients/reminder-client.js';
13
13
  import { SectionClient } from './clients/section-client.js';
14
14
  import { TaskClient } from './clients/task-client.js';
15
15
  import { TemplateClient } from './clients/template-client.js';
16
+ import { UiExtensionClient } from './clients/ui-extension-client.js';
16
17
  import { UploadClient } from './clients/upload-client.js';
17
18
  import { WorkspaceClient } from './clients/workspace-client.js';
18
19
  import { ENDPOINT_REST_USER, getSyncBaseUri } from './consts/endpoints.js';
@@ -57,7 +58,8 @@ export class TodoistApi {
57
58
  this.activityClient = new ActivityClient(clientDeps);
58
59
  this.productivityClient = new ProductivityClient(clientDeps);
59
60
  this.workspaceClient = new WorkspaceClient(clientDeps);
60
- this.goalsClient = new GoalsClient(clientDeps);
61
+ this.appClient = new AppClient(clientDeps);
62
+ this.uiExtensionClient = new UiExtensionClient(clientDeps);
61
63
  }
62
64
  /**
63
65
  * Executes a raw Sync API request.
@@ -937,37 +939,6 @@ export class TodoistApi {
937
939
  async deleteFolder(id, requestId) {
938
940
  return this.folderClient.deleteFolder(id, requestId);
939
941
  }
940
- // ── Goals ──
941
- async getGoals(args) {
942
- return this.goalsClient.getGoals(args);
943
- }
944
- async searchGoals(args) {
945
- return this.goalsClient.searchGoals(args);
946
- }
947
- async getGoal(id) {
948
- return this.goalsClient.getGoal(id);
949
- }
950
- async addGoal(args, requestId) {
951
- return this.goalsClient.addGoal(args, requestId);
952
- }
953
- async updateGoal(id, args, requestId) {
954
- return this.goalsClient.updateGoal(id, args, requestId);
955
- }
956
- async deleteGoal(id, requestId) {
957
- return this.goalsClient.deleteGoal(id, requestId);
958
- }
959
- async completeGoal(id, requestId) {
960
- return this.goalsClient.completeGoal(id, requestId);
961
- }
962
- async uncompleteGoal(id, requestId) {
963
- return this.goalsClient.uncompleteGoal(id, requestId);
964
- }
965
- async linkTaskToGoal(args, requestId) {
966
- return this.goalsClient.linkTaskToGoal(args, requestId);
967
- }
968
- async unlinkTaskFromGoal(args, requestId) {
969
- return this.goalsClient.unlinkTaskFromGoal(args, requestId);
970
- }
971
942
  // ── Backups ──
972
943
  /**
973
944
  * Retrieves a list of available backups.
@@ -1294,4 +1265,269 @@ export class TodoistApi {
1294
1265
  async getWorkspaceArchivedProjects(args, requestId) {
1295
1266
  return this.workspaceClient.getWorkspaceArchivedProjects(args, requestId);
1296
1267
  }
1268
+ // ---------------------------------------------------------------------------
1269
+ // App management (dev:app_console scope)
1270
+ // ---------------------------------------------------------------------------
1271
+ /**
1272
+ * Lists all developer applications owned by the authenticated user.
1273
+ *
1274
+ * Requires the `dev:app_console` scope.
1275
+ *
1276
+ * @param requestId - Optional request ID for idempotency.
1277
+ * @returns A promise that resolves to the list of apps.
1278
+ */
1279
+ async getApps(requestId) {
1280
+ return this.appClient.getApps(requestId);
1281
+ }
1282
+ /**
1283
+ * Retrieves a single developer application by ID.
1284
+ *
1285
+ * Requires the `dev:app_console` scope.
1286
+ */
1287
+ async getApp(appId, requestId) {
1288
+ return this.appClient.getApp(appId, requestId);
1289
+ }
1290
+ /**
1291
+ * Creates a new developer application.
1292
+ *
1293
+ * Requires the `dev:app_console` scope.
1294
+ */
1295
+ async addApp(args, requestId) {
1296
+ return this.appClient.addApp(args, requestId);
1297
+ }
1298
+ /**
1299
+ * Updates a developer application.
1300
+ *
1301
+ * Requires the `dev:app_console` scope.
1302
+ */
1303
+ async updateApp(appId, args, requestId) {
1304
+ return this.appClient.updateApp(appId, args, requestId);
1305
+ }
1306
+ /**
1307
+ * Deletes a developer application.
1308
+ *
1309
+ * Requires the `dev:app_console` scope.
1310
+ */
1311
+ async deleteApp(appId, requestId) {
1312
+ return this.appClient.deleteApp(appId, requestId);
1313
+ }
1314
+ /**
1315
+ * Retrieves the OAuth client credentials (client ID and secret) for an app.
1316
+ *
1317
+ * Requires the `dev:app_console` scope.
1318
+ */
1319
+ async getAppSecrets(appId, requestId) {
1320
+ return this.appClient.getAppSecrets(appId, requestId);
1321
+ }
1322
+ /**
1323
+ * Rotates the app's OAuth client secret, returning the updated app record.
1324
+ *
1325
+ * Requires the `dev:app_console` scope.
1326
+ */
1327
+ async resetAppClientSecret(appId, requestId) {
1328
+ return this.appClient.resetAppClientSecret(appId, requestId);
1329
+ }
1330
+ /**
1331
+ * Revokes every access token issued for the given app.
1332
+ *
1333
+ * Requires the `dev:app_console` scope.
1334
+ */
1335
+ async revokeAppTokens(appId, requestId) {
1336
+ return this.appClient.revokeAppTokens(appId, requestId);
1337
+ }
1338
+ /**
1339
+ * Uploads an icon for a developer application. The `size` argument
1340
+ * selects which icon slot to update (defaults to `'medium'`).
1341
+ *
1342
+ * Requires the `dev:app_console` scope.
1343
+ */
1344
+ async uploadAppIcon(args, requestId) {
1345
+ return this.appClient.uploadAppIcon(args, requestId);
1346
+ }
1347
+ /**
1348
+ * Gets the currently issued developer test token for an app (null if none exists).
1349
+ *
1350
+ * Requires the `dev:app_console` scope.
1351
+ */
1352
+ async getAppTestToken(appId, requestId) {
1353
+ return this.appClient.getAppTestToken(appId, requestId);
1354
+ }
1355
+ /**
1356
+ * Creates (or rotates) a developer test token for an app.
1357
+ *
1358
+ * Requires the `dev:app_console` scope.
1359
+ */
1360
+ async createAppTestToken(appId, requestId) {
1361
+ return this.appClient.createAppTestToken(appId, requestId);
1362
+ }
1363
+ /**
1364
+ * Gets the distribution token for an app, which third parties use to install it.
1365
+ *
1366
+ * Requires the `dev:app_console` scope.
1367
+ */
1368
+ async getAppDistributionToken(appId, requestId) {
1369
+ return this.appClient.getAppDistributionToken(appId, requestId);
1370
+ }
1371
+ /**
1372
+ * Gets the current webhook verification token for an app.
1373
+ *
1374
+ * Requires the `dev:app_console` scope.
1375
+ */
1376
+ async getAppVerificationToken(appId, requestId) {
1377
+ return this.appClient.getAppVerificationToken(appId, requestId);
1378
+ }
1379
+ /**
1380
+ * Resets the webhook verification token for an app, returning the new value.
1381
+ *
1382
+ * Requires the `dev:app_console` scope.
1383
+ */
1384
+ async resetAppVerificationToken(appId, requestId) {
1385
+ return this.appClient.resetAppVerificationToken(appId, requestId);
1386
+ }
1387
+ /**
1388
+ * Resolves a public-facing app view from a distribution token. Used during
1389
+ * the installation flow to show prospective installers what the app does
1390
+ * and which scopes it requests.
1391
+ *
1392
+ * Requires the `dev:app_console` scope.
1393
+ */
1394
+ async getAppByDistributionToken(distributionToken, requestId) {
1395
+ return this.appClient.getAppByDistributionToken(distributionToken, requestId);
1396
+ }
1397
+ /**
1398
+ * Gets the webhook configuration for an app (null if no webhook is configured).
1399
+ *
1400
+ * Requires the `dev:app_console` scope.
1401
+ */
1402
+ async getAppWebhook(appId, requestId) {
1403
+ return this.appClient.getAppWebhook(appId, requestId);
1404
+ }
1405
+ /**
1406
+ * Creates or updates an app webhook configuration (upsert).
1407
+ *
1408
+ * Requires the `dev:app_console` scope.
1409
+ */
1410
+ async updateAppWebhook(args, requestId) {
1411
+ return this.appClient.updateAppWebhook(args, requestId);
1412
+ }
1413
+ /**
1414
+ * Deletes an app webhook configuration.
1415
+ *
1416
+ * Requires the `dev:app_console` scope.
1417
+ */
1418
+ async deleteAppWebhook(appId, requestId) {
1419
+ return this.appClient.deleteAppWebhook(appId, requestId);
1420
+ }
1421
+ /**
1422
+ * Lists all apps installed on the authenticated user's account.
1423
+ *
1424
+ * Requires the `dev:app_console` scope.
1425
+ */
1426
+ async getAppInstallations(requestId) {
1427
+ return this.appClient.getAppInstallations(requestId);
1428
+ }
1429
+ /**
1430
+ * Installs an application via its distribution token.
1431
+ *
1432
+ * Requires the `dev:app_console` scope.
1433
+ */
1434
+ async installApp(args, requestId) {
1435
+ return this.appClient.installApp(args, requestId);
1436
+ }
1437
+ /**
1438
+ * Retrieves a single app installation by ID.
1439
+ *
1440
+ * Requires the `dev:app_console` scope.
1441
+ */
1442
+ async getAppInstallation(installationId, requestId) {
1443
+ return this.appClient.getAppInstallation(installationId, requestId);
1444
+ }
1445
+ /**
1446
+ * Updates an app installation.
1447
+ *
1448
+ * Requires the `dev:app_console` scope.
1449
+ */
1450
+ async updateAppInstallation(installationId, args, requestId) {
1451
+ return this.appClient.updateAppInstallation(installationId, args, requestId);
1452
+ }
1453
+ /**
1454
+ * Uninstalls (removes) an app installation.
1455
+ *
1456
+ * Requires the `dev:app_console` scope.
1457
+ */
1458
+ async uninstallApp(installationId, requestId) {
1459
+ return this.appClient.uninstallApp(installationId, requestId);
1460
+ }
1461
+ /**
1462
+ * Retrieves a single UI extension by ID.
1463
+ *
1464
+ * Requires the `dev:app_console` scope.
1465
+ */
1466
+ async getUiExtension(uiExtensionId, requestId) {
1467
+ return this.uiExtensionClient.getUiExtension(uiExtensionId, requestId);
1468
+ }
1469
+ /**
1470
+ * Lists UI extensions available (installed) in the web client for the current user.
1471
+ *
1472
+ * Requires the `dev:app_console` scope.
1473
+ */
1474
+ async getInstalledUiExtensions(requestId) {
1475
+ return this.uiExtensionClient.getInstalledUiExtensions(requestId);
1476
+ }
1477
+ /**
1478
+ * Lists all UI extensions belonging to a given app (integration).
1479
+ *
1480
+ * Requires the `dev:app_console` scope.
1481
+ */
1482
+ async getUiExtensionsForApp(appId, requestId) {
1483
+ return this.uiExtensionClient.getUiExtensionsForApp(appId, requestId);
1484
+ }
1485
+ /**
1486
+ * Adds a new UI extension to an app.
1487
+ *
1488
+ * Requires the `dev:app_console` scope.
1489
+ */
1490
+ async addUiExtension(args, requestId) {
1491
+ return this.uiExtensionClient.addUiExtension(args, requestId);
1492
+ }
1493
+ /**
1494
+ * Updates an existing UI extension.
1495
+ *
1496
+ * Requires the `dev:app_console` scope.
1497
+ */
1498
+ async updateUiExtension(uiExtensionId, args, requestId) {
1499
+ return this.uiExtensionClient.updateUiExtension(uiExtensionId, args, requestId);
1500
+ }
1501
+ /**
1502
+ * Deletes a UI extension.
1503
+ *
1504
+ * Requires the `dev:app_console` scope.
1505
+ */
1506
+ async deleteUiExtension(uiExtensionId, requestId) {
1507
+ return this.uiExtensionClient.deleteUiExtension(uiExtensionId, requestId);
1508
+ }
1509
+ /**
1510
+ * Uploads an icon for a UI extension.
1511
+ *
1512
+ * Requires the `dev:app_console` scope.
1513
+ */
1514
+ async uploadUiExtensionIcon(args, requestId) {
1515
+ return this.uiExtensionClient.uploadUiExtensionIcon(args, requestId);
1516
+ }
1517
+ /**
1518
+ * Lists all apps the user has authorized (granted a token to).
1519
+ *
1520
+ * Requires the `dev:app_console` scope.
1521
+ */
1522
+ async getUserAuthorizations(requestId) {
1523
+ return this.appClient.getUserAuthorizations(requestId);
1524
+ }
1525
+ /**
1526
+ * Revokes a specific user authorization (access token granted to a third-party app).
1527
+ *
1528
+ * Requires the `dev:app_console` scope.
1529
+ */
1530
+ async revokeUserAuthorization(args, requestId) {
1531
+ return this.appClient.revokeUserAuthorization(args, requestId);
1532
+ }
1297
1533
  }
@@ -95,6 +95,7 @@ export async function request(args) {
95
95
  break;
96
96
  case 'POST':
97
97
  case 'PUT':
98
+ case 'PATCH':
98
99
  case 'DELETE': {
99
100
  // Convert payload from camelCase to snake_case
100
101
  // Note: While DELETE with body is uncommon, the Todoist API uses it for some endpoints
@@ -0,0 +1,248 @@
1
+ import { z } from 'zod';
2
+ import { StringOrNumberSchema } from '../common.js';
3
+ import { UI_EXTENSION_TYPES } from '../ui-extensions/types.js';
4
+ /**
5
+ * Available statuses for a developer application.
6
+ */
7
+ export const APP_STATUSES = ['public'];
8
+ export const AppStatusSchema = z.enum(APP_STATUSES);
9
+ /**
10
+ * Webhook event types that can be subscribed to.
11
+ *
12
+ * These are the friendly public names the backend uses in webhook payloads.
13
+ * The on-the-wire config endpoint uses a different (legacy) form (see
14
+ * {@link WEBHOOK_EVENT_WIRE_NAMES}); the SDK converts between the two
15
+ * so consumers only ever work with these pretty names.
16
+ *
17
+ * @see https://developer.todoist.com/sync/v1/#webhooks
18
+ */
19
+ export const WEBHOOK_EVENTS = [
20
+ 'item:added',
21
+ 'item:updated',
22
+ 'item:completed',
23
+ 'item:uncompleted',
24
+ 'item:deleted',
25
+ 'note:added',
26
+ 'note:updated',
27
+ 'note:deleted',
28
+ 'project:added',
29
+ 'project:updated',
30
+ 'project:deleted',
31
+ 'project:archived',
32
+ 'project:unarchived',
33
+ 'section:added',
34
+ 'section:updated',
35
+ 'section:deleted',
36
+ 'section:archived',
37
+ 'section:unarchived',
38
+ 'label:added',
39
+ 'label:updated',
40
+ 'label:deleted',
41
+ 'filter:added',
42
+ 'filter:updated',
43
+ 'filter:deleted',
44
+ 'reminder:fired',
45
+ ];
46
+ export const WebhookEventSchema = z.enum(WEBHOOK_EVENTS);
47
+ /**
48
+ * Raw wire-format webhook event names used by the config endpoint
49
+ * (`POST/GET /apps/<id>/webhook`). Exported for completeness — prefer
50
+ * {@link WEBHOOK_EVENTS} when working with the SDK.
51
+ */
52
+ export const WEBHOOK_EVENT_WIRE_NAMES = [
53
+ 'e_item_added',
54
+ 'e_item_updated',
55
+ 'e_item_completed',
56
+ 'e_item_uncompleted',
57
+ 'e_item_deleted',
58
+ 'e_note_added',
59
+ 'e_note_updated',
60
+ 'e_note_deleted',
61
+ 'e_project_added',
62
+ 'e_project_updated',
63
+ 'e_project_deleted',
64
+ 'e_project_archived',
65
+ 'e_project_unarchived',
66
+ 'e_section_added',
67
+ 'e_section_updated',
68
+ 'e_section_deleted',
69
+ 'e_section_archived',
70
+ 'e_section_unarchived',
71
+ 'e_label_added',
72
+ 'e_label_updated',
73
+ 'e_label_deleted',
74
+ 'e_filter_added',
75
+ 'e_filter_updated',
76
+ 'e_filter_deleted',
77
+ 'e_reminder_fired',
78
+ ];
79
+ export const WebhookEventWireNameSchema = z.enum(WEBHOOK_EVENT_WIRE_NAMES);
80
+ /**
81
+ * Translates a wire-format event name (`'e_item_added'`) to its pretty form (`'item:added'`).
82
+ */
83
+ export function webhookEventFromWireName(wireName) {
84
+ // Strip leading `e_`, replace first `_` with `:`. The resulting string is
85
+ // guaranteed to be a `WebhookEvent` by construction of the two const arrays.
86
+ return wireName.slice(2).replace('_', ':');
87
+ }
88
+ /**
89
+ * Translates a pretty event name (`'item:added'`) to its wire-format form (`'e_item_added'`).
90
+ */
91
+ export function webhookEventToWireName(event) {
92
+ return ('e_' + event.replace(':', '_'));
93
+ }
94
+ /**
95
+ * Available statuses for an app webhook.
96
+ */
97
+ export const WEBHOOK_STATUSES = ['active', 'invalid'];
98
+ export const WebhookStatusSchema = z.enum(WEBHOOK_STATUSES);
99
+ /**
100
+ * Supported webhook payload versions. v9 is deprecated and intentionally excluded.
101
+ */
102
+ export const WEBHOOK_VERSIONS = ['1'];
103
+ export const WebhookVersionSchema = z.enum(WEBHOOK_VERSIONS);
104
+ /**
105
+ * Available installation types for an app installation.
106
+ */
107
+ export const INSTALLATION_TYPES = ['user'];
108
+ export const InstallationTypeSchema = z.enum(INSTALLATION_TYPES);
109
+ /**
110
+ * Transforms a comma-separated scope string into `string[] | null`.
111
+ *
112
+ * The backend stores `app_token_scopes` as a single comma-separated string
113
+ * (e.g. `"data:read,task:add"`). Reads are exposed as `string[]` (rather than
114
+ * `Permission[]`) so that newly added backend scopes don't break parsing —
115
+ * writes accept `Permission` for autocomplete while still permitting `string`
116
+ * (via `UpdateAppArgs`), so a fetched `App.appTokenScopes` can be round-tripped
117
+ * back into `updateApp()` without casts.
118
+ *
119
+ * Preserves `null` on read (backend returns `null` for apps that have had
120
+ * their scopes cleared via `updateApp({ appTokenScopes: null })`) so the
121
+ * read and write shapes line up and information is not lost.
122
+ */
123
+ export const AppTokenScopesSchema = z
124
+ .string()
125
+ .nullable()
126
+ .transform((value) => {
127
+ if (value === null)
128
+ return null;
129
+ if (value === '')
130
+ return [];
131
+ return value.split(',').filter(Boolean);
132
+ });
133
+ /**
134
+ * Schema for a developer application.
135
+ * @see https://developer.todoist.com/api/v1/#tag/Apps
136
+ */
137
+ export const AppSchema = z.object({
138
+ id: StringOrNumberSchema,
139
+ status: AppStatusSchema,
140
+ displayName: z.string(),
141
+ userId: StringOrNumberSchema,
142
+ createdAt: z.coerce.date(),
143
+ serviceUrl: z.string().nullable(),
144
+ oauthRedirectUri: z.string().nullable(),
145
+ description: z.string().nullable(),
146
+ iconSm: z.string().nullable(),
147
+ iconMd: z.string().nullable(),
148
+ iconLg: z.string().nullable(),
149
+ appTokenScopes: AppTokenScopesSchema,
150
+ });
151
+ /**
152
+ * Schema for a developer application that includes the user count.
153
+ * Returned by most endpoints that manage a single app (get, update, delete).
154
+ */
155
+ export const AppWithUserCountSchema = AppSchema.extend({
156
+ userCount: z.number().int(),
157
+ });
158
+ /**
159
+ * OAuth client credentials for a developer application.
160
+ */
161
+ export const AppSecretsSchema = z.object({
162
+ clientId: z.string(),
163
+ clientSecret: z.string(),
164
+ });
165
+ /**
166
+ * Webhook verification token for a developer application.
167
+ */
168
+ export const AppVerificationTokenSchema = z.object({
169
+ verificationToken: z.string(),
170
+ });
171
+ /**
172
+ * Developer test access token for a developer application.
173
+ */
174
+ export const AppTestTokenSchema = z.object({
175
+ accessToken: z.string().nullish(),
176
+ });
177
+ /**
178
+ * Distribution token for a developer application.
179
+ */
180
+ export const AppDistributionTokenSchema = z.object({
181
+ distributionToken: z.string(),
182
+ });
183
+ /**
184
+ * Subset of an app returned when resolving by distribution token — used by the installation flow.
185
+ * Includes a lightweight list of the app's UI extensions (not full `UIExtension` records).
186
+ */
187
+ export const AppByDistributionTokenUiExtensionSchema = z.object({
188
+ name: z.string(),
189
+ description: z.string(),
190
+ icon: z.string().nullable(),
191
+ extensionType: z.enum(UI_EXTENSION_TYPES),
192
+ });
193
+ export const AppByDistributionTokenSchema = z.object({
194
+ id: StringOrNumberSchema,
195
+ displayName: z.string(),
196
+ description: z.string().nullable(),
197
+ iconMd: z.string().nullable(),
198
+ appTokenScopes: AppTokenScopesSchema,
199
+ uiExtensions: z.array(AppByDistributionTokenUiExtensionSchema),
200
+ });
201
+ /**
202
+ * Schema for an app webhook.
203
+ *
204
+ * Events arrive from the wire in their `e_*` form and are transformed to
205
+ * their pretty `item:added`-style names for SDK consumers.
206
+ */
207
+ export const AppWebhookSchema = z.object({
208
+ status: WebhookStatusSchema,
209
+ callbackUrl: z.string(),
210
+ version: WebhookVersionSchema,
211
+ events: z.array(WebhookEventWireNameSchema.transform(webhookEventFromWireName)),
212
+ });
213
+ /**
214
+ * Lightweight view of an app embedded in an installation record.
215
+ * Mirrors `AppSchema` shape — backend returns the same `ApplicationRestView`.
216
+ */
217
+ export const InstalledIntegrationSchema = AppSchema;
218
+ /**
219
+ * Schema for an installed application (integration installed to a user's account).
220
+ */
221
+ export const AppInstallationSchema = z.object({
222
+ id: StringOrNumberSchema,
223
+ creator: StringOrNumberSchema,
224
+ createdTs: z.number().int(),
225
+ installationType: InstallationTypeSchema,
226
+ appTokenScopesValidated: z.boolean(),
227
+ integration: InstalledIntegrationSchema.nullable(),
228
+ });
229
+ /**
230
+ * Lightweight app info included on a user authorization record.
231
+ */
232
+ export const UserAuthorizationAppSchema = z.object({
233
+ id: StringOrNumberSchema,
234
+ displayName: z.string(),
235
+ description: z.string().nullable(),
236
+ serviceUrl: z.string().nullable(),
237
+ iconMd: z.string().nullable(),
238
+ });
239
+ /**
240
+ * Schema for a user authorization entry — a token the user has granted to a third-party app.
241
+ */
242
+ export const UserAuthorizationSchema = z.object({
243
+ accessTokenId: StringOrNumberSchema,
244
+ scope: z.array(z.string()),
245
+ scopeDescriptions: z.array(z.string()),
246
+ createdAt: z.coerce.date(),
247
+ app: UserAuthorizationAppSchema.nullable(),
248
+ });
@@ -9,7 +9,6 @@ export * from './productivity/index.js';
9
9
  export * from './activity/index.js';
10
10
  export * from './workspaces/index.js';
11
11
  export * from './folders/index.js';
12
- export * from './goals/index.js';
13
12
  export * from './insights/index.js';
14
13
  export * from './backups/index.js';
15
14
  export * from './id-mappings/index.js';
@@ -19,3 +18,5 @@ export * from './templates/index.js';
19
18
  export * from './errors.js';
20
19
  export * from './http.js';
21
20
  export * from './sync/index.js';
21
+ export * from './apps/index.js';
22
+ export * from './ui-extensions/index.js';
@@ -11,7 +11,6 @@ export * from './workspaces.js';
11
11
  export * from './folders.js';
12
12
  export * from './workspace-filters.js';
13
13
  export * from './workspace-goals.js';
14
- export * from './goals.js';
15
14
  export * from './notifications.js';
16
15
  export * from './sharing.js';
17
16
  export * from './view-options.js';
@@ -29,7 +29,6 @@ export const SYNC_RESOURCE_TYPES = [
29
29
  'role_actions',
30
30
  'folders',
31
31
  'workspace_goals',
32
- 'goals',
33
32
  'day_orders',
34
33
  'calendars',
35
34
  'calendar_accounts',
@@ -1,5 +1,4 @@
1
1
  import { z } from 'zod';
2
- import { GoalSchema } from '../goals/types.js';
3
2
  import { LabelSchema } from '../labels/types.js';
4
3
  import { ProjectSchema } from '../projects/types.js';
5
4
  import { SectionSchema } from '../sections/types.js';
@@ -44,7 +43,6 @@ export const SyncResponseSchema = z.looseObject({
44
43
  projectViewOptionsDefaults: z.array(ProjectViewOptionsDefaultsSchema).optional(),
45
44
  roleActions: z.array(z.record(z.string(), z.unknown())).optional(),
46
45
  folders: z.array(FolderSchema).optional(),
47
- goals: z.array(GoalSchema).optional(),
48
46
  workspaceGoals: z.array(WorkspaceGoalSchema).optional(),
49
47
  dayOrders: z.record(z.string(), z.number()).optional(),
50
48
  calendars: z.array(CalendarSchema).optional(),