cc98-cli 0.1.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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +246 -0
  3. package/dist/api/client.d.ts +47 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +188 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/api/endpoints.d.ts +48 -0
  8. package/dist/api/endpoints.d.ts.map +1 -0
  9. package/dist/api/endpoints.js +53 -0
  10. package/dist/api/endpoints.js.map +1 -0
  11. package/dist/api/types.d.ts +14 -0
  12. package/dist/api/types.d.ts.map +1 -0
  13. package/dist/api/types.js +2 -0
  14. package/dist/api/types.js.map +1 -0
  15. package/dist/cli/commands/account.d.ts +2 -0
  16. package/dist/cli/commands/account.d.ts.map +1 -0
  17. package/dist/cli/commands/account.js +81 -0
  18. package/dist/cli/commands/account.js.map +1 -0
  19. package/dist/cli/commands/board.d.ts +2 -0
  20. package/dist/cli/commands/board.d.ts.map +1 -0
  21. package/dist/cli/commands/board.js +61 -0
  22. package/dist/cli/commands/board.js.map +1 -0
  23. package/dist/cli/commands/forum.d.ts +2 -0
  24. package/dist/cli/commands/forum.d.ts.map +1 -0
  25. package/dist/cli/commands/forum.js +38 -0
  26. package/dist/cli/commands/forum.js.map +1 -0
  27. package/dist/cli/commands/login.d.ts +2 -0
  28. package/dist/cli/commands/login.d.ts.map +1 -0
  29. package/dist/cli/commands/login.js +98 -0
  30. package/dist/cli/commands/login.js.map +1 -0
  31. package/dist/cli/commands/logout.d.ts +2 -0
  32. package/dist/cli/commands/logout.d.ts.map +1 -0
  33. package/dist/cli/commands/logout.js +20 -0
  34. package/dist/cli/commands/logout.js.map +1 -0
  35. package/dist/cli/commands/me.d.ts +2 -0
  36. package/dist/cli/commands/me.d.ts.map +1 -0
  37. package/dist/cli/commands/me.js +9 -0
  38. package/dist/cli/commands/me.js.map +1 -0
  39. package/dist/cli/commands/message.d.ts +2 -0
  40. package/dist/cli/commands/message.d.ts.map +1 -0
  41. package/dist/cli/commands/message.js +42 -0
  42. package/dist/cli/commands/message.js.map +1 -0
  43. package/dist/cli/commands/notice.d.ts +2 -0
  44. package/dist/cli/commands/notice.d.ts.map +1 -0
  45. package/dist/cli/commands/notice.js +30 -0
  46. package/dist/cli/commands/notice.js.map +1 -0
  47. package/dist/cli/commands/post.d.ts +2 -0
  48. package/dist/cli/commands/post.d.ts.map +1 -0
  49. package/dist/cli/commands/post.js +37 -0
  50. package/dist/cli/commands/post.js.map +1 -0
  51. package/dist/cli/commands/search.d.ts +2 -0
  52. package/dist/cli/commands/search.d.ts.map +1 -0
  53. package/dist/cli/commands/search.js +13 -0
  54. package/dist/cli/commands/search.js.map +1 -0
  55. package/dist/cli/commands/topic.d.ts +2 -0
  56. package/dist/cli/commands/topic.d.ts.map +1 -0
  57. package/dist/cli/commands/topic.js +196 -0
  58. package/dist/cli/commands/topic.js.map +1 -0
  59. package/dist/cli/commands/user.d.ts +2 -0
  60. package/dist/cli/commands/user.d.ts.map +1 -0
  61. package/dist/cli/commands/user.js +90 -0
  62. package/dist/cli/commands/user.js.map +1 -0
  63. package/dist/cli/context.d.ts +9 -0
  64. package/dist/cli/context.d.ts.map +1 -0
  65. package/dist/cli/context.js +8 -0
  66. package/dist/cli/context.js.map +1 -0
  67. package/dist/cli/options.d.ts +6 -0
  68. package/dist/cli/options.d.ts.map +1 -0
  69. package/dist/cli/options.js +22 -0
  70. package/dist/cli/options.js.map +1 -0
  71. package/dist/cli/parse.d.ts +15 -0
  72. package/dist/cli/parse.d.ts.map +1 -0
  73. package/dist/cli/parse.js +55 -0
  74. package/dist/cli/parse.js.map +1 -0
  75. package/dist/cli/prompt.d.ts +4 -0
  76. package/dist/cli/prompt.d.ts.map +1 -0
  77. package/dist/cli/prompt.js +53 -0
  78. package/dist/cli/prompt.js.map +1 -0
  79. package/dist/cli/router.d.ts +2 -0
  80. package/dist/cli/router.d.ts.map +1 -0
  81. package/dist/cli/router.js +77 -0
  82. package/dist/cli/router.js.map +1 -0
  83. package/dist/main.d.ts +3 -0
  84. package/dist/main.d.ts.map +1 -0
  85. package/dist/main.js +17 -0
  86. package/dist/main.js.map +1 -0
  87. package/dist/storage/cache-store.d.ts +19 -0
  88. package/dist/storage/cache-store.d.ts.map +1 -0
  89. package/dist/storage/cache-store.js +82 -0
  90. package/dist/storage/cache-store.js.map +1 -0
  91. package/dist/storage/paths.d.ts +4 -0
  92. package/dist/storage/paths.d.ts.map +1 -0
  93. package/dist/storage/paths.js +14 -0
  94. package/dist/storage/paths.js.map +1 -0
  95. package/dist/storage/token-store.d.ts +39 -0
  96. package/dist/storage/token-store.d.ts.map +1 -0
  97. package/dist/storage/token-store.js +177 -0
  98. package/dist/storage/token-store.js.map +1 -0
  99. package/dist/tui/ansi.d.ts +16 -0
  100. package/dist/tui/ansi.d.ts.map +1 -0
  101. package/dist/tui/ansi.js +24 -0
  102. package/dist/tui/ansi.js.map +1 -0
  103. package/dist/tui/app.d.ts +2 -0
  104. package/dist/tui/app.d.ts.map +1 -0
  105. package/dist/tui/app.js +1096 -0
  106. package/dist/tui/app.js.map +1 -0
  107. package/dist/tui/cached-client.d.ts +22 -0
  108. package/dist/tui/cached-client.d.ts.map +1 -0
  109. package/dist/tui/cached-client.js +60 -0
  110. package/dist/tui/cached-client.js.map +1 -0
  111. package/dist/tui/terminal.d.ts +21 -0
  112. package/dist/tui/terminal.d.ts.map +1 -0
  113. package/dist/tui/terminal.js +67 -0
  114. package/dist/tui/terminal.js.map +1 -0
  115. package/dist/tui/ubb-renderer.d.ts +7 -0
  116. package/dist/tui/ubb-renderer.d.ts.map +1 -0
  117. package/dist/tui/ubb-renderer.js +102 -0
  118. package/dist/tui/ubb-renderer.js.map +1 -0
  119. package/package.json +39 -0
@@ -0,0 +1,196 @@
1
+ import { createCliContext } from "../context.js";
2
+ import { extractAccountOption } from "../options.js";
3
+ import { extractPageOptions, parseIds, parseNonNegativeInteger, parsePositiveInteger, printJson } from "../parse.js";
4
+ export async function topicCommand(args) {
5
+ const accountOption = extractAccountOption(args);
6
+ const [subcommandOrId, ...rest] = accountOption.args;
7
+ if (!subcommandOrId || subcommandOrId === "--help" || subcommandOrId === "-h" || subcommandOrId === "help") {
8
+ printTopicHelp();
9
+ return;
10
+ }
11
+ const { client } = createCliContext({ account: accountOption.account });
12
+ if (/^\d+$/.test(subcommandOrId)) {
13
+ const topicId = parsePositiveInteger(subcommandOrId, "topic-id");
14
+ const options = parseTopicReadOptions(rest);
15
+ if (options.metaOnly && options.postsOnly) {
16
+ throw new Error("cannot use --meta and --posts together");
17
+ }
18
+ if (options.metaOnly) {
19
+ printJson(await client.getTopic(topicId));
20
+ return;
21
+ }
22
+ if (options.postsOnly) {
23
+ printJson(await client.getTopicPosts(topicId, options.from, options.size));
24
+ return;
25
+ }
26
+ const [topic, posts] = await Promise.all([
27
+ client.getTopic(topicId),
28
+ client.getTopicPosts(topicId, options.from, options.size)
29
+ ]);
30
+ printJson({
31
+ topic,
32
+ posts,
33
+ page: {
34
+ from: options.from,
35
+ size: options.size,
36
+ count: posts.length
37
+ }
38
+ });
39
+ return;
40
+ }
41
+ switch (subcommandOrId) {
42
+ case "new": {
43
+ const page = extractPageOptions(rest, { size: 20 });
44
+ printJson(await client.getNewTopics(page.from, page.size));
45
+ return;
46
+ }
47
+ case "random": {
48
+ const size = parseSizeOnly(rest, 10);
49
+ printJson(await client.getRandomTopics(size));
50
+ return;
51
+ }
52
+ case "recent": {
53
+ const { userId, args: pageArgs } = extractUserOption(rest);
54
+ const page = extractPageOptions(pageArgs, { size: 11 });
55
+ printJson(await client.getRecentTopics(userId, page.from, page.size));
56
+ return;
57
+ }
58
+ case "favorite": {
59
+ const favoriteOptions = parseFavoriteOptions(rest);
60
+ printJson(await client.getFavoriteTopics(favoriteOptions.from, favoriteOptions.size, favoriteOptions.order, favoriteOptions.groupId));
61
+ return;
62
+ }
63
+ case "is-favorite": {
64
+ const topicId = parsePositiveInteger(rest[0], "topic-id");
65
+ printJson(await client.isTopicFavorite(topicId));
66
+ return;
67
+ }
68
+ case "vote": {
69
+ const topicId = parsePositiveInteger(rest[0], "topic-id");
70
+ printJson(await client.getTopicVote(topicId));
71
+ return;
72
+ }
73
+ case "basic":
74
+ printJson(await client.getBasicTopics(parseIds(rest)));
75
+ return;
76
+ case "search": {
77
+ const page = extractPageOptions(rest, { size: 20 });
78
+ const keyword = page.rest.join(" ").trim();
79
+ if (!keyword) {
80
+ throw new Error("usage: cc98 topic search <keyword> [--from n] [--size n]");
81
+ }
82
+ printJson(await client.searchTopics(keyword, page.from, page.size));
83
+ return;
84
+ }
85
+ default:
86
+ throw new Error(`unknown topic command: ${subcommandOrId}`);
87
+ }
88
+ }
89
+ function parseTopicReadOptions(args) {
90
+ let from = 0;
91
+ let size = 10;
92
+ let metaOnly = false;
93
+ let postsOnly = false;
94
+ for (let index = 0; index < args.length; index += 1) {
95
+ const arg = args[index];
96
+ if (arg === "--meta") {
97
+ metaOnly = true;
98
+ continue;
99
+ }
100
+ if (arg === "--posts") {
101
+ postsOnly = true;
102
+ continue;
103
+ }
104
+ if (arg === "--from") {
105
+ from = parseNonNegativeInteger(args[index + 1], "--from");
106
+ index += 1;
107
+ continue;
108
+ }
109
+ if (arg === "--size") {
110
+ size = parsePositiveInteger(args[index + 1], "--size");
111
+ index += 1;
112
+ continue;
113
+ }
114
+ throw new Error(`unknown topic option: ${arg}`);
115
+ }
116
+ return { from, size, metaOnly, postsOnly };
117
+ }
118
+ function parseSizeOnly(args, defaultSize) {
119
+ if (args.length === 0) {
120
+ return defaultSize;
121
+ }
122
+ if (args[0] === "--size") {
123
+ return parsePositiveInteger(args[1], "--size");
124
+ }
125
+ throw new Error(`unknown option: ${args[0]}`);
126
+ }
127
+ function extractUserOption(args) {
128
+ const rest = [];
129
+ let userId;
130
+ for (let index = 0; index < args.length; index += 1) {
131
+ const arg = args[index];
132
+ if (arg === "--me") {
133
+ userId = undefined;
134
+ continue;
135
+ }
136
+ if (arg === "--user") {
137
+ userId = parsePositiveInteger(args[index + 1], "--user");
138
+ index += 1;
139
+ continue;
140
+ }
141
+ rest.push(arg);
142
+ }
143
+ return { userId, args: rest };
144
+ }
145
+ function parseFavoriteOptions(args) {
146
+ let from = 0;
147
+ let size = 11;
148
+ let order = 1;
149
+ let groupId = 0;
150
+ for (let index = 0; index < args.length; index += 1) {
151
+ const arg = args[index];
152
+ if (arg === "--from") {
153
+ from = parseNonNegativeInteger(args[index + 1], "--from");
154
+ index += 1;
155
+ continue;
156
+ }
157
+ if (arg === "--size") {
158
+ size = parsePositiveInteger(args[index + 1], "--size");
159
+ index += 1;
160
+ continue;
161
+ }
162
+ if (arg === "--order") {
163
+ order = parseNonNegativeInteger(args[index + 1], "--order");
164
+ index += 1;
165
+ continue;
166
+ }
167
+ if (arg === "--group") {
168
+ groupId = parseNonNegativeInteger(args[index + 1], "--group");
169
+ index += 1;
170
+ continue;
171
+ }
172
+ throw new Error(`unknown topic favorite option: ${arg}`);
173
+ }
174
+ return { from, size, order, groupId };
175
+ }
176
+ function printTopicHelp() {
177
+ console.log(`cc98 topic
178
+
179
+ Usage:
180
+ cc98 topic <topic-id> [--from n] [--size n]
181
+ cc98 topic <topic-id> --meta
182
+ cc98 topic <topic-id> --posts
183
+ cc98 topic new [--from n] [--size n]
184
+ cc98 topic random [--size n]
185
+ cc98 topic recent [--me | --user id] [--from n] [--size n]
186
+ cc98 topic favorite [--group id] [--order n] [--from n] [--size n]
187
+ cc98 topic is-favorite <topic-id>
188
+ cc98 topic vote <topic-id>
189
+ cc98 topic basic <ids...>
190
+ cc98 topic search <keyword> [--from n] [--size n]
191
+
192
+ Output:
193
+ Default output is JSON.
194
+ `);
195
+ }
196
+ //# sourceMappingURL=topic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic.js","sourceRoot":"","sources":["../../../src/cli/commands/topic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function userCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/user.ts"],"names":[],"mappings":"AAIA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoE/D"}
@@ -0,0 +1,90 @@
1
+ import { createCliContext } from "../context.js";
2
+ import { extractAccountOption } from "../options.js";
3
+ import { extractPageOptions, parseIds, parsePositiveInteger, printJson } from "../parse.js";
4
+ export async function userCommand(args) {
5
+ const accountOption = extractAccountOption(args);
6
+ const [subcommand, ...rest] = accountOption.args;
7
+ const { client } = createCliContext({ account: accountOption.account });
8
+ switch (subcommand) {
9
+ case undefined:
10
+ case "--help":
11
+ case "-h":
12
+ case "help":
13
+ printUserHelp();
14
+ return;
15
+ case "me":
16
+ printJson(await client.getMe());
17
+ return;
18
+ case "profile": {
19
+ const userId = parsePositiveInteger(rest[0], "user-id");
20
+ printJson(await client.getUserProfile(userId));
21
+ return;
22
+ }
23
+ case "basic":
24
+ printJson(await client.getBasicUsers(parseIds(rest)));
25
+ return;
26
+ case "list":
27
+ printJson(await client.getUsers(parseIds(rest)));
28
+ return;
29
+ case "followers": {
30
+ const page = extractPageOptions(rest, { size: 10 });
31
+ printJson(await client.getFriendIds("follower", page.from, page.size));
32
+ return;
33
+ }
34
+ case "followees": {
35
+ const page = extractPageOptions(rest, { size: 10 });
36
+ printJson(await client.getFriendIds("followee", page.from, page.size));
37
+ return;
38
+ }
39
+ case "moment": {
40
+ const page = extractPageOptions(rest, { size: 20 });
41
+ printJson(await client.getMoment(page.from, page.size));
42
+ return;
43
+ }
44
+ case "favorite-updates": {
45
+ const page = extractPageOptions(rest, { size: 20 });
46
+ printJson(await client.getFavoriteUpdates(page.from, page.size));
47
+ return;
48
+ }
49
+ case "favorite-groups":
50
+ printJson(await client.getFavoriteGroups());
51
+ return;
52
+ case "search": {
53
+ const name = rest.join(" ").trim();
54
+ if (!name) {
55
+ throw new Error("usage: cc98 user search <name>");
56
+ }
57
+ printJson(await client.searchUsers(name));
58
+ return;
59
+ }
60
+ case "unread":
61
+ printJson(await client.getUnreadCount());
62
+ return;
63
+ case "browse-history": {
64
+ const page = extractPageOptions(rest, { size: 11 });
65
+ printJson(await client.getBrowseHistory(page.from, page.size));
66
+ return;
67
+ }
68
+ default:
69
+ throw new Error(`unknown user command: ${subcommand}`);
70
+ }
71
+ }
72
+ function printUserHelp() {
73
+ console.log(`cc98 user
74
+
75
+ Usage:
76
+ cc98 user me
77
+ cc98 user profile <user-id>
78
+ cc98 user basic <ids...>
79
+ cc98 user list <ids...>
80
+ cc98 user followers [--from n] [--size n]
81
+ cc98 user followees [--from n] [--size n]
82
+ cc98 user moment [--from n] [--size n]
83
+ cc98 user favorite-updates [--from n] [--size n]
84
+ cc98 user favorite-groups
85
+ cc98 user search <name>
86
+ cc98 user unread
87
+ cc98 user browse-history [--from n] [--size n]
88
+ `);
89
+ }
90
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../../src/cli/commands/user.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Cc98Client } from "../api/client.js";
2
+ import { TokenStore } from "../storage/token-store.js";
3
+ export declare function createCliContext(options?: {
4
+ account?: string;
5
+ }): {
6
+ client: Cc98Client;
7
+ tokenStore: TokenStore;
8
+ };
9
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvD,wBAAgB,gBAAgB,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAInH"}
@@ -0,0 +1,8 @@
1
+ import { Cc98Client } from "../api/client.js";
2
+ import { TokenStore } from "../storage/token-store.js";
3
+ export function createCliContext(options = {}) {
4
+ const tokenStore = new TokenStore().withAccount(options.account);
5
+ const client = new Cc98Client({ tokenStore });
6
+ return { client, tokenStore };
7
+ }
8
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvD,MAAM,UAAU,gBAAgB,CAAC,UAAgC,EAAE;IACjE,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAC9C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface AccountOptionResult {
2
+ account?: string;
3
+ args: string[];
4
+ }
5
+ export declare function extractAccountOption(args: string[]): AccountOptionResult;
6
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAwBxE"}
@@ -0,0 +1,22 @@
1
+ export function extractAccountOption(args) {
2
+ const nextArgs = [];
3
+ let account;
4
+ for (let index = 0; index < args.length; index += 1) {
5
+ const arg = args[index];
6
+ if (arg === "--account" || arg === "-a") {
7
+ const value = args[index + 1];
8
+ if (!value) {
9
+ throw new Error(`missing value for ${arg}`);
10
+ }
11
+ account = value;
12
+ index += 1;
13
+ continue;
14
+ }
15
+ nextArgs.push(arg);
16
+ }
17
+ return {
18
+ account,
19
+ args: nextArgs
20
+ };
21
+ }
22
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/cli/options.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,oBAAoB,CAAC,IAAc;IACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,OAA2B,CAAC;IAEhC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAExB,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,GAAG,KAAK,CAAC;YAChB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,OAAO;QACL,OAAO;QACP,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare function parseInteger(value: string | undefined, name: string): number;
2
+ export declare function parsePositiveInteger(value: string | undefined, name: string): number;
3
+ export declare function parseNonNegativeInteger(value: string | undefined, name: string): number;
4
+ export declare function parseIds(values: string[], name?: string): number[];
5
+ export interface PageOptions {
6
+ from: number;
7
+ size: number;
8
+ rest: string[];
9
+ }
10
+ export declare function extractPageOptions(args: string[], defaults?: {
11
+ from?: number;
12
+ size?: number;
13
+ }): PageOptions;
14
+ export declare function printJson(value: unknown): void;
15
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/cli/parse.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpF;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvF;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,SAAQ,GAAG,MAAM,EAAE,CAWjE;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,CAwB/G;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE9C"}
@@ -0,0 +1,55 @@
1
+ export function parseInteger(value, name) {
2
+ const parsed = Number(value);
3
+ if (!Number.isInteger(parsed)) {
4
+ throw new Error(`missing or invalid value for ${name}`);
5
+ }
6
+ return parsed;
7
+ }
8
+ export function parsePositiveInteger(value, name) {
9
+ const parsed = parseInteger(value, name);
10
+ if (parsed <= 0) {
11
+ throw new Error(`missing or invalid value for ${name}`);
12
+ }
13
+ return parsed;
14
+ }
15
+ export function parseNonNegativeInteger(value, name) {
16
+ const parsed = parseInteger(value, name);
17
+ if (parsed < 0) {
18
+ throw new Error(`missing or invalid value for ${name}`);
19
+ }
20
+ return parsed;
21
+ }
22
+ export function parseIds(values, name = "ids") {
23
+ const ids = values.flatMap((value) => value.split(","))
24
+ .map((value) => value.trim())
25
+ .filter(Boolean)
26
+ .map((value) => parsePositiveInteger(value, name));
27
+ if (ids.length === 0) {
28
+ throw new Error(`missing ${name}`);
29
+ }
30
+ return ids;
31
+ }
32
+ export function extractPageOptions(args, defaults = {}) {
33
+ const rest = [];
34
+ let from = defaults.from ?? 0;
35
+ let size = defaults.size ?? 20;
36
+ for (let index = 0; index < args.length; index += 1) {
37
+ const arg = args[index];
38
+ if (arg === "--from") {
39
+ from = parseNonNegativeInteger(args[index + 1], "--from");
40
+ index += 1;
41
+ continue;
42
+ }
43
+ if (arg === "--size") {
44
+ size = parsePositiveInteger(args[index + 1], "--size");
45
+ index += 1;
46
+ continue;
47
+ }
48
+ rest.push(arg);
49
+ }
50
+ return { from, size, rest };
51
+ }
52
+ export function printJson(value) {
53
+ console.log(JSON.stringify(value, null, 2));
54
+ }
55
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/cli/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function promptText(label: string): Promise<string>;
2
+ export declare function promptPassword(label: string): Promise<string>;
3
+ export declare function readStdinText(): Promise<string>;
4
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAuBA,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBnE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAMrD"}
@@ -0,0 +1,53 @@
1
+ import { stdin, stdout } from "node:process";
2
+ import { Writable } from "node:stream";
3
+ import { createInterface } from "node:readline/promises";
4
+ class MuteableOutput extends Writable {
5
+ target;
6
+ muted = false;
7
+ constructor(target) {
8
+ super();
9
+ this.target = target;
10
+ }
11
+ _write(chunk, encoding, callback) {
12
+ if (!this.muted) {
13
+ this.target.write(chunk, encoding);
14
+ }
15
+ callback();
16
+ }
17
+ }
18
+ export async function promptText(label) {
19
+ const rl = createInterface({ input: stdin, output: stdout });
20
+ try {
21
+ return await rl.question(label);
22
+ }
23
+ finally {
24
+ rl.close();
25
+ }
26
+ }
27
+ export async function promptPassword(label) {
28
+ if (!stdin.isTTY) {
29
+ return promptText(label);
30
+ }
31
+ const output = new MuteableOutput(stdout);
32
+ const rl = createInterface({ input: stdin, output, terminal: true });
33
+ try {
34
+ stdout.write(label);
35
+ output.muted = true;
36
+ const password = await rl.question("");
37
+ output.muted = false;
38
+ stdout.write("\n");
39
+ return password;
40
+ }
41
+ finally {
42
+ output.muted = false;
43
+ rl.close();
44
+ }
45
+ }
46
+ export async function readStdinText() {
47
+ const chunks = [];
48
+ for await (const chunk of stdin) {
49
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
50
+ }
51
+ return Buffer.concat(chunks).toString("utf8");
52
+ }
53
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,cAAe,SAAQ,QAAQ;IAGN;IAF7B,KAAK,GAAG,KAAK,CAAC;IAEd,YAA6B,MAA0B;QACrD,KAAK,EAAE,CAAC;QADmB,WAAM,GAAN,MAAM,CAAoB;IAEvD,CAAC;IAEQ,MAAM,CACb,KAAsB,EACtB,QAAwB,EACxB,QAAwC;QAExC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;QACD,QAAQ,EAAE,CAAC;IACb,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa;IAC5C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa;IAChD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAErE,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,QAAQ,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runCli(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/cli/router.ts"],"names":[],"mappings":"AAiCA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1D"}
@@ -0,0 +1,77 @@
1
+ import { accountCommand } from "./commands/account.js";
2
+ import { boardCommand } from "./commands/board.js";
3
+ import { forumCommand } from "./commands/forum.js";
4
+ import { loginCommand } from "./commands/login.js";
5
+ import { logoutCommand } from "./commands/logout.js";
6
+ import { messageCommand } from "./commands/message.js";
7
+ import { meCommand } from "./commands/me.js";
8
+ import { noticeCommand } from "./commands/notice.js";
9
+ import { postCommand } from "./commands/post.js";
10
+ import { extractAccountOption } from "./options.js";
11
+ import { searchCommand } from "./commands/search.js";
12
+ import { topicCommand } from "./commands/topic.js";
13
+ import { userCommand } from "./commands/user.js";
14
+ import { runTui } from "../tui/app.js";
15
+ const commands = {
16
+ account: accountCommand,
17
+ board: boardCommand,
18
+ forum: forumCommand,
19
+ login: loginCommand,
20
+ logout: logoutCommand,
21
+ message: messageCommand,
22
+ me: meCommand,
23
+ notice: noticeCommand,
24
+ post: postCommand,
25
+ search: searchCommand,
26
+ topic: topicCommand,
27
+ tui: runTui,
28
+ user: userCommand
29
+ };
30
+ export async function runCli(args) {
31
+ const accountOption = extractAccountOption(args);
32
+ const [command, ...rest] = accountOption.args;
33
+ if (!command || command === "--help" || command === "-h" || command === "help") {
34
+ printHelp();
35
+ return;
36
+ }
37
+ if (command === "--version" || command === "-v") {
38
+ console.log("cc98-cli 0.1.0");
39
+ return;
40
+ }
41
+ const handler = commands[command];
42
+ if (!handler) {
43
+ throw new Error(`unknown command: ${command}. Run "cc98 --help" for usage.`);
44
+ }
45
+ const commandArgs = accountOption.account && command !== "account"
46
+ ? [...rest, "--account", accountOption.account]
47
+ : rest;
48
+ await handler(commandArgs);
49
+ }
50
+ function printHelp() {
51
+ console.log(`cc98
52
+
53
+ Usage:
54
+ cc98 Open the TUI
55
+ cc98 tui Open the TUI explicitly
56
+ cc98 login Sign in and save tokens
57
+ cc98 account list List local accounts
58
+ cc98 account use <name> Set current account
59
+ cc98 logout Remove saved tokens
60
+ cc98 me Show current user profile
61
+ cc98 forum index Read forum index config
62
+ cc98 forum boards Read all boards
63
+ cc98 board <board-id> List topics in a board
64
+ cc98 topic <topic-id> Read a topic
65
+ cc98 user profile <id> Read user profile
66
+ cc98 message unread Read unread counts
67
+ cc98 notice system Read system notices
68
+ cc98 post rate-reasons 0 Read post rating reasons
69
+ cc98 search <keyword> Search topics
70
+
71
+ Options:
72
+ -a, --account <name> Use this account for supported commands
73
+ -h, --help Show this help
74
+ -v, --version Show version
75
+ `);
76
+ }
77
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/cli/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIvC,MAAM,QAAQ,GAAmC;IAC/C,OAAO,EAAE,cAAc;IACvB,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;IACrB,OAAO,EAAE,cAAc;IACvB,EAAE,EAAE,SAAS;IACb,MAAM,EAAE,aAAa;IACrB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,WAAW;CAClB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAc;IACzC,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC;IAE9C,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAC/E,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,gCAAgC,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,IAAI,OAAO,KAAK,SAAS;QAChE,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC;QAC/C,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwBb,CAAC,CAAC;AACH,CAAC"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
package/dist/main.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./cli/router.js";
3
+ import { runTui } from "./tui/app.js";
4
+ async function main() {
5
+ const args = process.argv.slice(2);
6
+ if (args.length === 0) {
7
+ await runTui();
8
+ return;
9
+ }
10
+ await runCli(args);
11
+ }
12
+ main().catch((error) => {
13
+ const message = error instanceof Error ? error.message : String(error);
14
+ console.error(`cc98: ${message}`);
15
+ process.exitCode = 1;
16
+ });
17
+ //# sourceMappingURL=main.js.map