@doist/todoist-cli 1.58.0 → 1.60.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 (59) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/commands/comment/add.d.ts.map +1 -1
  3. package/dist/commands/comment/add.js +7 -4
  4. package/dist/commands/comment/add.js.map +1 -1
  5. package/dist/commands/config/view.d.ts.map +1 -1
  6. package/dist/commands/config/view.js +85 -13
  7. package/dist/commands/config/view.js.map +1 -1
  8. package/dist/commands/doctor.d.ts.map +1 -1
  9. package/dist/commands/doctor.js +69 -1
  10. package/dist/commands/doctor.js.map +1 -1
  11. package/dist/commands/stats/helpers.d.ts +3 -1
  12. package/dist/commands/stats/helpers.d.ts.map +1 -1
  13. package/dist/commands/stats/helpers.js +2 -1
  14. package/dist/commands/stats/helpers.js.map +1 -1
  15. package/dist/commands/user/current.d.ts +5 -0
  16. package/dist/commands/user/current.d.ts.map +1 -0
  17. package/dist/commands/user/current.js +32 -0
  18. package/dist/commands/user/current.js.map +1 -0
  19. package/dist/commands/user/index.d.ts.map +1 -1
  20. package/dist/commands/user/index.js +16 -1
  21. package/dist/commands/user/index.js.map +1 -1
  22. package/dist/commands/user/remove.d.ts +2 -0
  23. package/dist/commands/user/remove.d.ts.map +1 -0
  24. package/dist/commands/user/remove.js +26 -0
  25. package/dist/commands/user/remove.js.map +1 -0
  26. package/dist/commands/view.d.ts.map +1 -1
  27. package/dist/commands/view.js +12 -7
  28. package/dist/commands/view.js.map +1 -1
  29. package/dist/index.js +13 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/lib/api/core.d.ts.map +1 -1
  32. package/dist/lib/api/core.js +4 -1
  33. package/dist/lib/api/core.js.map +1 -1
  34. package/dist/lib/api/stats.d.ts +1 -32
  35. package/dist/lib/api/stats.d.ts.map +1 -1
  36. package/dist/lib/api/stats.js +2 -54
  37. package/dist/lib/api/stats.js.map +1 -1
  38. package/dist/lib/migrate-auth.d.ts.map +1 -1
  39. package/dist/lib/migrate-auth.js +3 -2
  40. package/dist/lib/migrate-auth.js.map +1 -1
  41. package/dist/lib/oauth.d.ts.map +1 -1
  42. package/dist/lib/oauth.js +2 -1
  43. package/dist/lib/oauth.js.map +1 -1
  44. package/dist/lib/permissions.d.ts.map +1 -1
  45. package/dist/lib/permissions.js +2 -0
  46. package/dist/lib/permissions.js.map +1 -1
  47. package/dist/lib/skills/content.d.ts +1 -1
  48. package/dist/lib/skills/content.d.ts.map +1 -1
  49. package/dist/lib/skills/content.js +3 -1
  50. package/dist/lib/skills/content.js.map +1 -1
  51. package/dist/lib/usage-tracking.d.ts +9 -0
  52. package/dist/lib/usage-tracking.d.ts.map +1 -0
  53. package/dist/lib/usage-tracking.js +93 -0
  54. package/dist/lib/usage-tracking.js.map +1 -0
  55. package/package.json +2 -2
  56. package/dist/lib/api/uploads.d.ts +0 -10
  57. package/dist/lib/api/uploads.d.ts.map +0 -1
  58. package/dist/lib/api/uploads.js +0 -34
  59. package/dist/lib/api/uploads.js.map +0 -1
@@ -54,7 +54,9 @@ The CLI can hold credentials for multiple Todoist accounts at once.
54
54
  \`\`\`bash
55
55
  td auth login # adds the account; first one becomes default
56
56
  td user list # all stored accounts (with default marker)
57
- td user use <id|email> # set the default account
57
+ td user use <id|email> # set the default account (alias: td user default)
58
+ td user current # show the active account
59
+ td user remove <id|email> # delete an account (and its token)
58
60
  td --user <id|email> task list # one-off override for any command
59
61
  td auth logout --user <id|email> # log out a specific account
60
62
  \`\`\`
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAA;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAC1B,iRAAiR,CAAA;AACrR,MAAM,CAAC,MAAM,mBAAmB,GAC5B,iGAAiG,CAAA;AAErG,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyT5B,CAAA"}
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAA;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAC1B,iRAAiR,CAAA;AACrR,MAAM,CAAC,MAAM,mBAAmB,GAC5B,iGAAiG,CAAA;AAErG,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2T5B,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { CustomFetch } from '@doist/todoist-sdk';
2
+ export declare function normalizeCommandPath(commandPath: string): string;
3
+ export declare function setActiveCommandPath(commandPath: string | undefined): void;
4
+ export declare function getActiveCommandPath(): string | undefined;
5
+ export declare function buildUsageTrackingHeaders(commandPath?: string): Record<string, string>;
6
+ export declare function createTrackedFetch(baseFetch?: typeof fetch): CustomFetch;
7
+ export declare function fetchTodoist(url: string | URL, options?: RequestInit, fetchImpl?: typeof fetch, commandPath?: string): Promise<Response>;
8
+ export declare function resetUsageTrackingForTests(): void;
9
+ //# sourceMappingURL=usage-tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-tracking.d.ts","sourceRoot":"","sources":["../../src/lib/usage-tracking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,oBAAoB,CAAA;AA4B1E,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE1E;AAED,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAEzD;AAED,wBAAgB,yBAAyB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBtF;AAwBD,wBAAgB,kBAAkB,CAAC,SAAS,GAAE,OAAO,KAAwB,GAAG,WAAW,CAiB1F;AAED,wBAAgB,YAAY,CACxB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,OAAO,GAAE,WAAgB,EACzB,SAAS,GAAE,OAAO,KAAwB,EAC1C,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,QAAQ,CAAC,CAMnB;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
@@ -0,0 +1,93 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import packageJson from '../../package.json' with { type: 'json' };
3
+ const CLI_NAME = 'todoist-cli';
4
+ const CLI_VERSION = packageJson.version;
5
+ const SESSION_ID = randomUUID();
6
+ let activeCommandPath;
7
+ function getUserAgent() {
8
+ return `${CLI_NAME}/${CLI_VERSION}`;
9
+ }
10
+ function getDoistOs(platform = process.platform) {
11
+ switch (platform) {
12
+ case 'darwin':
13
+ return 'macos';
14
+ case 'linux':
15
+ return 'linux';
16
+ case 'win32':
17
+ return 'windows';
18
+ default:
19
+ return 'unknown';
20
+ }
21
+ }
22
+ export function normalizeCommandPath(commandPath) {
23
+ return commandPath
24
+ .replace(/^td\s+/, '')
25
+ .trim()
26
+ .toLowerCase()
27
+ .replace(/\s+/g, ':');
28
+ }
29
+ export function setActiveCommandPath(commandPath) {
30
+ activeCommandPath = commandPath ? normalizeCommandPath(commandPath) : undefined;
31
+ }
32
+ export function getActiveCommandPath() {
33
+ return activeCommandPath;
34
+ }
35
+ export function buildUsageTrackingHeaders(commandPath) {
36
+ const normalizedCommandPath = commandPath
37
+ ? normalizeCommandPath(commandPath)
38
+ : activeCommandPath;
39
+ const headers = {
40
+ 'User-Agent': getUserAgent(),
41
+ 'doist-platform': 'cli',
42
+ 'doist-version': CLI_VERSION,
43
+ 'doist-os': getDoistOs(),
44
+ 'X-TD-Request-Id': randomUUID(),
45
+ 'X-TD-Session-Id': SESSION_ID,
46
+ 'X-TD-CLI-Command': normalizedCommandPath ?? 'unknown',
47
+ };
48
+ return headers;
49
+ }
50
+ function mergeTodoistHeaders(headersInit, commandPath) {
51
+ const mergedHeaders = new Headers(headersInit);
52
+ for (const [key, value] of Object.entries(buildUsageTrackingHeaders(commandPath))) {
53
+ mergedHeaders.set(key, value);
54
+ }
55
+ return Object.fromEntries(mergedHeaders.entries());
56
+ }
57
+ function toCustomFetchResponse(response) {
58
+ return {
59
+ ok: response.ok,
60
+ status: response.status,
61
+ statusText: response.statusText,
62
+ headers: Object.fromEntries(response.headers.entries()),
63
+ text: () => response.text(),
64
+ json: () => response.json(),
65
+ };
66
+ }
67
+ export function createTrackedFetch(baseFetch = globalThis.fetch) {
68
+ return async (url, options = {}) => {
69
+ const { timeout: timeoutMs, headers, signal, ...rest } = options;
70
+ let abortSignal = signal;
71
+ if (timeoutMs) {
72
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
73
+ abortSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
74
+ }
75
+ const response = await baseFetch(url, {
76
+ ...rest,
77
+ signal: abortSignal,
78
+ headers: mergeTodoistHeaders(headers),
79
+ });
80
+ return toCustomFetchResponse(response);
81
+ };
82
+ }
83
+ export function fetchTodoist(url, options = {}, fetchImpl = globalThis.fetch, commandPath) {
84
+ const { headers, ...rest } = options;
85
+ return fetchImpl(url, {
86
+ ...rest,
87
+ headers: mergeTodoistHeaders(headers, commandPath),
88
+ });
89
+ }
90
+ export function resetUsageTrackingForTests() {
91
+ activeCommandPath = undefined;
92
+ }
93
+ //# sourceMappingURL=usage-tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-tracking.js","sourceRoot":"","sources":["../../src/lib/usage-tracking.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/todoist-cli",
3
- "version": "1.58.0",
3
+ "version": "1.60.0",
4
4
  "description": "TypeScript CLI for Todoist",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -51,7 +51,7 @@
51
51
  "CHANGELOG.md"
52
52
  ],
53
53
  "dependencies": {
54
- "@doist/todoist-sdk": "9.8.0",
54
+ "@doist/todoist-sdk": "10.0.0",
55
55
  "@napi-rs/keyring": "1.2.0",
56
56
  "@pnpm/tabtab": "0.5.4",
57
57
  "chalk": "5.6.2",
@@ -1,10 +0,0 @@
1
- export interface UploadResult {
2
- fileName: string;
3
- fileSize: number;
4
- fileType: string;
5
- fileUrl: string;
6
- resourceType: string;
7
- uploadState: string;
8
- }
9
- export declare function uploadFile(filePath: string): Promise<UploadResult>;
10
- //# sourceMappingURL=uploads.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"uploads.d.ts","sourceRoot":"","sources":["../../../src/lib/api/uploads.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACtB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAsCxE"}
@@ -1,34 +0,0 @@
1
- import { getApiToken } from '../auth.js';
2
- import { CliError } from '../errors.js';
3
- import { ensureWriteAllowed } from '../permissions.js';
4
- export async function uploadFile(filePath) {
5
- await ensureWriteAllowed();
6
- const fs = await import('node:fs');
7
- const path = await import('node:path');
8
- const token = await getApiToken();
9
- const fileName = path.basename(filePath);
10
- const fileBuffer = fs.readFileSync(filePath);
11
- const formData = new FormData();
12
- formData.append('file_name', fileName);
13
- formData.append('file', new Blob([fileBuffer]), fileName);
14
- const response = await fetch('https://api.todoist.com/api/v1/uploads', {
15
- method: 'POST',
16
- headers: {
17
- Authorization: `Bearer ${token}`,
18
- },
19
- body: formData,
20
- });
21
- if (!response.ok) {
22
- throw new CliError('UPLOAD_FAILED', `Upload failed: ${response.status} ${response.statusText}`);
23
- }
24
- const data = await response.json();
25
- return {
26
- fileName: data.file_name,
27
- fileSize: data.file_size,
28
- fileType: data.file_type,
29
- fileUrl: data.file_url,
30
- resourceType: data.resource_type,
31
- uploadState: data.upload_state,
32
- };
33
- }
34
- //# sourceMappingURL=uploads.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"uploads.js","sourceRoot":"","sources":["../../../src/lib/api/uploads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAWtD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC7C,MAAM,kBAAkB,EAAE,CAAA;IAE1B,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;IAEtC,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAA;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACxC,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;IAE5C,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;IACtC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;IAEzD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,wCAAwC,EAAE;QACnE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACL,aAAa,EAAE,UAAU,KAAK,EAAE;SACnC;QACD,IAAI,EAAE,QAAQ;KACjB,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CACd,eAAe,EACf,kBAAkB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC7D,CAAA;IACL,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAClC,OAAO;QACH,QAAQ,EAAE,IAAI,CAAC,SAAS;QACxB,QAAQ,EAAE,IAAI,CAAC,SAAS;QACxB,QAAQ,EAAE,IAAI,CAAC,SAAS;QACxB,OAAO,EAAE,IAAI,CAAC,QAAQ;QACtB,YAAY,EAAE,IAAI,CAAC,aAAa;QAChC,WAAW,EAAE,IAAI,CAAC,YAAY;KACjC,CAAA;AACL,CAAC"}