@will-17173/telegram-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 (82) hide show
  1. package/LICENSE +675 -0
  2. package/README.md +264 -0
  3. package/README.zh-CN.md +264 -0
  4. package/dist/account/account-context.js +22 -0
  5. package/dist/account/account-context.js.map +1 -0
  6. package/dist/account/account-presets.js +22 -0
  7. package/dist/account/account-presets.js.map +1 -0
  8. package/dist/account/account-store.js +225 -0
  9. package/dist/account/account-store.js.map +1 -0
  10. package/dist/cli/app.js +21 -0
  11. package/dist/cli/app.js.map +1 -0
  12. package/dist/cli/output.js +39 -0
  13. package/dist/cli/output.js.map +1 -0
  14. package/dist/commands/account-options.js +55 -0
  15. package/dist/commands/account-options.js.map +1 -0
  16. package/dist/commands/account.js +449 -0
  17. package/dist/commands/account.js.map +1 -0
  18. package/dist/commands/config.js +63 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/data.js +52 -0
  21. package/dist/commands/data.js.map +1 -0
  22. package/dist/commands/query.js +116 -0
  23. package/dist/commands/query.js.map +1 -0
  24. package/dist/commands/telegram.js +423 -0
  25. package/dist/commands/telegram.js.map +1 -0
  26. package/dist/commands/types.js +12 -0
  27. package/dist/commands/types.js.map +1 -0
  28. package/dist/config/credential-store.js +82 -0
  29. package/dist/config/credential-store.js.map +1 -0
  30. package/dist/config/env.js +78 -0
  31. package/dist/config/env.js.map +1 -0
  32. package/dist/index.js +4 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/presenters/human.js +218 -0
  35. package/dist/presenters/human.js.map +1 -0
  36. package/dist/presenters/ink/DetailView.js +14 -0
  37. package/dist/presenters/ink/DetailView.js.map +1 -0
  38. package/dist/presenters/ink/TableView.js +9 -0
  39. package/dist/presenters/ink/TableView.js.map +1 -0
  40. package/dist/presenters/ink/TimelineView.js +34 -0
  41. package/dist/presenters/ink/TimelineView.js.map +1 -0
  42. package/dist/presenters/ink/display-width.js +149 -0
  43. package/dist/presenters/ink/display-width.js.map +1 -0
  44. package/dist/presenters/ink/image-preview.js +47 -0
  45. package/dist/presenters/ink/image-preview.js.map +1 -0
  46. package/dist/presenters/ink/listen-scroll.js +37 -0
  47. package/dist/presenters/ink/listen-scroll.js.map +1 -0
  48. package/dist/presenters/ink/listen-scrollbar.js +49 -0
  49. package/dist/presenters/ink/listen-scrollbar.js.map +1 -0
  50. package/dist/presenters/ink/listen.js +542 -0
  51. package/dist/presenters/ink/listen.js.map +1 -0
  52. package/dist/presenters/ink/mouse-scroll.js +55 -0
  53. package/dist/presenters/ink/mouse-scroll.js.map +1 -0
  54. package/dist/presenters/ink/render.js +45 -0
  55. package/dist/presenters/ink/render.js.map +1 -0
  56. package/dist/presenters/listen-message.js +267 -0
  57. package/dist/presenters/listen-message.js.map +1 -0
  58. package/dist/presenters/structured.js +30 -0
  59. package/dist/presenters/structured.js.map +1 -0
  60. package/dist/services/attachment-download.js +21 -0
  61. package/dist/services/attachment-download.js.map +1 -0
  62. package/dist/services/data-service.js +76 -0
  63. package/dist/services/data-service.js.map +1 -0
  64. package/dist/services/listen-album-aggregator.js +72 -0
  65. package/dist/services/listen-album-aggregator.js.map +1 -0
  66. package/dist/services/message-service.js +102 -0
  67. package/dist/services/message-service.js.map +1 -0
  68. package/dist/services/query-service.js +116 -0
  69. package/dist/services/query-service.js.map +1 -0
  70. package/dist/services/sync-service.js +134 -0
  71. package/dist/services/sync-service.js.map +1 -0
  72. package/dist/storage/chat-resolver.js +9 -0
  73. package/dist/storage/chat-resolver.js.map +1 -0
  74. package/dist/storage/message-db.js +246 -0
  75. package/dist/storage/message-db.js.map +1 -0
  76. package/dist/telegram/client-factory.js +27 -0
  77. package/dist/telegram/client-factory.js.map +1 -0
  78. package/dist/telegram/mtcute-client.js +324 -0
  79. package/dist/telegram/mtcute-client.js.map +1 -0
  80. package/dist/telegram/types.js +2 -0
  81. package/dist/telegram/types.js.map +1 -0
  82. package/package.json +50 -0
@@ -0,0 +1,449 @@
1
+ import { mkdtempSync, mkdirSync, renameSync, rmSync, existsSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { TelegramClient } from '@mtcute/node';
5
+ import { getAccountRegistryPath, getDataDir, getTelegramCredentials } from '../config/env.js';
6
+ import { AccountStore } from '../account/account-store.js';
7
+ import { accountSessionPath } from '../account/account-presets.js';
8
+ import { outputFormatConflict } from './types.js';
9
+ import { renderResult } from '../cli/output.js';
10
+ export function registerAccountCommands(app) {
11
+ const account = app.command('account').description('Manage Telegram accounts');
12
+ account.command('add')
13
+ .description('Add and authenticate a Telegram account')
14
+ .option('--json')
15
+ .option('--yaml')
16
+ .action(async (options) => {
17
+ await runAccountCommand(options, async () => {
18
+ const registered = await addAccount();
19
+ return {
20
+ ok: true,
21
+ data: registered,
22
+ human: {
23
+ kind: 'detail',
24
+ title: 'Account added',
25
+ fields: [
26
+ { label: 'Name', value: registered.account.name },
27
+ { label: 'Current', value: String(registered.current), tone: registered.current ? 'success' : 'default' },
28
+ { label: 'User ID', value: String(registered.account.user_id) },
29
+ ],
30
+ },
31
+ };
32
+ });
33
+ });
34
+ account.command('list')
35
+ .description('List registered accounts')
36
+ .option('--json')
37
+ .option('--yaml')
38
+ .action(async (options) => {
39
+ await runAccountCommand(options, () => {
40
+ const store = new AccountStore(getAccountRegistryPath());
41
+ const registry = store.read();
42
+ const accounts = registry.accounts.map((account) => ({
43
+ name: account.name,
44
+ display_name: normalizeDisplayName(account.display_name),
45
+ username: account.username,
46
+ phone: account.phone,
47
+ current: account.name === registry.current_account,
48
+ }));
49
+ return {
50
+ ok: true,
51
+ data: {
52
+ current_account: registry.current_account,
53
+ accounts,
54
+ },
55
+ human: {
56
+ kind: 'table',
57
+ title: 'Accounts',
58
+ columns: ['NAME', 'DISPLAY NAME', 'USERNAME', 'PHONE', 'CURRENT'],
59
+ rows: accounts.map((account) => [
60
+ account.name,
61
+ account.display_name,
62
+ account.username,
63
+ account.phone,
64
+ account.current ? 'yes' : 'no',
65
+ ]),
66
+ emptyText: 'No accounts found.',
67
+ },
68
+ };
69
+ });
70
+ });
71
+ account.command('current')
72
+ .description('Show the current account')
73
+ .option('--json')
74
+ .option('--yaml')
75
+ .action(async (options) => {
76
+ await runAccountCommand(options, () => {
77
+ const store = new AccountStore(getAccountRegistryPath());
78
+ const registry = store.read();
79
+ if (registry.current_account === null) {
80
+ return {
81
+ ok: false,
82
+ error: {
83
+ code: 'account_required',
84
+ message: 'No current account is set. Run tg account switch <name> or add one with tg account add.',
85
+ },
86
+ };
87
+ }
88
+ const account = store.current();
89
+ if (!account) {
90
+ return {
91
+ ok: false,
92
+ error: {
93
+ code: 'account_not_found',
94
+ message: `Current account "${registry.current_account}" no longer exists.`,
95
+ },
96
+ };
97
+ }
98
+ return {
99
+ ok: true,
100
+ data: {
101
+ account,
102
+ current: true,
103
+ },
104
+ human: {
105
+ kind: 'detail',
106
+ title: 'Current account',
107
+ fields: [
108
+ { label: 'Name', value: account.name },
109
+ { label: 'Display name', value: normalizeDisplayName(account.display_name) },
110
+ { label: 'Username', value: `@${account.username}` },
111
+ { label: 'User ID', value: String(account.user_id) },
112
+ { label: 'Phone', value: account.phone },
113
+ { label: 'Current', value: 'yes', tone: 'success' },
114
+ ],
115
+ },
116
+ };
117
+ });
118
+ });
119
+ account.command('switch <name>')
120
+ .description('Set the default account')
121
+ .option('--json')
122
+ .option('--yaml')
123
+ .action(async (name, options) => {
124
+ await runAccountCommand(options, async () => {
125
+ const store = new AccountStore(getAccountRegistryPath());
126
+ const current = await store.withLock(() => {
127
+ const registry = store.read();
128
+ if (!registry.accounts.some((account) => account.name === name)) {
129
+ return {
130
+ code: 'account_not_found',
131
+ message: `Account "${name}" is not registered.`,
132
+ };
133
+ }
134
+ const next = { ...registry, current_account: name };
135
+ store.write(next);
136
+ return {
137
+ code: null,
138
+ message: '',
139
+ current: next.current_account,
140
+ };
141
+ });
142
+ if (current.code !== null) {
143
+ return {
144
+ ok: false,
145
+ error: {
146
+ code: current.code,
147
+ message: current.message,
148
+ },
149
+ };
150
+ }
151
+ return {
152
+ ok: true,
153
+ data: {
154
+ current_account: current.current,
155
+ },
156
+ human: {
157
+ kind: 'detail',
158
+ title: 'Current account updated',
159
+ fields: [{ label: 'Current account', value: current.current }],
160
+ },
161
+ };
162
+ });
163
+ });
164
+ account.command('remove <name>')
165
+ .description('Remove an account from local registry')
166
+ .option('--force', 'Delete local files without interactive confirmation')
167
+ .option('--json')
168
+ .option('--yaml')
169
+ .action(async (name, options) => {
170
+ await runAccountCommand(options, async () => {
171
+ if (!options.force && process.stdin.isTTY !== true) {
172
+ return {
173
+ ok: false,
174
+ error: {
175
+ code: 'account_in_use',
176
+ message: 'Account removal requires --force in non-interactive mode.',
177
+ },
178
+ };
179
+ }
180
+ const store = new AccountStore(getAccountRegistryPath());
181
+ const dataDir = getDataDir();
182
+ const removed = await store.withLock(() => {
183
+ const registry = store.read();
184
+ const account = registry.accounts.find((item) => item.name === name);
185
+ if (!account) {
186
+ return {
187
+ code: 'account_not_found',
188
+ message: `Account "${name}" is not registered.`,
189
+ };
190
+ }
191
+ const accountDir = dirname(accountSessionPath(dataDir, account.name));
192
+ const tombstone = join(dirname(accountDir), `.delete-${account.name}-${randomUUID()}`);
193
+ try {
194
+ renameSync(accountDir, tombstone);
195
+ }
196
+ catch (error) {
197
+ return {
198
+ code: 'account_in_use',
199
+ message: `Could not move account files for "${account.name}": ${errorMessage(error)}`,
200
+ };
201
+ }
202
+ const remaining = registry.accounts.filter((item) => item.name !== account.name);
203
+ const nextCurrent = registry.current_account === account.name
204
+ ? remaining[0]?.name ?? null
205
+ : registry.current_account;
206
+ const next = { ...registry, accounts: remaining, current_account: nextCurrent };
207
+ try {
208
+ store.write(next);
209
+ }
210
+ catch (error) {
211
+ try {
212
+ renameSync(tombstone, accountDir);
213
+ }
214
+ catch {
215
+ return {
216
+ code: 'account_store_error',
217
+ message: `Failed to restore files after registry update failure for "${account.name}".`,
218
+ };
219
+ }
220
+ return {
221
+ code: 'account_store_error',
222
+ message: `Failed to update registry: ${errorMessage(error)}`,
223
+ };
224
+ }
225
+ return {
226
+ code: null,
227
+ message: '',
228
+ removed: account.name,
229
+ account,
230
+ current_account: next.current_account,
231
+ tombstone,
232
+ };
233
+ });
234
+ if (removed.code !== null) {
235
+ return {
236
+ ok: false,
237
+ error: {
238
+ code: removed.code,
239
+ message: removed.message,
240
+ },
241
+ };
242
+ }
243
+ try {
244
+ rmSync(removed.tombstone, { recursive: true, force: true });
245
+ }
246
+ catch (error) {
247
+ return {
248
+ ok: false,
249
+ error: {
250
+ code: 'account_in_use',
251
+ message: `Account was removed from registry, but local files could not be deleted: ${errorMessage(error)}`,
252
+ details: { tombstone: removed.tombstone },
253
+ },
254
+ };
255
+ }
256
+ return {
257
+ ok: true,
258
+ data: {
259
+ removed: removed.removed,
260
+ current_account: removed.current_account,
261
+ },
262
+ human: {
263
+ kind: 'detail',
264
+ title: 'Account removed',
265
+ fields: [
266
+ { label: 'Removed', value: removed.removed },
267
+ { label: 'Current', value: removed.current_account ?? 'none' },
268
+ ],
269
+ },
270
+ };
271
+ });
272
+ });
273
+ }
274
+ async function runAccountCommand(options, handler) {
275
+ const conflict = outputFormatConflict(options);
276
+ if (conflict) {
277
+ await renderResult(conflict, { yaml: true });
278
+ return;
279
+ }
280
+ try {
281
+ const result = await handler();
282
+ await renderResult(result, options);
283
+ }
284
+ catch (error) {
285
+ await renderResult(unwrapFailure(error, 'account_store_error'), options);
286
+ }
287
+ }
288
+ async function addAccount() {
289
+ const dataDir = getDataDir();
290
+ const store = new AccountStore(getAccountRegistryPath(dataDir));
291
+ const temporaryAccountDir = mkdtempSync(join(dataDir, 'tmp-account-'));
292
+ const temporarySessionPath = join(temporaryAccountDir, 'session');
293
+ const credentials = getTelegramCredentials();
294
+ let auth;
295
+ try {
296
+ auth = await authenticateAccount(temporarySessionPath, credentials);
297
+ const user = await auth.getMe();
298
+ const mapped = mapAuthUser(user);
299
+ await auth.close();
300
+ auth = undefined;
301
+ const registration = await store.withLock(() => {
302
+ const registry = store.read();
303
+ if (registry.accounts.some((account) => account.user_id === mapped.user_id)) {
304
+ return {
305
+ code: 'account_already_exists',
306
+ message: `Account ${mapped.user_id} is already registered.`,
307
+ account: null,
308
+ current: false,
309
+ };
310
+ }
311
+ let name = mapped.name;
312
+ const collision = registry.accounts.find((account) => account.name === name);
313
+ if (collision != null && collision.user_id !== mapped.user_id) {
314
+ name = `${name}-${mapped.user_id}`;
315
+ }
316
+ const account = {
317
+ ...mapped,
318
+ name,
319
+ };
320
+ const accounts = registry.accounts.concat([account]);
321
+ const currentAccount = registry.current_account ?? account.name;
322
+ store.write({ ...registry, accounts, current_account: currentAccount });
323
+ return {
324
+ code: null,
325
+ message: '',
326
+ account,
327
+ current: currentAccount === account.name,
328
+ };
329
+ });
330
+ if (registration.code !== null) {
331
+ throwCodeError(registration.code, registration.message);
332
+ }
333
+ const finalSessionPath = accountSessionPath(dataDir, registration.account.name);
334
+ try {
335
+ moveSession(temporarySessionPath, finalSessionPath);
336
+ }
337
+ catch (error) {
338
+ await rollbackRegistration(store, registration.account.name);
339
+ throwCodeError('account_store_error', `Failed to move session file: ${errorMessage(error)}`);
340
+ }
341
+ return {
342
+ account: registration.account,
343
+ current: registration.current,
344
+ };
345
+ }
346
+ finally {
347
+ if (auth) {
348
+ await auth.close();
349
+ }
350
+ rmSync(temporaryAccountDir, { recursive: true, force: true });
351
+ }
352
+ }
353
+ async function authenticateAccount(sessionPath, credentials) {
354
+ const client = new TelegramClient({
355
+ apiId: credentials.apiId,
356
+ apiHash: credentials.apiHash,
357
+ storage: sessionPath,
358
+ });
359
+ try {
360
+ await client.start();
361
+ return {
362
+ getMe: () => client.getMe(),
363
+ close: () => client.destroy(),
364
+ };
365
+ }
366
+ catch (error) {
367
+ await client.destroy().catch(() => undefined);
368
+ throwCodeError('account_login_failed', errorMessage(error));
369
+ }
370
+ }
371
+ function mapAuthUser(user) {
372
+ const displayName = user.displayName?.trim();
373
+ const displayNameFallback = [
374
+ user.firstName,
375
+ user.lastName,
376
+ ].filter((value) => value != null && value.trim().length > 0).join(' ');
377
+ const username = user.username?.trim() || `user-${user.id}`;
378
+ const phone = (user.phoneNumber ?? '').replace(/\D/g, '') || String(user.id);
379
+ const preferredName = user.username?.trim().toLowerCase() || '';
380
+ const name = preferredName.length > 0 ? preferredName : phone;
381
+ const resolvedDisplayName = displayName && displayName.length > 0
382
+ ? displayName
383
+ : displayNameFallback;
384
+ return {
385
+ user_id: user.id,
386
+ username: username.toLowerCase(),
387
+ phone,
388
+ display_name: resolvedDisplayName.length > 0 ? normalizeDisplayName(resolvedDisplayName) : username,
389
+ name,
390
+ };
391
+ }
392
+ function normalizeDisplayName(displayName) {
393
+ const normalized = displayName.trim().replace(/\s+/g, ' ');
394
+ const words = normalized.split(' ');
395
+ for (let len = 1; len * 2 <= words.length; len += 1) {
396
+ if (words.length !== len * 2)
397
+ continue;
398
+ const first = words.slice(0, len).join(' ');
399
+ const second = words.slice(len).join(' ');
400
+ if (first === second)
401
+ return first;
402
+ }
403
+ return normalized;
404
+ }
405
+ async function rollbackRegistration(store, name) {
406
+ await store.withLock(() => {
407
+ const registry = store.read();
408
+ const accounts = registry.accounts.filter((account) => account.name !== name);
409
+ if (accounts.length === registry.accounts.length)
410
+ return;
411
+ const current_account = registry.current_account === name
412
+ ? accounts[0]?.name ?? null
413
+ : registry.current_account;
414
+ store.write({ ...registry, accounts, current_account });
415
+ });
416
+ }
417
+ function moveSession(source, destination) {
418
+ if (!existsSync(source)) {
419
+ throwCodeError('account_store_error', `Missing temporary session file: ${source}`);
420
+ }
421
+ mkdirSync(dirname(destination), { recursive: true });
422
+ if (existsSync(destination)) {
423
+ rmSync(destination, { force: true });
424
+ }
425
+ renameSync(source, destination);
426
+ }
427
+ function unwrapFailure(error, fallbackCode) {
428
+ const message = errorMessage(error);
429
+ const coded = error;
430
+ const code = typeof coded.code === 'string' && coded.code.length > 0
431
+ ? coded.code
432
+ : fallbackCode;
433
+ return {
434
+ ok: false,
435
+ error: {
436
+ code,
437
+ message,
438
+ },
439
+ };
440
+ }
441
+ function throwCodeError(code, message) {
442
+ const error = new Error(message);
443
+ error.code = code;
444
+ throw error;
445
+ }
446
+ function errorMessage(error) {
447
+ return error instanceof Error ? error.message : String(error);
448
+ }
449
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/commands/account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { renderResult } from '../cli/output.js';
2
+ import { validateCredentials, writeCredentials } from '../config/credential-store.js';
3
+ import { getConfigPath } from '../config/env.js';
4
+ import { outputFormatConflict } from './types.js';
5
+ export function registerConfigCommands(app) {
6
+ const config = app.command('config').description('Manage Telegram CLI configuration');
7
+ config.command('set')
8
+ .description('Save Telegram API credentials')
9
+ .option('--api-id <id>', 'Telegram API ID')
10
+ .option('--api-hash <hash>', 'Telegram API hash')
11
+ .option('--json')
12
+ .option('--yaml')
13
+ .action(async (options) => {
14
+ const conflict = outputFormatConflict(options);
15
+ if (conflict) {
16
+ await renderResult(conflict, { yaml: true });
17
+ return;
18
+ }
19
+ let credentials;
20
+ try {
21
+ credentials = validateCredentials({
22
+ apiId: options.apiId,
23
+ apiHash: options.apiHash,
24
+ });
25
+ }
26
+ catch (error) {
27
+ await renderResult({
28
+ ok: false,
29
+ error: {
30
+ code: 'invalid_config',
31
+ message: error instanceof Error ? error.message : 'Telegram API configuration is invalid.',
32
+ },
33
+ }, options);
34
+ return;
35
+ }
36
+ try {
37
+ writeCredentials(getConfigPath(), credentials);
38
+ }
39
+ catch {
40
+ await renderResult({
41
+ ok: false,
42
+ error: {
43
+ code: 'config_write_failed',
44
+ message: 'Failed to save Telegram API credentials.',
45
+ },
46
+ }, options);
47
+ return;
48
+ }
49
+ const result = {
50
+ ok: true,
51
+ data: {
52
+ configured: true,
53
+ api_id: credentials.apiId,
54
+ },
55
+ human: {
56
+ kind: 'text',
57
+ text: 'Telegram API credentials saved.',
58
+ },
59
+ };
60
+ await renderResult(result, options);
61
+ });
62
+ }
63
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,oBAAoB,EAAwC,MAAM,YAAY,CAAA;AAOvF,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAA;IAErF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SAClB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,eAAe,EAAE,iBAAiB,CAAC;SAC1C,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;SAChD,MAAM,CAAC,QAAQ,CAAC;SAChB,MAAM,CAAC,QAAQ,CAAC;SAChB,MAAM,CAAC,KAAK,EAAE,OAAyB,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;QAC9C,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QAED,IAAI,WAAW,CAAA;QACf,IAAI,CAAC;YACH,WAAW,GAAG,mBAAmB,CAAC;gBAChC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,OAAO,EAAE,OAAO,CAAC,OAAO;aACzB,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,CAAC;gBACjB,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wCAAwC;iBAC3F;aACF,EAAE,OAAO,CAAC,CAAA;YACX,OAAM;QACR,CAAC;QAED,IAAI,CAAC;YACH,gBAAgB,CAAC,aAAa,EAAE,EAAE,WAAW,CAAC,CAAA;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,YAAY,CAAC;gBACjB,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,qBAAqB;oBAC3B,OAAO,EAAE,0CAA0C;iBACpD;aACF,EAAE,OAAO,CAAC,CAAA;YACX,OAAM;QACR,CAAC;QAED,MAAM,MAAM,GAAwD;YAClE,EAAE,EAAE,IAAI;YACR,IAAI,EAAE;gBACJ,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,WAAW,CAAC,KAAK;aAC1B;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,iCAAiC;aACxC;SACF,CAAA;QACD,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { renderResult } from '../cli/output.js';
2
+ import { MessageDB } from '../storage/message-db.js';
3
+ import { DataService } from '../services/data-service.js';
4
+ import { outputFormatConflict } from './types.js';
5
+ import { runWithAccountContext } from './account-options.js';
6
+ export function registerDataCommands(app) {
7
+ app.command('export')
8
+ .description('Export locally stored messages from a chat')
9
+ .argument('<chat>')
10
+ .option('-f, --format <format>', 'text, json, or yaml', 'text')
11
+ .option('-o, --output <output>')
12
+ .option('--hours <hours>')
13
+ .option('--json')
14
+ .option('--yaml')
15
+ .action(async (chat, options) => {
16
+ await renderDataResult(options, (service) => service.exportMessages({
17
+ chat,
18
+ format: options.format ?? 'text',
19
+ output: options.output,
20
+ hours: numberOption(options.hours),
21
+ }));
22
+ });
23
+ app.command('purge')
24
+ .description('Delete locally stored messages from a chat')
25
+ .argument('<chat>')
26
+ .option('-y, --yes')
27
+ .option('--json')
28
+ .option('--yaml')
29
+ .action(async (chat, options) => {
30
+ await renderDataResult(options, (service) => service.purge({ chat, yes: Boolean(options.yes) }));
31
+ });
32
+ }
33
+ function numberOption(value) {
34
+ return value == null ? undefined : Number(value);
35
+ }
36
+ async function renderDataResult(options, handler) {
37
+ const conflict = outputFormatConflict(options);
38
+ if (conflict) {
39
+ await renderResult(conflict, { yaml: true });
40
+ return;
41
+ }
42
+ await runWithAccountContext(options, (context) => {
43
+ const service = new DataService(new MessageDB(context.dbPath));
44
+ try {
45
+ return handler(service);
46
+ }
47
+ finally {
48
+ service.close();
49
+ }
50
+ });
51
+ }
52
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/commands/data.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAsB,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAA8B,MAAM,sBAAsB,CAAA;AAWxF,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;SAClB,WAAW,CAAC,4CAA4C,CAAC;SACzD,QAAQ,CAAC,QAAQ,CAAC;SAClB,MAAM,CAAC,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,CAAC;SAC9D,MAAM,CAAC,uBAAuB,CAAC;SAC/B,MAAM,CAAC,iBAAiB,CAAC;SACzB,MAAM,CAAC,QAAQ,CAAC;SAChB,MAAM,CAAC,QAAQ,CAAC;SAChB,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAkB,EAAE,EAAE;QACjD,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC;YAClE,IAAI;YACJ,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC,CAAA;IACL,CAAC,CAAC,CAAA;IAEJ,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;SACjB,WAAW,CAAC,4CAA4C,CAAC;SACzD,QAAQ,CAAC,QAAQ,CAAC;SAClB,MAAM,CAAC,WAAW,CAAC;SACnB,MAAM,CAAC,QAAQ,CAAC;SAChB,MAAM,CAAC,QAAQ,CAAC;SAChB,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAkB,EAAE,EAAE;QACjD,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IAClG,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,YAAY,CAAC,KAAyB;IAC7C,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAClD,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAkB,EAAE,OAAgD;IAClG,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC9C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAC5C,OAAM;IACR,CAAC;IAED,MAAM,qBAAqB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE;QAC/C,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,EAAE,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}