@shiori-sh/cli 0.4.0 → 0.5.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 (3) hide show
  1. package/README.md +4 -1
  2. package/dist/index.js +95 -54
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -46,8 +46,11 @@ shiori update <id> --read # Mark as read
46
46
  shiori update <id> --unread # Mark as unread
47
47
  shiori update <id> --title "..." # Update title
48
48
  shiori update <id> --restore # Restore from trash
49
+ shiori update --ids <id1,id2,...> --read # Bulk mark as read
50
+ shiori update --ids <id1,id2,...> --unread # Bulk mark as unread
49
51
 
50
52
  shiori delete <id> # Move to trash
53
+ shiori delete --ids <id1,id2,...> # Bulk move to trash
51
54
  shiori trash # List trashed links
52
55
  shiori trash --empty # Permanently delete all trash
53
56
 
@@ -58,7 +61,7 @@ shiori subscriptions remove <id> # Remove a subscription
58
61
  shiori subscriptions sync <id> # Sync a subscription now
59
62
  shiori subscriptions sync <id> --limit 5 # Sync with item limit
60
63
 
61
- shiori me # Show account info
64
+ shiori whoami # Show account info
62
65
  shiori auth --status # Check auth status
63
66
  shiori auth --logout # Remove stored credentials
64
67
  ```
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/commands/auth.ts
4
- import { exec } from "child_process";
4
+ import { execFile } from "child_process";
5
5
  import { hostname } from "os";
6
6
  import { createInterface } from "readline";
7
7
 
@@ -92,7 +92,7 @@ function promptSecret(question) {
92
92
  function openUrl(url) {
93
93
  const platform = process.platform;
94
94
  const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
95
- exec(`${cmd} ${JSON.stringify(url)}`);
95
+ execFile(cmd, [url]);
96
96
  }
97
97
  function sleep(ms) {
98
98
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -290,7 +290,8 @@ function getPositional(args) {
290
290
  "--title",
291
291
  "--summary",
292
292
  "--since",
293
- "--format"
293
+ "--format",
294
+ "--ids"
294
295
  ].includes(args[i])) {
295
296
  i++;
296
297
  }
@@ -361,18 +362,35 @@ Options:
361
362
  // src/commands/delete.ts
362
363
  async function run3(args) {
363
364
  if (hasFlag(args, "--help", "-h")) {
364
- console.log(`shiori delete - Delete a link (move to trash)
365
+ console.log(`shiori delete - Delete links (move to trash)
365
366
 
366
367
  Usage: shiori delete <id> [options]
368
+ shiori delete --ids <id1,id2,...> [options]
367
369
 
368
370
  Options:
369
- --json Output raw JSON
370
- --help, -h Show this help`);
371
+ --ids <ids> Comma-separated list of link IDs for bulk delete
372
+ --json Output raw JSON
373
+ --help, -h Show this help`);
374
+ return;
375
+ }
376
+ const idsFlag = getFlag(args, "--ids");
377
+ if (idsFlag) {
378
+ const ids = idsFlag.split(",").map((id2) => id2.trim()).filter(Boolean);
379
+ if (ids.length === 0) {
380
+ console.error("No valid IDs provided.");
381
+ process.exit(1);
382
+ }
383
+ const { data: data2 } = await api("PATCH", "/api/links", { ids, deleted: true });
384
+ if (hasFlag(args, "--json")) {
385
+ console.log(JSON.stringify(data2, null, 2));
386
+ return;
387
+ }
388
+ console.log(`Deleted ${data2.updated} link(s).`);
371
389
  return;
372
390
  }
373
391
  const id = getPositional(args);
374
392
  if (!id) {
375
- console.error("Usage: shiori delete <id>");
393
+ console.error("Usage: shiori delete <id> or shiori delete --ids <id1,id2,...>");
376
394
  process.exit(1);
377
395
  }
378
396
  const { data } = await api("DELETE", `/api/links/${id}`);
@@ -475,36 +493,8 @@ Links: ${data.links.length} of ${data.total} total
475
493
  console.log();
476
494
  }
477
495
 
478
- // src/commands/me.ts
479
- async function run6(args) {
480
- if (hasFlag(args, "--help", "-h")) {
481
- console.log(`shiori me - Show current user info
482
-
483
- Usage: shiori me [options]
484
-
485
- Options:
486
- --json Output raw JSON
487
- --help, -h Show this help`);
488
- return;
489
- }
490
- const { data } = await api("GET", "/api/user/me");
491
- if (hasFlag(args, "--json")) {
492
- console.log(JSON.stringify(data, null, 2));
493
- return;
494
- }
495
- const user = data.user;
496
- console.log(`
497
- Name: ${user.full_name || "--"}`);
498
- const plan = user.subscription?.plan === "subscription" ? "Pro" : user.subscription?.plan || "Free";
499
- console.log(` Plan: ${plan}`);
500
- console.log(
501
- ` Member since: ${new Date(user.created_at).toLocaleDateString("en-US", { month: "long", year: "numeric" })}`
502
- );
503
- console.log();
504
- }
505
-
506
496
  // src/commands/save.ts
507
- async function run7(args) {
497
+ async function run6(args) {
508
498
  if (hasFlag(args, "--help", "-h")) {
509
499
  console.log(`shiori save - Save a new link
510
500
 
@@ -539,7 +529,7 @@ Options:
539
529
  }
540
530
 
541
531
  // src/commands/search.ts
542
- async function run8(args) {
532
+ async function run7(args) {
543
533
  if (hasFlag(args, "--help", "-h")) {
544
534
  console.log(`shiori search - Search saved links
545
535
 
@@ -606,7 +596,7 @@ Examples:
606
596
  shiori subscriptions add https://example.com --sync
607
597
  shiori subscriptions remove <id>
608
598
  shiori subscriptions sync <id> --limit 5`;
609
- async function run9(args) {
599
+ async function run8(args) {
610
600
  if (hasFlag(args, "--help", "-h") && !args[0]) {
611
601
  console.log(HELP);
612
602
  return;
@@ -745,7 +735,7 @@ Options:
745
735
  }
746
736
 
747
737
  // src/commands/trash.ts
748
- async function run10(args) {
738
+ async function run9(args) {
749
739
  if (hasFlag(args, "--help", "-h")) {
750
740
  console.log(`shiori trash - List or empty the trash
751
741
 
@@ -796,22 +786,44 @@ Trashed links: ${data.links.length} of ${data.total} total
796
786
  }
797
787
 
798
788
  // src/commands/update.ts
799
- async function run11(args) {
789
+ async function run10(args) {
800
790
  if (hasFlag(args, "--help", "-h")) {
801
- console.log(`shiori update - Update a link
791
+ console.log(`shiori update - Update links
802
792
 
803
793
  Usage: shiori update <id> [options]
794
+ shiori update --ids <id1,id2,...> --read|--unread [options]
804
795
 
805
796
  Options:
797
+ --ids <ids> Comma-separated list of link IDs for bulk update
806
798
  --read Mark as read
807
799
  --unread Mark as unread
808
- --title <title> Update title
809
- --summary <text> Update summary
810
- --restore Restore from trash
800
+ --title <title> Update title (single link only)
801
+ --summary <text> Update summary (single link only)
802
+ --restore Restore from trash (single link only)
811
803
  --json Output raw JSON
812
804
  --help, -h Show this help`);
813
805
  return;
814
806
  }
807
+ const idsFlag = getFlag(args, "--ids");
808
+ if (idsFlag) {
809
+ const ids = idsFlag.split(",").map((id2) => id2.trim()).filter(Boolean);
810
+ if (ids.length === 0) {
811
+ console.error("No valid IDs provided.");
812
+ process.exit(1);
813
+ }
814
+ if (!hasFlag(args, "--read") && !hasFlag(args, "--unread")) {
815
+ console.error("Bulk update requires --read or --unread.");
816
+ process.exit(1);
817
+ }
818
+ const read = hasFlag(args, "--read");
819
+ const { data: data2 } = await api("PATCH", "/api/links", { ids, read });
820
+ if (hasFlag(args, "--json")) {
821
+ console.log(JSON.stringify(data2, null, 2));
822
+ return;
823
+ }
824
+ console.log(`Updated ${data2.updated} link(s).`);
825
+ return;
826
+ }
815
827
  const id = getPositional(args);
816
828
  if (!id) {
817
829
  console.error("Usage: shiori update <id> [--read | --unread | --title <title> | --restore]");
@@ -845,6 +857,34 @@ Options:
845
857
  console.log(data.message || "Updated.");
846
858
  }
847
859
 
860
+ // src/commands/whoami.ts
861
+ async function run11(args) {
862
+ if (hasFlag(args, "--help", "-h")) {
863
+ console.log(`shiori whoami - Show current user info
864
+
865
+ Usage: shiori whoami [options]
866
+
867
+ Options:
868
+ --json Output raw JSON
869
+ --help, -h Show this help`);
870
+ return;
871
+ }
872
+ const { data } = await api("GET", "/api/user/me");
873
+ if (hasFlag(args, "--json")) {
874
+ console.log(JSON.stringify(data, null, 2));
875
+ return;
876
+ }
877
+ const user = data.user;
878
+ console.log(`
879
+ Name: ${user.full_name || "--"}`);
880
+ const plan = user.subscription?.plan === "subscription" ? "Pro" : user.subscription?.plan || "Free";
881
+ console.log(` Plan: ${plan}`);
882
+ console.log(
883
+ ` Member since: ${new Date(user.created_at).toLocaleDateString("en-US", { month: "long", year: "numeric" })}`
884
+ );
885
+ console.log();
886
+ }
887
+
848
888
  // src/error-report.ts
849
889
  function reportError(command, error) {
850
890
  const raw = error instanceof Error ? error.message : String(error);
@@ -854,7 +894,7 @@ function reportError(command, error) {
854
894
  method: "POST",
855
895
  headers: { "Content-Type": "application/json" },
856
896
  body: JSON.stringify({
857
- version: "0.4.0",
897
+ version: "0.5.0",
858
898
  command,
859
899
  error: message,
860
900
  platform: process.platform
@@ -896,15 +936,15 @@ async function checkForUpdate(currentVersion, isJson) {
896
936
  var COMMANDS = {
897
937
  auth: { run, desc: "Authenticate with Shiori (browser or API key)" },
898
938
  list: { run: run5, desc: "List saved links" },
899
- search: { run: run8, desc: "Search saved links" },
939
+ search: { run: run7, desc: "Search saved links" },
900
940
  get: { run: run4, desc: "Get a link by ID (includes content)" },
901
941
  content: { run: run2, desc: "Print link content as markdown" },
902
- save: { run: run7, desc: "Save a new link" },
903
- update: { run: run11, desc: "Update a link" },
942
+ save: { run: run6, desc: "Save a new link" },
943
+ update: { run: run10, desc: "Update a link" },
904
944
  delete: { run: run3, desc: "Delete a link (move to trash)" },
905
- trash: { run: run10, desc: "List or empty the trash" },
906
- subscriptions: { run: run9, desc: "Manage RSS subscriptions" },
907
- me: { run: run6, desc: "Show current user info" }
945
+ trash: { run: run9, desc: "List or empty the trash" },
946
+ subscriptions: { run: run8, desc: "Manage RSS subscriptions" },
947
+ whoami: { run: run11, desc: "Show current user info" }
908
948
  };
909
949
  function printHelp() {
910
950
  console.log(`shiori - Manage your Shiori link library from the terminal
@@ -923,7 +963,8 @@ Get started:
923
963
  shiori list List your recent links
924
964
  shiori save <url> Save a new link
925
965
  shiori search <query> Search your links
926
- shiori content <id> Print markdown content (pipe to other tools)`);
966
+ shiori content <id> Print markdown content (pipe to other tools)
967
+ shiori whoami Show your account info`);
927
968
  }
928
969
  async function main() {
929
970
  const args = process.argv.slice(2);
@@ -933,7 +974,7 @@ async function main() {
933
974
  return;
934
975
  }
935
976
  if (command === "--version" || command === "-v") {
936
- console.log("0.4.0");
977
+ console.log("0.5.0");
937
978
  return;
938
979
  }
939
980
  const cmd = COMMANDS[command];
@@ -946,7 +987,7 @@ async function main() {
946
987
  const cmdArgs = args.slice(1);
947
988
  const isJson = cmdArgs.includes("--json");
948
989
  await cmd.run(cmdArgs);
949
- checkForUpdate("0.4.0", isJson).catch(() => {
990
+ checkForUpdate("0.5.0", isJson).catch(() => {
950
991
  });
951
992
  }
952
993
  main().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shiori-sh/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "CLI for managing your Shiori link library",
5
5
  "author": "Brian Lovin",
6
6
  "license": "MIT",