@doist/todoist-cli 1.39.2 → 1.39.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [1.39.3](https://github.com/Doist/todoist-cli/compare/v1.39.2...v1.39.3) (2026-04-07)
2
+
3
+ ### Bug Fixes
4
+
5
+ * try fallback ports when OAuth callback port is in use ([#237](https://github.com/Doist/todoist-cli/issues/237)) ([5115b62](https://github.com/Doist/todoist-cli/commit/5115b62536837264e6901e29b77f02a8af797ffd))
6
+
1
7
  ## [1.39.2](https://github.com/Doist/todoist-cli/compare/v1.39.1...v1.39.2) (2026-04-07)
2
8
 
3
9
  ### Bug Fixes
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BxF"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,CAAC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCxF"}
@@ -10,14 +10,17 @@ export async function loginWithOAuth(options = {}) {
10
10
  const codeChallenge = generateCodeChallenge(codeVerifier);
11
11
  const state = generateState();
12
12
  console.log('Opening browser for Todoist authorization...');
13
- const authUrl = buildAuthorizationUrl(codeChallenge, state, { readOnly: options.readOnly });
14
- const { promise: callbackPromise, cleanup } = startCallbackServer(state);
13
+ const { promise: callbackPromise, port, cleanup } = await startCallbackServer(state);
14
+ const authUrl = buildAuthorizationUrl(codeChallenge, state, {
15
+ readOnly: options.readOnly,
16
+ port,
17
+ });
15
18
  try {
16
19
  await open(authUrl);
17
20
  console.log(chalk.dim('Waiting for authorization...'));
18
21
  const code = await callbackPromise;
19
22
  console.log(chalk.dim('Exchanging code for token...'));
20
- const accessToken = await exchangeCodeForToken(code, codeVerifier);
23
+ const accessToken = await exchangeCodeForToken(code, codeVerifier, port);
21
24
  const result = await saveApiToken(accessToken, {
22
25
  authMode: options.readOnly ? 'read-only' : 'read-write',
23
26
  authScope: options.readOnly ? READ_ONLY_SCOPES : READ_WRITE_SCOPES,
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EACH,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC9F,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAEpD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkC,EAAE;IACrE,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAA;IAC3C,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,KAAK,GAAG,aAAa,EAAE,CAAA;IAE7B,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;IAE3D,MAAM,OAAO,GAAG,qBAAqB,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC3F,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;IAExE,IAAI,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,CAAA;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QAEtD,MAAM,IAAI,GAAG,MAAM,eAAe,CAAA;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QAEtD,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QAClE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE;YAC3C,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;YACvD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB;SACrE,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,yBAAyB,CAAC,CAAA;QACxD,qBAAqB,CAAC,MAAM,EAAE,wDAAwD,CAAC,CAAA;IAC3F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,EAAE,CAAA;QACT,MAAM,KAAK,CAAA;IACf,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EACH,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC9F,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAEpD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkC,EAAE;IACrE,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAA;IAC3C,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,KAAK,GAAG,aAAa,EAAE,CAAA;IAE7B,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;IAE3D,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAA;IACpF,MAAM,OAAO,GAAG,qBAAqB,CAAC,aAAa,EAAE,KAAK,EAAE;QACxD,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI;KACP,CAAC,CAAA;IAEF,IAAI,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,CAAA;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QAEtD,MAAM,IAAI,GAAG,MAAM,eAAe,CAAA;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAA;QAEtD,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,CAAA;QACxE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE;YAC3C,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;YACvD,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB;SACrE,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,yBAAyB,CAAC,CAAA;QACxD,qBAAqB,CAAC,MAAM,EAAE,wDAAwD,CAAC,CAAA;IAC3F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,EAAE,CAAA;QACT,MAAM,KAAK,CAAA;IACf,CAAC;AACL,CAAC"}
@@ -1,6 +1,8 @@
1
- export declare function startCallbackServer(expectedState: string): {
1
+ export declare const DEFAULT_PORT = 8765;
2
+ export declare function getRedirectUri(port: number): string;
3
+ export declare function startCallbackServer(expectedState: string): Promise<{
2
4
  promise: Promise<string>;
5
+ port: number;
3
6
  cleanup: () => void;
4
- };
5
- export declare const OAUTH_REDIRECT_URI = "http://localhost:8765/callback";
7
+ }>;
6
8
  //# sourceMappingURL=oauth-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-server.d.ts","sourceRoot":"","sources":["../../src/lib/oauth-server.ts"],"names":[],"mappings":"AAusBA,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG;IACxD,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,OAAO,EAAE,MAAM,IAAI,CAAA;CACtB,CA2EA;AAED,eAAO,MAAM,kBAAkB,mCAAsC,CAAA"}
1
+ {"version":3,"file":"oauth-server.d.ts","sourceRoot":"","sources":["../../src/lib/oauth-server.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,OAAO,CAAA;AAssBhC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAYD,wBAAsB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IACtE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAgGD"}
@@ -1,5 +1,6 @@
1
1
  import { createServer } from 'node:http';
2
- const PORT = 8765;
2
+ export const DEFAULT_PORT = 8765;
3
+ const MAX_PORT_ATTEMPTS = 5;
3
4
  const TIMEOUT_MS = 3 * 60 * 1000; // 3 minutes
4
5
  const SUCCESS_HTML = `
5
6
  <!DOCTYPE html>
@@ -705,22 +706,55 @@ const ERROR_HTML = (message) => `
705
706
  </body>
706
707
  </html>
707
708
  `;
708
- export function startCallbackServer(expectedState) {
709
- let server = null;
709
+ export function getRedirectUri(port) {
710
+ return `http://localhost:${port}/callback`;
711
+ }
712
+ function tryListen(server, port) {
713
+ return new Promise((resolve, reject) => {
714
+ server.once('error', reject);
715
+ server.listen(port, () => {
716
+ server.removeListener('error', reject);
717
+ resolve();
718
+ });
719
+ });
720
+ }
721
+ export async function startCallbackServer(expectedState) {
710
722
  let timeoutId = null;
723
+ let boundPort = DEFAULT_PORT;
724
+ const server = createServer();
725
+ let closed = false;
711
726
  const cleanup = () => {
727
+ if (closed)
728
+ return;
729
+ closed = true;
712
730
  if (timeoutId) {
713
731
  clearTimeout(timeoutId);
714
732
  timeoutId = null;
715
733
  }
716
- if (server) {
717
- server.close();
718
- server = null;
719
- }
734
+ server.close();
720
735
  };
736
+ // Find an available port
737
+ for (let port = DEFAULT_PORT; port < DEFAULT_PORT + MAX_PORT_ATTEMPTS; port++) {
738
+ try {
739
+ await tryListen(server, port);
740
+ boundPort = port;
741
+ break;
742
+ }
743
+ catch (err) {
744
+ if (err instanceof Error &&
745
+ 'code' in err &&
746
+ err.code === 'EADDRINUSE') {
747
+ if (port === DEFAULT_PORT + MAX_PORT_ATTEMPTS - 1) {
748
+ throw new Error(`Could not find an available port (tried ${DEFAULT_PORT}-${DEFAULT_PORT + MAX_PORT_ATTEMPTS - 1})`);
749
+ }
750
+ continue;
751
+ }
752
+ throw err;
753
+ }
754
+ }
721
755
  const promise = new Promise((resolve, reject) => {
722
- const handleRequest = (req, res) => {
723
- const url = new URL(req.url || '/', `http://localhost:${PORT}`);
756
+ server.on('request', (req, res) => {
757
+ const url = new URL(req.url || '/', `http://localhost:${boundPort}`);
724
758
  if (url.pathname !== '/callback') {
725
759
  res.writeHead(404);
726
760
  res.end('Not found');
@@ -754,20 +788,16 @@ export function startCallbackServer(expectedState) {
754
788
  res.end(SUCCESS_HTML);
755
789
  cleanup();
756
790
  resolve(code);
757
- };
758
- server = createServer(handleRequest);
791
+ });
759
792
  server.on('error', (err) => {
760
793
  cleanup();
761
794
  reject(err);
762
795
  });
763
- server.listen(PORT, () => {
764
- timeoutId = setTimeout(() => {
765
- cleanup();
766
- reject(new Error('OAuth callback timed out'));
767
- }, TIMEOUT_MS);
768
- });
796
+ timeoutId = setTimeout(() => {
797
+ cleanup();
798
+ reject(new Error('OAuth callback timed out'));
799
+ }, TIMEOUT_MS);
769
800
  });
770
- return { promise, cleanup };
801
+ return { promise, port: boundPort, cleanup };
771
802
  }
772
- export const OAUTH_REDIRECT_URI = `http://localhost:${PORT}/callback`;
773
803
  //# sourceMappingURL=oauth-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-server.js","sourceRoot":"","sources":["../../src/lib/oauth-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth-server.js","sourceRoot":"","sources":["../../src/lib/oauth-server.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export declare const READ_WRITE_SCOPES = "data:read_write,data:delete,project:de
2
2
  export declare const READ_ONLY_SCOPES = "data:read";
3
3
  export declare function buildAuthorizationUrl(codeChallenge: string, state: string, options?: {
4
4
  readOnly?: boolean;
5
+ port?: number;
5
6
  }): string;
6
- export declare function exchangeCodeForToken(code: string, codeVerifier: string): Promise<string>;
7
+ export declare function exchangeCodeForToken(code: string, codeVerifier: string, port: number): Promise<string>;
7
8
  //# sourceMappingURL=oauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iBAAiB,+CAA+C,CAAA;AAC7E,eAAO,MAAM,gBAAgB,cAAc,CAAA;AAE3C,wBAAgB,qBAAqB,CACjC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,CAWR;AAOD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB9F"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iBAAiB,+CAA+C,CAAA;AAC7E,eAAO,MAAM,gBAAgB,cAAc,CAAA;AAE3C,wBAAgB,qBAAqB,CACjC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,MAAM,CAYR;AAOD,wBAAsB,oBAAoB,CACtC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
package/dist/lib/oauth.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CliError } from './errors.js';
2
- import { OAUTH_REDIRECT_URI } from './oauth-server.js';
2
+ import { DEFAULT_PORT, getRedirectUri } from './oauth-server.js';
3
3
  const TODOIST_CLIENT_ID = '04863cc1e3584830a578622f50224d5b';
4
4
  const OAUTH_AUTHORIZE_URL = 'https://todoist.com/oauth/authorize';
5
5
  const OAUTH_TOKEN_URL = 'https://todoist.com/oauth/access_token';
@@ -7,22 +7,23 @@ export const READ_WRITE_SCOPES = 'data:read_write,data:delete,project:delete';
7
7
  export const READ_ONLY_SCOPES = 'data:read';
8
8
  export function buildAuthorizationUrl(codeChallenge, state, options = {}) {
9
9
  const scope = options.readOnly ? READ_ONLY_SCOPES : READ_WRITE_SCOPES;
10
+ const redirectUri = getRedirectUri(options.port ?? DEFAULT_PORT);
10
11
  const params = new URLSearchParams({
11
12
  client_id: TODOIST_CLIENT_ID,
12
13
  scope,
13
14
  state: state,
14
- redirect_uri: OAUTH_REDIRECT_URI,
15
+ redirect_uri: redirectUri,
15
16
  code_challenge: codeChallenge,
16
17
  code_challenge_method: 'S256',
17
18
  });
18
19
  return `${OAUTH_AUTHORIZE_URL}?${params.toString()}`;
19
20
  }
20
- export async function exchangeCodeForToken(code, codeVerifier) {
21
+ export async function exchangeCodeForToken(code, codeVerifier, port) {
21
22
  const body = new URLSearchParams({
22
23
  client_id: TODOIST_CLIENT_ID,
23
24
  code: code,
24
25
  code_verifier: codeVerifier,
25
- redirect_uri: OAUTH_REDIRECT_URI,
26
+ redirect_uri: getRedirectUri(port),
26
27
  });
27
28
  const response = await fetch(OAUTH_TOKEN_URL, {
28
29
  method: 'POST',
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEtD,MAAM,iBAAiB,GAAG,kCAAkC,CAAA;AAC5D,MAAM,mBAAmB,GAAG,qCAAqC,CAAA;AACjE,MAAM,eAAe,GAAG,wCAAwC,CAAA;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,4CAA4C,CAAA;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAA;AAE3C,MAAM,UAAU,qBAAqB,CACjC,aAAqB,EACrB,KAAa,EACb,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAA;IACrE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QAC/B,SAAS,EAAE,iBAAiB;QAC5B,KAAK;QACL,KAAK,EAAE,KAAK;QACZ,YAAY,EAAE,kBAAkB;QAChC,cAAc,EAAE,aAAa;QAC7B,qBAAqB,EAAE,MAAM;KAChC,CAAC,CAAA;IACF,OAAO,GAAG,mBAAmB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;AACxD,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY,EAAE,YAAoB;IACzE,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC7B,SAAS,EAAE,iBAAiB;QAC5B,IAAI,EAAE,IAAI;QACV,aAAa,EAAE,YAAY;QAC3B,YAAY,EAAE,kBAAkB;KACnC,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE;QAC1C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACL,cAAc,EAAE,mCAAmC;SACtD;QACD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,IAAI,QAAQ,CAAC,aAAa,EAAE,0BAA0B,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAA;IAC1F,CAAC;IAED,MAAM,IAAI,GAAkB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IACjD,OAAO,IAAI,CAAC,YAAY,CAAA;AAC5B,CAAC"}
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEhE,MAAM,iBAAiB,GAAG,kCAAkC,CAAA;AAC5D,MAAM,mBAAmB,GAAG,qCAAqC,CAAA;AACjE,MAAM,eAAe,GAAG,wCAAwC,CAAA;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,4CAA4C,CAAA;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAA;AAE3C,MAAM,UAAU,qBAAqB,CACjC,aAAqB,EACrB,KAAa,EACb,UAAiD,EAAE;IAEnD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAA;IACrE,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC,CAAA;IAChE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QAC/B,SAAS,EAAE,iBAAiB;QAC5B,KAAK;QACL,KAAK,EAAE,KAAK;QACZ,YAAY,EAAE,WAAW;QACzB,cAAc,EAAE,aAAa;QAC7B,qBAAqB,EAAE,MAAM;KAChC,CAAC,CAAA;IACF,OAAO,GAAG,mBAAmB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;AACxD,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,IAAY,EACZ,YAAoB,EACpB,IAAY;IAEZ,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC7B,SAAS,EAAE,iBAAiB;QAC5B,IAAI,EAAE,IAAI;QACV,aAAa,EAAE,YAAY;QAC3B,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC;KACrC,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE;QAC1C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACL,cAAc,EAAE,mCAAmC;SACtD;QACD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,IAAI,QAAQ,CAAC,aAAa,EAAE,0BAA0B,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAA;IAC1F,CAAC;IAED,MAAM,IAAI,GAAkB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IACjD,OAAO,IAAI,CAAC,YAAY,CAAA;AAC5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/todoist-cli",
3
- "version": "1.39.2",
3
+ "version": "1.39.3",
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": "8.1.0",
54
+ "@doist/todoist-sdk": "8.2.1",
55
55
  "@napi-rs/keyring": "1.2.0",
56
56
  "@pnpm/tabtab": "0.5.4",
57
57
  "chalk": "5.6.2",