@doist/automations-cli 1.10.0 → 1.11.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.
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import { fileURLToPath } from "node:url";
15
15
  // package.json
16
16
  var package_default = {
17
17
  name: "@doist/automations-cli",
18
- version: "1.10.0",
18
+ version: "1.11.1",
19
19
  description: "Command-line client for Todoist Automations",
20
20
  type: "module",
21
21
  bin: {
@@ -59,8 +59,8 @@ var package_default = {
59
59
  postinstall: "node scripts/refresh-skills.mjs"
60
60
  },
61
61
  dependencies: {
62
- "@doist/cli-core": "1.5.0",
63
- "@napi-rs/keyring": "1.3.0",
62
+ "@doist/cli-core": "1.6.0",
63
+ "@napi-rs/keyring": "2.0.0",
64
64
  ai: "7.0.77",
65
65
  commander: "15.0.0",
66
66
  oauth4webapi: "3.8.8",
@@ -19906,9 +19906,9 @@ var AdminAccessResponseSchema = external_exports.object({
19906
19906
  allowed: external_exports.literal(true)
19907
19907
  });
19908
19908
  var adminTestEmailTemplatePaths = [
19909
- "/emails/todoist/automations/test",
19910
- "/emails/todoist/automations/failed",
19911
- "/emails/todoist/automations/input_required"
19909
+ "/emails/automations/test",
19910
+ "/emails/automations/failed",
19911
+ "/emails/automations/input_required"
19912
19912
  ];
19913
19913
  var sendAdminTestEmailRequestSchema = external_exports.object({
19914
19914
  templatePath: external_exports.enum(adminTestEmailTemplatePaths),
@@ -22548,6 +22548,40 @@ var WORKSPACE_PLANS = ["STARTER", "BUSINESS"];
22548
22548
  var WORKSPACE_ROLES = ["ADMIN", "MEMBER", "GUEST"];
22549
22549
  var WORKSPACE_ACCESS_LEVELS = ["full", "locked"];
22550
22550
 
22551
+ // ../../packages/core/dist/esm/schemas/schedule-input.js
22552
+ function resolveScheduleInput(input2, labels) {
22553
+ const chooseOne = `Choose exactly one of ${labels.cron} or ${labels.interval}.`;
22554
+ if (input2.cron !== void 0) {
22555
+ if (input2.interval !== void 0)
22556
+ throw new Error(chooseOne);
22557
+ if (!input2.timezone)
22558
+ throw new Error(`${labels.timezone} is required with ${labels.cron}.`);
22559
+ const value = parseScheduleValue({ expression: input2.cron, timezone: input2.timezone });
22560
+ assertKnownTimezone(input2.timezone);
22561
+ return value;
22562
+ }
22563
+ if (input2.interval !== void 0) {
22564
+ if (input2.timezone !== void 0) {
22565
+ throw new Error(`${labels.timezone} can only be used with ${labels.cron}.`);
22566
+ }
22567
+ return parseScheduleValue(input2.interval);
22568
+ }
22569
+ throw new Error(chooseOne);
22570
+ }
22571
+ function parseScheduleValue(value) {
22572
+ const result = scheduleValueSchema.safeParse(value);
22573
+ if (result.success)
22574
+ return result.data;
22575
+ throw new Error(result.error.issues[0]?.message ?? "Invalid schedule value.");
22576
+ }
22577
+ function assertKnownTimezone(timezone) {
22578
+ try {
22579
+ new Intl.DateTimeFormat("en", { timeZone: timezone });
22580
+ } catch {
22581
+ throw new Error(`Unknown IANA timezone "${timezone}".`);
22582
+ }
22583
+ }
22584
+
22551
22585
  // ../../packages/core/dist/esm/schemas/notification.schema.js
22552
22586
  var NOTIFICATION_TYPES = ["notification", "prompt"];
22553
22587
  var INFO_NOTIFICATION_STATUSES = ["active"];
@@ -25197,10 +25231,6 @@ function createAutomationsTokenStore(options = {}) {
25197
25231
  });
25198
25232
  }
25199
25233
 
25200
- // src/commands/auth/login.ts
25201
- import { formatJson, formatNdjson } from "@doist/cli-core";
25202
- import { attachLoginCommand } from "@doist/cli-core/auth";
25203
-
25204
25234
  // src/lib/credentials.ts
25205
25235
  import { CliError, getConfigPath as getConfigPath3, getErrorMessage as getErrorMessage3 } from "@doist/cli-core";
25206
25236
  import { refreshAccessToken } from "@doist/cli-core/auth";
@@ -25408,14 +25438,20 @@ async function resolveCredential(options = {}) {
25408
25438
  scope: snapshot.account.scope
25409
25439
  };
25410
25440
  }
25441
+ function createTokenRefreshOptions() {
25442
+ return {
25443
+ provider: createAutomationsAuthProvider(),
25444
+ skewMs: DEFAULT_TOKEN_LIFETIME_MS,
25445
+ lockPath: `${getConfigPath3(SERVICE_NAME)}.refresh.lock`,
25446
+ handshake: () => ({ env: getEnvironment().name })
25447
+ };
25448
+ }
25411
25449
  async function freshAccessToken(store2, snapshot, minimumTokenLifetimeMs) {
25412
25450
  try {
25413
25451
  const result = await refreshAccessToken({
25414
25452
  store: store2,
25415
- provider: createAutomationsAuthProvider(),
25416
- skewMs: minimumTokenLifetimeMs ?? DEFAULT_TOKEN_LIFETIME_MS,
25417
- lockPath: `${getConfigPath3(SERVICE_NAME)}.refresh.lock`,
25418
- handshake: { env: getEnvironment().name }
25453
+ ...createTokenRefreshOptions(),
25454
+ skewMs: minimumTokenLifetimeMs ?? DEFAULT_TOKEN_LIFETIME_MS
25419
25455
  });
25420
25456
  return result.bundle.accessToken;
25421
25457
  } catch (error62) {
@@ -25530,6 +25566,10 @@ function readProperty(error62, key) {
25530
25566
  return error62[key];
25531
25567
  }
25532
25568
 
25569
+ // src/commands/auth/login.ts
25570
+ import { formatJson, formatNdjson } from "@doist/cli-core";
25571
+ import { attachLoginCommand } from "@doist/cli-core/auth";
25572
+
25533
25573
  // src/lib/api-configuration.ts
25534
25574
  function getGlobalOptions(command) {
25535
25575
  return command.optsWithGlobals();
@@ -26194,6 +26234,9 @@ function attachAutomationsStatusCommand(auth, store2) {
26194
26234
  return attachStatusCommand(auth, {
26195
26235
  store: store2,
26196
26236
  description: "Show which account the CLI is signed in as",
26237
+ // Rotate first when the token is near expiry, so the expiry shown is
26238
+ // the one commands will actually run with.
26239
+ refresh: createTokenRefreshOptions(),
26197
26240
  fetchLive: async ({ account, bundle }) => {
26198
26241
  expiresAt = bundle?.accessTokenExpiresAt;
26199
26242
  return account;
@@ -26245,7 +26288,10 @@ function registerAuthCommand(program) {
26245
26288
  attachTokenViewCommand(tokenCmd, {
26246
26289
  name: "view",
26247
26290
  store: store2,
26248
- description: "Print the stored access token for use in scripts"
26291
+ description: "Print the stored access token for use in scripts",
26292
+ // Rotate first when the token is near expiry: the output goes straight
26293
+ // into scripts and MCP servers, so a stale token here is a dead one.
26294
+ refresh: createTokenRefreshOptions()
26249
26295
  });
26250
26296
  attachRefreshTokenViewCommand(auth, { store: store2 });
26251
26297
  }
@@ -26813,25 +26859,11 @@ async function* streamAutomationList(options, fetchPage) {
26813
26859
  }
26814
26860
  }
26815
26861
  function resolveScheduleValue(options) {
26816
- if (options.cron !== void 0) {
26817
- if (options.interval !== void 0) {
26818
- throw new Error("Choose exactly one of --cron or --interval.");
26819
- }
26820
- if (!options.timezone) throw new Error("--timezone is required with --cron.");
26821
- return parseScheduleValue({ expression: options.cron, timezone: options.timezone });
26822
- }
26823
- if (options.interval !== void 0) {
26824
- if (options.timezone !== void 0) {
26825
- throw new Error("--timezone can only be used with --cron.");
26826
- }
26827
- return parseScheduleValue(options.interval);
26828
- }
26829
- throw new Error("Choose exactly one of --cron or --interval.");
26830
- }
26831
- function parseScheduleValue(value) {
26832
- const result = scheduleValueSchema.safeParse(value);
26833
- if (result.success) return result.data;
26834
- throw new Error(result.error.issues[0]?.message ?? "Invalid schedule value.");
26862
+ return resolveScheduleInput(options, {
26863
+ cron: "--cron",
26864
+ timezone: "--timezone",
26865
+ interval: "--interval"
26866
+ });
26835
26867
  }
26836
26868
 
26837
26869
  // src/commands/chat/index.ts