chirpie 1.0.27 → 1.0.29

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 (2) hide show
  1. package/dist/index.js +98 -47
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -279,7 +279,15 @@ var threadCommand = new Command4("thread").description("Create a thread").argume
279
279
 
280
280
  // src/commands/posts.ts
281
281
  import { Command as Command5 } from "commander";
282
- var postsCommand = new Command5("posts").description("List, get, or delete posts").option("--status <status>", "Filter by status").option("--account <id>", "Filter by account").option("--limit <n>", "Limit results", "20").option("--json", "Output raw JSON").action(async (opts) => {
282
+
283
+ // src/lib/flags.ts
284
+ function wantsJson(opts, cmd) {
285
+ if (opts?.json) return true;
286
+ return Boolean(cmd?.optsWithGlobals?.().json);
287
+ }
288
+
289
+ // src/commands/posts.ts
290
+ var postsCommand = new Command5("posts").description("List, get, or delete posts").option("--status <status>", "Filter by status").option("--account <id>", "Filter by account").option("--limit <n>", "Limit results", "20").option("--json", "Output raw JSON").action(async (opts, cmd) => {
283
291
  const client = getClient();
284
292
  try {
285
293
  const posts = await client.listPosts({
@@ -287,7 +295,7 @@ var postsCommand = new Command5("posts").description("List, get, or delete posts
287
295
  account_id: opts.account,
288
296
  limit: parseInt(opts.limit)
289
297
  });
290
- if (opts.json) {
298
+ if (wantsJson(opts, cmd)) {
291
299
  json(posts);
292
300
  } else {
293
301
  table(
@@ -304,11 +312,11 @@ var postsCommand = new Command5("posts").description("List, get, or delete posts
304
312
  process.exit(1);
305
313
  }
306
314
  });
307
- postsCommand.command("get <id>").description("Get a post by ID").option("--json", "Output raw JSON").action(async (id, opts) => {
315
+ postsCommand.command("get <id>").description("Get a post by ID").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
308
316
  const client = getClient();
309
317
  try {
310
318
  const post = await client.getPost(id);
311
- if (opts.json) {
319
+ if (wantsJson(opts, cmd)) {
312
320
  json(post);
313
321
  } else {
314
322
  console.log(`ID: ${post.id}`);
@@ -326,12 +334,14 @@ postsCommand.command("get <id>").description("Get a post by ID").option("--json"
326
334
  });
327
335
  postsCommand.command("delete <id>").description(
328
336
  "Delete a post (deleting any post of a scheduled thread cancels the thread)"
329
- ).action(async (id) => {
337
+ ).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
330
338
  const client = getClient();
331
339
  try {
332
340
  const result = await client.deletePost(id);
333
341
  const cancelled = result.cancelled_ids ?? [];
334
- if (cancelled.length > 1) {
342
+ if (wantsJson(opts, cmd)) {
343
+ json(result);
344
+ } else if (cancelled.length > 1) {
335
345
  success(
336
346
  `Scheduled thread canceled (${cancelled.length} posts): ${cancelled.join(", ")}`
337
347
  );
@@ -394,12 +404,12 @@ async function readSecretFromStdin(prompt) {
394
404
  stdin.on("data", onData);
395
405
  });
396
406
  }
397
- var accountsCommand = new Command6("accounts").description("List connected social accounts (X, Bluesky, LinkedIn, Threads, Mastodon, Instagram, Facebook, Telegram, Pinterest, TikTok, YouTube, and Google Business Profile)").option("--json", "Output raw JSON").action(async (opts) => {
407
+ var accountsCommand = new Command6("accounts").description("List connected social accounts (X, Bluesky, LinkedIn, Threads, Mastodon, Instagram, Facebook, Telegram, Pinterest, TikTok, YouTube, and Google Business Profile)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
398
408
  const client = getClient();
399
409
  try {
400
410
  const list = await client.listAccountsWithLimits();
401
411
  const { accounts, accounts_limit, accounts_active } = list;
402
- if (opts.json) {
412
+ if (wantsJson(opts, cmd)) {
403
413
  json(list);
404
414
  } else {
405
415
  info(
@@ -426,11 +436,11 @@ var accountsCommand = new Command6("accounts").description("List connected socia
426
436
  process.exit(1);
427
437
  }
428
438
  });
429
- accountsCommand.command("activate").argument("<id>", "Account ID (from `chirpie accounts`)").description("Activate a connected account so it can publish").option("--json", "Output raw JSON").action(async (id, opts) => {
439
+ accountsCommand.command("activate").argument("<id>", "Account ID (from `chirpie accounts`)").description("Activate a connected account so it can publish").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
430
440
  const client = getClient();
431
441
  try {
432
442
  const account = await client.activateAccount(id);
433
- if (opts.json) {
443
+ if (wantsJson(opts, cmd)) {
434
444
  json(account);
435
445
  } else {
436
446
  success(`Activated ${account.display_name ?? account.username} (${account.platform})`);
@@ -442,11 +452,11 @@ accountsCommand.command("activate").argument("<id>", "Account ID (from `chirpie
442
452
  });
443
453
  accountsCommand.command("deactivate").argument("<id>", "Account ID (from `chirpie accounts`)").description(
444
454
  "Deactivate a connected account (stays connected, frees a plan slot, cancels its scheduled posts)"
445
- ).option("--json", "Output raw JSON").action(async (id, opts) => {
455
+ ).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
446
456
  const client = getClient();
447
457
  try {
448
458
  const account = await client.deactivateAccount(id);
449
- if (opts.json) {
459
+ if (wantsJson(opts, cmd)) {
450
460
  json(account);
451
461
  } else {
452
462
  success(
@@ -463,20 +473,24 @@ accountsCommand.command("deactivate").argument("<id>", "Account ID (from `chirpi
463
473
  process.exit(1);
464
474
  }
465
475
  });
466
- accountsCommand.command("connect-x").description("Connect a new X/Twitter account via OAuth").action(async () => {
476
+ accountsCommand.command("connect-x").description("Connect a new X/Twitter account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
467
477
  const client = getClient();
468
478
  try {
469
479
  const result = await client.connectXAccount();
470
- info("Open this URL in your browser to connect your X account:");
471
- console.log(`
480
+ if (wantsJson(opts, cmd)) {
481
+ json(result);
482
+ } else {
483
+ info("Open this URL in your browser to connect your X account:");
484
+ console.log(`
472
485
  ${result.authorization_url}
473
486
  `);
487
+ }
474
488
  } catch (err) {
475
489
  error(err instanceof Error ? err.message : "Failed to start connection");
476
490
  process.exit(1);
477
491
  }
478
492
  });
479
- accountsCommand.command("connect-bluesky").description("Connect a Bluesky account via app password").requiredOption("--handle <handle>", "Bluesky handle (e.g. user.bsky.social)").option("--app-password <password>", "App password (omit to enter securely via prompt)").action(async (opts) => {
493
+ accountsCommand.command("connect-bluesky").description("Connect a Bluesky account via app password").requiredOption("--handle <handle>", "Bluesky handle (e.g. user.bsky.social)").option("--app-password <password>", "App password (omit to enter securely via prompt)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
480
494
  const client = getClient();
481
495
  try {
482
496
  let appPassword = opts.appPassword;
@@ -492,81 +506,110 @@ accountsCommand.command("connect-bluesky").description("Connect a Bluesky accoun
492
506
  identifier: opts.handle,
493
507
  app_password: appPassword
494
508
  });
495
- info(`Connected Bluesky account: ${result.username} (${result.platform_user_id})`);
509
+ if (wantsJson(opts, cmd)) {
510
+ json(result);
511
+ } else {
512
+ info(`Connected Bluesky account: ${result.username} (${result.platform_user_id})`);
513
+ }
496
514
  } catch (err) {
497
515
  error(err instanceof Error ? err.message : "Failed to connect Bluesky account");
498
516
  process.exit(1);
499
517
  }
500
518
  });
501
- accountsCommand.command("connect-linkedin").description("Connect a LinkedIn account via OAuth").action(async () => {
519
+ accountsCommand.command("connect-linkedin").description("Connect a LinkedIn account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
502
520
  const client = getClient();
503
521
  try {
504
522
  const result = await client.connectLinkedInAccount();
505
- info("Open this URL in your browser to connect your LinkedIn account:");
506
- console.log(`
523
+ if (wantsJson(opts, cmd)) {
524
+ json(result);
525
+ } else {
526
+ info("Open this URL in your browser to connect your LinkedIn account:");
527
+ console.log(`
507
528
  ${result.authorization_url}
508
529
  `);
530
+ }
509
531
  } catch (err) {
510
532
  error(err instanceof Error ? err.message : "Failed to start LinkedIn connection");
511
533
  process.exit(1);
512
534
  }
513
535
  });
514
- accountsCommand.command("connect-threads").description("Connect a Threads (Meta) account via OAuth").action(async () => {
536
+ accountsCommand.command("connect-threads").description("Connect a Threads (Meta) account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
515
537
  const client = getClient();
516
538
  try {
517
539
  const result = await client.connectThreadsAccount();
518
- info("Open this URL in your browser to connect your Threads account:");
519
- console.log(`
540
+ if (wantsJson(opts, cmd)) {
541
+ json(result);
542
+ } else {
543
+ info("Open this URL in your browser to connect your Threads account:");
544
+ console.log(`
520
545
  ${result.authorization_url}
521
546
  `);
547
+ }
522
548
  } catch (err) {
523
549
  error(err instanceof Error ? err.message : "Failed to start Threads connection");
524
550
  process.exit(1);
525
551
  }
526
552
  });
527
- accountsCommand.command("connect-mastodon").description("Connect a Mastodon account via OAuth").requiredOption("--instance <url>", "Mastodon instance URL (e.g. https://mastodon.social)").action(async (opts) => {
553
+ accountsCommand.command("connect-mastodon").description("Connect a Mastodon account via OAuth").requiredOption("--instance <url>", "Mastodon instance URL (e.g. https://mastodon.social)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
528
554
  const client = getClient();
529
555
  try {
530
556
  const result = await client.connectMastodonAccount({
531
557
  platform: "mastodon",
532
558
  instance_url: opts.instance
533
559
  });
534
- info("Open this URL in your browser to connect your Mastodon account:");
535
- console.log(`
560
+ if (wantsJson(opts, cmd)) {
561
+ json(result);
562
+ } else {
563
+ info("Open this URL in your browser to connect your Mastodon account:");
564
+ console.log(`
536
565
  ${result.authorization_url}
537
566
  `);
567
+ }
538
568
  } catch (err) {
539
569
  error(err instanceof Error ? err.message : "Failed to start Mastodon connection");
540
570
  process.exit(1);
541
571
  }
542
572
  });
543
- accountsCommand.command("connect-instagram").description("Connect an Instagram account via Instagram Login (OAuth)").action(async () => {
573
+ accountsCommand.command("connect-instagram").description("Connect an Instagram account via Instagram Login (OAuth)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
544
574
  const client = getClient();
545
575
  try {
546
576
  const result = await client.connectInstagramAccount();
547
- info("Open this URL in your browser to connect your Instagram account:");
548
- console.log(`
577
+ if (wantsJson(opts, cmd)) {
578
+ json(result);
579
+ } else {
580
+ info("Open this URL in your browser to connect your Instagram account:");
581
+ console.log(`
549
582
  ${result.authorization_url}
550
583
  `);
584
+ }
551
585
  } catch (err) {
552
586
  error(err instanceof Error ? err.message : "Failed to start Instagram connection");
553
587
  process.exit(1);
554
588
  }
555
589
  });
556
- accountsCommand.command("connect-facebook").description("Connect a Facebook Page via Facebook Login (OAuth)").action(async () => {
590
+ accountsCommand.command("connect-facebook").description("Connect a Facebook Page via Facebook Login (OAuth)").option(
591
+ "--reconnect",
592
+ "Re-run the flow for an already authorized Facebook account, asking again about anything turned down last time"
593
+ ).option("--json", "Output raw JSON").action(async (opts, cmd) => {
557
594
  const client = getClient();
558
595
  try {
559
- const result = await client.connectFacebookAccount();
560
- info("Open this URL in your browser to connect your Facebook Page:");
561
- console.log(`
596
+ const result = await client.connectFacebookAccount({
597
+ reconnect: opts.reconnect === true
598
+ });
599
+ if (wantsJson(opts, cmd)) {
600
+ json(result);
601
+ } else {
602
+ info("Open this URL in your browser to connect your Facebook Page:");
603
+ console.log(`
562
604
  ${result.authorization_url}
563
605
  `);
606
+ }
564
607
  } catch (err) {
565
608
  error(err instanceof Error ? err.message : "Failed to start Facebook connection");
566
609
  process.exit(1);
567
610
  }
568
611
  });
569
- accountsCommand.command("connect-telegram").description("Connect a Telegram bot to a channel or group").option("--bot-token <token>", "Telegram bot token (omit to enter securely via prompt)").option("--chat-id <id>", "Telegram chat ID (omit to enter via prompt)").action(async (opts) => {
612
+ accountsCommand.command("connect-telegram").description("Connect a Telegram bot to a channel or group").option("--bot-token <token>", "Telegram bot token (omit to enter securely via prompt)").option("--chat-id <id>", "Telegram chat ID (omit to enter via prompt)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
570
613
  const client = getClient();
571
614
  try {
572
615
  let botToken = opts.botToken;
@@ -598,14 +641,18 @@ accountsCommand.command("connect-telegram").description("Connect a Telegram bot
598
641
  bot_token: botToken,
599
642
  chat_id: chatId
600
643
  });
601
- info(`Connected Telegram bot: ${result.username} (${result.platform_user_id})`);
644
+ if (wantsJson(opts, cmd)) {
645
+ json(result);
646
+ } else {
647
+ info(`Connected Telegram bot: ${result.username} (${result.platform_user_id})`);
648
+ }
602
649
  } catch (err) {
603
650
  error(err instanceof Error ? err.message : "Failed to connect Telegram bot");
604
651
  process.exit(1);
605
652
  }
606
653
  });
607
654
  var xKeysCommand = accountsCommand.command("x-keys").description("Manage your own X developer app used to connect X accounts");
608
- xKeysCommand.command("set").description("Set or replace your own X developer app credentials").requiredOption("--client-id <id>", "OAuth 2.0 Client ID from developer.x.com").option("--client-secret <secret>", "OAuth 2.0 Client Secret (omit to enter securely via prompt)").option("--label <label>", "Optional name for the app").option("--json", "Output raw JSON").action(async (opts) => {
655
+ xKeysCommand.command("set").description("Set or replace your own X developer app credentials").requiredOption("--client-id <id>", "OAuth 2.0 Client ID from developer.x.com").option("--client-secret <secret>", "OAuth 2.0 Client Secret (omit to enter securely via prompt)").option("--label <label>", "Optional name for the app").option("--json", "Output raw JSON").action(async (opts, cmd) => {
609
656
  const client = getClient();
610
657
  try {
611
658
  let clientSecret = opts.clientSecret;
@@ -621,7 +668,7 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
621
668
  client_secret: clientSecret,
622
669
  ...opts.label ? { label: opts.label } : {}
623
670
  });
624
- if (opts.json) {
671
+ if (wantsJson(opts, cmd)) {
625
672
  json(result);
626
673
  } else {
627
674
  success("X developer keys saved.");
@@ -634,11 +681,11 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
634
681
  process.exit(1);
635
682
  }
636
683
  });
637
- xKeysCommand.command("status").description("Show whether your own X developer app is configured").option("--json", "Output raw JSON").action(async (opts) => {
684
+ xKeysCommand.command("status").description("Show whether your own X developer app is configured").option("--json", "Output raw JSON").action(async (opts, cmd) => {
638
685
  const client = getClient();
639
686
  try {
640
687
  const status = await client.getXKeysStatus();
641
- if (opts.json) {
688
+ if (wantsJson(opts, cmd)) {
642
689
  json(status);
643
690
  } else if (!status.configured) {
644
691
  info("No X developer app configured. X accounts connect through Chirpie's app.");
@@ -654,11 +701,11 @@ xKeysCommand.command("status").description("Show whether your own X developer ap
654
701
  process.exit(1);
655
702
  }
656
703
  });
657
- xKeysCommand.command("remove").description("Remove your own X developer app credentials").option("--json", "Output raw JSON").action(async (opts) => {
704
+ xKeysCommand.command("remove").description("Remove your own X developer app credentials").option("--json", "Output raw JSON").action(async (opts, cmd) => {
658
705
  const client = getClient();
659
706
  try {
660
707
  const result = await client.removeXKeys();
661
- if (opts.json) {
708
+ if (wantsJson(opts, cmd)) {
662
709
  json(result);
663
710
  } else {
664
711
  success(result.message);
@@ -708,11 +755,11 @@ var analyticsCommand = new Command7("analytics").description("Get analytics for
708
755
 
709
756
  // src/commands/keys.ts
710
757
  import { Command as Command8 } from "commander";
711
- var keysCommand = new Command8("keys").description("Manage API keys").option("--json", "Output raw JSON").action(async (opts) => {
758
+ var keysCommand = new Command8("keys").description("Manage API keys").option("--json", "Output raw JSON").action(async (opts, cmd) => {
712
759
  const client = getClient();
713
760
  try {
714
761
  const keys = await client.listKeys();
715
- if (opts.json) {
762
+ if (wantsJson(opts, cmd)) {
716
763
  json(keys);
717
764
  } else {
718
765
  table(
@@ -732,11 +779,11 @@ var keysCommand = new Command8("keys").description("Manage API keys").option("--
732
779
  process.exit(1);
733
780
  }
734
781
  });
735
- keysCommand.command("create").description("Create a new API key").option("-n, --name <name>", "Key name").option("--json", "Output raw JSON").action(async (opts) => {
782
+ keysCommand.command("create").description("Create a new API key").option("-n, --name <name>", "Key name").option("--json", "Output raw JSON").action(async (opts, cmd) => {
736
783
  const client = getClient();
737
784
  try {
738
785
  const key = await client.createKey(opts.name);
739
- if (opts.json) {
786
+ if (wantsJson(opts, cmd)) {
740
787
  json(key);
741
788
  } else {
742
789
  success("API key created. Save it now; you won't see it again.");
@@ -749,11 +796,15 @@ keysCommand.command("create").description("Create a new API key").option("-n, --
749
796
  process.exit(1);
750
797
  }
751
798
  });
752
- keysCommand.command("revoke <id>").description("Revoke an API key").action(async (id) => {
799
+ keysCommand.command("revoke <id>").description("Revoke an API key").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
753
800
  const client = getClient();
754
801
  try {
755
802
  await client.revokeKey(id);
756
- success(`Key ${id} revoked`);
803
+ if (wantsJson(opts, cmd)) {
804
+ json({ id, revoked: true });
805
+ } else {
806
+ success(`Key ${id} revoked`);
807
+ }
757
808
  } catch (err) {
758
809
  error(err instanceof Error ? err.message : "Failed to revoke key");
759
810
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chirpie",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "Chirpie CLI: post to social media from the command line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -44,7 +44,7 @@
44
44
  ],
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
- "@chirpie/sdk": "^1.0.25",
47
+ "@chirpie/sdk": "^1.0.26",
48
48
  "commander": "^13"
49
49
  },
50
50
  "devDependencies": {