chirpie 1.0.28 → 1.0.30

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 +93 -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,62 +506,82 @@ 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);
@@ -556,22 +590,26 @@ accountsCommand.command("connect-instagram").description("Connect an Instagram a
556
590
  accountsCommand.command("connect-facebook").description("Connect a Facebook Page via Facebook Login (OAuth)").option(
557
591
  "--reconnect",
558
592
  "Re-run the flow for an already authorized Facebook account, asking again about anything turned down last time"
559
- ).action(async (options) => {
593
+ ).option("--json", "Output raw JSON").action(async (opts, cmd) => {
560
594
  const client = getClient();
561
595
  try {
562
596
  const result = await client.connectFacebookAccount({
563
- reconnect: options.reconnect === true
597
+ reconnect: opts.reconnect === true
564
598
  });
565
- info("Open this URL in your browser to connect your Facebook Page:");
566
- console.log(`
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(`
567
604
  ${result.authorization_url}
568
605
  `);
606
+ }
569
607
  } catch (err) {
570
608
  error(err instanceof Error ? err.message : "Failed to start Facebook connection");
571
609
  process.exit(1);
572
610
  }
573
611
  });
574
- 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) => {
575
613
  const client = getClient();
576
614
  try {
577
615
  let botToken = opts.botToken;
@@ -603,14 +641,18 @@ accountsCommand.command("connect-telegram").description("Connect a Telegram bot
603
641
  bot_token: botToken,
604
642
  chat_id: chatId
605
643
  });
606
- 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
+ }
607
649
  } catch (err) {
608
650
  error(err instanceof Error ? err.message : "Failed to connect Telegram bot");
609
651
  process.exit(1);
610
652
  }
611
653
  });
612
654
  var xKeysCommand = accountsCommand.command("x-keys").description("Manage your own X developer app used to connect X accounts");
613
- 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) => {
614
656
  const client = getClient();
615
657
  try {
616
658
  let clientSecret = opts.clientSecret;
@@ -626,7 +668,7 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
626
668
  client_secret: clientSecret,
627
669
  ...opts.label ? { label: opts.label } : {}
628
670
  });
629
- if (opts.json) {
671
+ if (wantsJson(opts, cmd)) {
630
672
  json(result);
631
673
  } else {
632
674
  success("X developer keys saved.");
@@ -639,11 +681,11 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
639
681
  process.exit(1);
640
682
  }
641
683
  });
642
- 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) => {
643
685
  const client = getClient();
644
686
  try {
645
687
  const status = await client.getXKeysStatus();
646
- if (opts.json) {
688
+ if (wantsJson(opts, cmd)) {
647
689
  json(status);
648
690
  } else if (!status.configured) {
649
691
  info("No X developer app configured. X accounts connect through Chirpie's app.");
@@ -659,11 +701,11 @@ xKeysCommand.command("status").description("Show whether your own X developer ap
659
701
  process.exit(1);
660
702
  }
661
703
  });
662
- 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) => {
663
705
  const client = getClient();
664
706
  try {
665
707
  const result = await client.removeXKeys();
666
- if (opts.json) {
708
+ if (wantsJson(opts, cmd)) {
667
709
  json(result);
668
710
  } else {
669
711
  success(result.message);
@@ -713,11 +755,11 @@ var analyticsCommand = new Command7("analytics").description("Get analytics for
713
755
 
714
756
  // src/commands/keys.ts
715
757
  import { Command as Command8 } from "commander";
716
- 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) => {
717
759
  const client = getClient();
718
760
  try {
719
761
  const keys = await client.listKeys();
720
- if (opts.json) {
762
+ if (wantsJson(opts, cmd)) {
721
763
  json(keys);
722
764
  } else {
723
765
  table(
@@ -737,11 +779,11 @@ var keysCommand = new Command8("keys").description("Manage API keys").option("--
737
779
  process.exit(1);
738
780
  }
739
781
  });
740
- 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) => {
741
783
  const client = getClient();
742
784
  try {
743
785
  const key = await client.createKey(opts.name);
744
- if (opts.json) {
786
+ if (wantsJson(opts, cmd)) {
745
787
  json(key);
746
788
  } else {
747
789
  success("API key created. Save it now; you won't see it again.");
@@ -754,11 +796,15 @@ keysCommand.command("create").description("Create a new API key").option("-n, --
754
796
  process.exit(1);
755
797
  }
756
798
  });
757
- 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) => {
758
800
  const client = getClient();
759
801
  try {
760
802
  await client.revokeKey(id);
761
- success(`Key ${id} revoked`);
803
+ if (wantsJson(opts, cmd)) {
804
+ json({ id, revoked: true });
805
+ } else {
806
+ success(`Key ${id} revoked`);
807
+ }
762
808
  } catch (err) {
763
809
  error(err instanceof Error ? err.message : "Failed to revoke key");
764
810
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chirpie",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
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.26",
47
+ "@chirpie/sdk": "^1.0.27",
48
48
  "commander": "^13"
49
49
  },
50
50
  "devDependencies": {