@urugus/slack-cli 0.2.7 → 0.2.9

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 (52) hide show
  1. package/.claude/settings.local.json +13 -55
  2. package/.github/workflows/ci.yml +2 -2
  3. package/dist/commands/history-display.d.ts +1 -1
  4. package/dist/commands/history-display.d.ts.map +1 -1
  5. package/dist/commands/history-display.js +8 -28
  6. package/dist/commands/history-display.js.map +1 -1
  7. package/dist/commands/history.d.ts.map +1 -1
  8. package/dist/commands/history.js +9 -2
  9. package/dist/commands/history.js.map +1 -1
  10. package/dist/commands/unread.d.ts.map +1 -1
  11. package/dist/commands/unread.js +32 -16
  12. package/dist/commands/unread.js.map +1 -1
  13. package/dist/index.js +0 -0
  14. package/dist/types/commands.d.ts +1 -0
  15. package/dist/types/commands.d.ts.map +1 -1
  16. package/dist/utils/errors.d.ts.map +1 -1
  17. package/dist/utils/errors.js +1 -5
  18. package/dist/utils/errors.js.map +1 -1
  19. package/dist/utils/formatters/history-formatters.d.ts +8 -0
  20. package/dist/utils/formatters/history-formatters.d.ts.map +1 -0
  21. package/dist/utils/formatters/history-formatters.js +105 -0
  22. package/dist/utils/formatters/history-formatters.js.map +1 -0
  23. package/dist/utils/validators.d.ts +4 -0
  24. package/dist/utils/validators.d.ts.map +1 -1
  25. package/dist/utils/validators.js +12 -0
  26. package/dist/utils/validators.js.map +1 -1
  27. package/eslint.config.js +38 -0
  28. package/package.json +12 -14
  29. package/src/commands/history-display.ts +9 -28
  30. package/src/commands/history.ts +9 -2
  31. package/src/commands/unread.ts +52 -22
  32. package/src/types/commands.ts +1 -0
  33. package/src/utils/errors.ts +1 -5
  34. package/src/utils/formatters/history-formatters.ts +123 -0
  35. package/src/utils/validators.ts +13 -0
  36. package/tests/commands/history.test.ts +115 -0
  37. package/tests/index.test.ts +2 -2
  38. package/.eslintrc.json +0 -25
  39. package/dist/utils/config.d.ts +0 -10
  40. package/dist/utils/config.d.ts.map +0 -1
  41. package/dist/utils/config.js +0 -94
  42. package/dist/utils/config.js.map +0 -1
  43. package/dist/utils/formatters/output-formatter.d.ts +0 -7
  44. package/dist/utils/formatters/output-formatter.d.ts.map +0 -1
  45. package/dist/utils/formatters/output-formatter.js +0 -7
  46. package/dist/utils/formatters/output-formatter.js.map +0 -1
  47. package/dist/utils/profile-config-refactored.d.ts +0 -20
  48. package/dist/utils/profile-config-refactored.d.ts.map +0 -1
  49. package/dist/utils/profile-config-refactored.js +0 -174
  50. package/dist/utils/profile-config-refactored.js.map +0 -1
  51. package/src/utils/formatters/output-formatter.ts +0 -7
  52. package/tests/utils/slack-operations/channel-operations-refactored.test.ts +0 -179
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@urugus/slack-cli",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "A command-line tool for sending messages to Slack",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -31,27 +31,25 @@
31
31
  },
32
32
  "license": "MIT",
33
33
  "dependencies": {
34
- "@slack/web-api": "^6.9.0",
35
- "chalk": "^4.1.2",
36
- "commander": "^11.1.0",
37
- "dotenv": "^16.3.1",
38
- "inquirer": "^8.2.6",
34
+ "@slack/web-api": "^7.9.3",
35
+ "chalk": "^5.4.1",
36
+ "commander": "^14.0.0",
39
37
  "p-limit": "^3.1.0"
40
38
  },
41
39
  "devDependencies": {
42
- "@types/inquirer": "^8.2.10",
43
40
  "@types/node": "^20.10.0",
44
- "@typescript-eslint/eslint-plugin": "^6.13.0",
45
- "@typescript-eslint/parser": "^6.13.0",
46
- "@vitest/coverage-v8": "^1.0.4",
47
- "eslint": "^8.55.0",
48
- "eslint-config-prettier": "^9.1.0",
41
+ "@typescript-eslint/eslint-plugin": "^8.34.1",
42
+ "@typescript-eslint/parser": "^8.34.1",
43
+ "@vitest/coverage-v8": "^3.2.4",
44
+ "eslint": "^9.30.0",
45
+ "eslint-config-prettier": "^10.1.5",
49
46
  "prettier": "^3.1.1",
50
47
  "ts-node": "^10.9.1",
51
48
  "typescript": "^5.3.2",
52
- "vitest": "^1.0.4"
49
+ "typescript-eslint": "^8.35.0",
50
+ "vitest": "^3.2.4"
53
51
  },
54
52
  "engines": {
55
- "node": ">=16.0.0"
53
+ "node": ">=20.0.0"
56
54
  }
57
55
  }
@@ -1,38 +1,19 @@
1
- import chalk from 'chalk';
2
1
  import { Message } from '../utils/slack-api-client';
3
- import { formatSlackTimestamp } from '../utils/date-utils';
4
- import { formatMessageWithMentions } from '../utils/format-utils';
2
+ import { createHistoryFormatter } from '../utils/formatters/history-formatters';
5
3
 
6
4
  export function displayHistoryResults(
7
5
  messages: Message[],
8
6
  users: Map<string, string>,
9
- channelName: string
7
+ channelName: string,
8
+ format = 'table'
10
9
  ): void {
11
- if (messages.length === 0) {
12
- console.log(chalk.yellow('No messages found in the specified channel.'));
13
- return;
14
- }
15
-
16
- console.log(chalk.bold(`\nMessage History for #${channelName}:\n`));
17
-
18
10
  // Display messages in reverse order (oldest first)
19
- messages.reverse().forEach((message: Message) => {
20
- const timestamp = formatSlackTimestamp(message.ts);
21
- let author = 'Unknown';
11
+ const orderedMessages = [...messages].reverse();
22
12
 
23
- if (message.user && users.has(message.user)) {
24
- author = users.get(message.user)!;
25
- } else if (message.bot_id) {
26
- author = 'Bot';
27
- }
28
-
29
- console.log(chalk.gray(`[${timestamp}]`) + ' ' + chalk.cyan(author));
30
- if (message.text) {
31
- const formattedText = formatMessageWithMentions(message.text, users);
32
- console.log(formattedText);
33
- }
34
- console.log(''); // Empty line between messages
13
+ const formatter = createHistoryFormatter(format);
14
+ formatter.format({
15
+ channelName,
16
+ messages: orderedMessages,
17
+ users,
35
18
  });
36
-
37
- console.log(chalk.green(`✓ Displayed ${messages.length} message(s)`));
38
19
  }
@@ -6,6 +6,7 @@ import { HistoryOptions } from '../types/commands';
6
6
  import { API_LIMITS } from '../utils/constants';
7
7
  import { parseCount, parseProfile } from '../utils/option-parsers';
8
8
  import { createValidationHook, optionValidators } from '../utils/validators';
9
+ import { parseFormat } from '../utils/option-parsers';
9
10
  import { prepareSinceTimestamp } from './history-validators';
10
11
  import { displayHistoryResults } from './history-display';
11
12
 
@@ -19,10 +20,15 @@ export function setupHistoryCommand(): Command {
19
20
  API_LIMITS.DEFAULT_MESSAGE_COUNT.toString()
20
21
  )
21
22
  .option('--since <date>', 'Get messages since specific date (YYYY-MM-DD HH:MM:SS)')
23
+ .option('--format <format>', 'Output format: table, simple, json', 'table')
22
24
  .option('--profile <profile>', 'Use specific workspace profile')
23
25
  .hook(
24
26
  'preAction',
25
- createValidationHook([optionValidators.messageCount, optionValidators.sinceDate])
27
+ createValidationHook([
28
+ optionValidators.messageCount,
29
+ optionValidators.sinceDate,
30
+ optionValidators.format,
31
+ ])
26
32
  )
27
33
  .action(
28
34
  wrapCommand(async (options: HistoryOptions) => {
@@ -46,7 +52,8 @@ export function setupHistoryCommand(): Command {
46
52
  }
47
53
 
48
54
  const { messages, users } = await client.getHistory(options.channel, historyOptions);
49
- displayHistoryResults(messages, users, options.channel);
55
+ const format = parseFormat(options.format);
56
+ displayHistoryResults(messages, users, options.channel, format);
50
57
  })
51
58
  );
52
59
 
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import { wrapCommand } from '../utils/command-wrapper';
3
3
  import { createSlackClient } from '../utils/client-factory';
4
- import { SlackApiClient } from '../utils/slack-api-client';
4
+ import { SlackApiClient, ChannelUnreadResult, Channel } from '../utils/slack-api-client';
5
5
  import { UnreadOptions } from '../types/commands';
6
6
  import chalk from 'chalk';
7
7
  import { createChannelFormatter } from '../utils/formatters/channel-formatters';
@@ -9,15 +9,15 @@ import { createMessageFormatter } from '../utils/formatters/message-formatters';
9
9
  import { DEFAULTS } from '../utils/constants';
10
10
  import { parseLimit, parseFormat, parseBoolean } from '../utils/option-parsers';
11
11
 
12
- async function handleSpecificChannelUnread(
13
- client: SlackApiClient,
14
- options: UnreadOptions
15
- ): Promise<void> {
16
- const result = await client.getChannelUnread(options.channel!);
17
-
18
- const format = parseFormat(options.format);
19
- const countOnly = parseBoolean(options.countOnly);
12
+ async function fetchChannelUnreadData(client: SlackApiClient, channelName: string) {
13
+ return await client.getChannelUnread(channelName);
14
+ }
20
15
 
16
+ function formatChannelUnreadOutput(
17
+ result: ChannelUnreadResult,
18
+ format: string,
19
+ countOnly: boolean
20
+ ): void {
21
21
  const formatter = createMessageFormatter(format);
22
22
  formatter.format({
23
23
  channel: result.channel,
@@ -26,40 +26,70 @@ async function handleSpecificChannelUnread(
26
26
  countOnly: countOnly,
27
27
  format: format,
28
28
  });
29
+ }
30
+
31
+ async function markChannelAsRead(client: SlackApiClient, channel: Channel): Promise<void> {
32
+ await client.markAsRead(channel.id);
33
+ console.log(chalk.green(`✓ Marked messages in #${channel.name} as read`));
34
+ }
35
+
36
+ async function handleSpecificChannelUnread(
37
+ client: SlackApiClient,
38
+ options: UnreadOptions
39
+ ): Promise<void> {
40
+ const result = await fetchChannelUnreadData(client, options.channel!);
41
+
42
+ const format = parseFormat(options.format);
43
+ const countOnly = parseBoolean(options.countOnly);
44
+
45
+ formatChannelUnreadOutput(result, format, countOnly);
29
46
 
30
47
  if (parseBoolean(options.markRead)) {
31
- await client.markAsRead(result.channel.id);
32
- console.log(chalk.green(`✓ Marked messages in #${result.channel.name} as read`));
48
+ await markChannelAsRead(client, result.channel);
33
49
  }
34
50
  }
35
51
 
52
+ async function fetchAllUnreadChannels(client: SlackApiClient) {
53
+ return await client.listUnreadChannels();
54
+ }
55
+
56
+ function formatAllChannelsOutput(
57
+ channels: Channel[],
58
+ format: string,
59
+ countOnly: boolean,
60
+ limit: number
61
+ ): void {
62
+ const displayChannels = channels.slice(0, limit);
63
+ const formatter = createChannelFormatter(format, countOnly);
64
+ formatter.format({ channels: displayChannels, countOnly: countOnly });
65
+ }
66
+
67
+ async function markAllChannelsAsRead(client: SlackApiClient, channels: Channel[]): Promise<void> {
68
+ for (const channel of channels) {
69
+ await client.markAsRead(channel.id);
70
+ }
71
+ console.log(chalk.green('✓ Marked all messages as read'));
72
+ }
73
+
36
74
  async function handleAllChannelsUnread(
37
75
  client: SlackApiClient,
38
76
  options: UnreadOptions
39
77
  ): Promise<void> {
40
- const channels = await client.listUnreadChannels();
78
+ const channels = await fetchAllUnreadChannels(client);
41
79
 
42
80
  if (channels.length === 0) {
43
81
  console.log(chalk.green('✓ No unread messages'));
44
82
  return;
45
83
  }
46
84
 
47
- // Apply limit
48
85
  const limit = parseLimit(options.limit, DEFAULTS.UNREAD_DISPLAY_LIMIT);
49
- const displayChannels = channels.slice(0, limit);
50
-
51
86
  const format = parseFormat(options.format);
52
87
  const countOnly = parseBoolean(options.countOnly);
53
88
 
54
- const formatter = createChannelFormatter(format, countOnly);
55
- formatter.format({ channels: displayChannels, countOnly: countOnly });
89
+ formatAllChannelsOutput(channels, format, countOnly, limit);
56
90
 
57
91
  if (parseBoolean(options.markRead)) {
58
- // Mark all unread channels as read
59
- for (const channel of channels) {
60
- await client.markAsRead(channel.id);
61
- }
62
- console.log(chalk.green('✓ Marked all messages as read'));
92
+ await markAllChannelsAsRead(client, channels);
63
93
  }
64
94
  }
65
95
 
@@ -35,6 +35,7 @@ export interface HistoryOptions {
35
35
  channel: string;
36
36
  number?: string;
37
37
  since?: string;
38
+ format?: 'table' | 'simple' | 'json';
38
39
  profile?: string;
39
40
  }
40
41
 
@@ -4,34 +4,30 @@ export class SlackCliError extends Error {
4
4
  public code?: string
5
5
  ) {
6
6
  super(message);
7
- this.name = 'SlackCliError';
7
+ this.name = this.constructor.name;
8
8
  }
9
9
  }
10
10
 
11
11
  export class ConfigurationError extends SlackCliError {
12
12
  constructor(message: string) {
13
13
  super(message, 'CONFIGURATION_ERROR');
14
- this.name = 'ConfigurationError';
15
14
  }
16
15
  }
17
16
 
18
17
  export class ValidationError extends SlackCliError {
19
18
  constructor(message: string) {
20
19
  super(message, 'VALIDATION_ERROR');
21
- this.name = 'ValidationError';
22
20
  }
23
21
  }
24
22
 
25
23
  export class ApiError extends SlackCliError {
26
24
  constructor(message: string) {
27
25
  super(message, 'API_ERROR');
28
- this.name = 'ApiError';
29
26
  }
30
27
  }
31
28
 
32
29
  export class FileError extends SlackCliError {
33
30
  constructor(message: string) {
34
31
  super(message, 'FILE_ERROR');
35
- this.name = 'FileError';
36
32
  }
37
33
  }
@@ -0,0 +1,123 @@
1
+ import chalk from 'chalk';
2
+ import { AbstractFormatter, JsonFormatter, createFormatterFactory } from './base-formatter';
3
+ import { formatSlackTimestamp } from '../date-utils';
4
+
5
+ function formatTimestampFixed(slackTimestamp: string): string {
6
+ const timestamp = parseFloat(slackTimestamp);
7
+ const date = new Date(timestamp * 1000);
8
+ const year = date.getUTCFullYear();
9
+ const month = String(date.getUTCMonth() + 1).padStart(2, '0');
10
+ const day = String(date.getUTCDate()).padStart(2, '0');
11
+ const hours = String(date.getUTCHours()).padStart(2, '0');
12
+ const minutes = String(date.getUTCMinutes()).padStart(2, '0');
13
+ const seconds = String(date.getUTCSeconds()).padStart(2, '0');
14
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
15
+ }
16
+ import { formatMessageWithMentions } from '../format-utils';
17
+ import { Message as SlackMessage } from '../slack-api-client';
18
+
19
+ export interface HistoryFormatterOptions {
20
+ channelName: string;
21
+ messages: SlackMessage[];
22
+ users: Map<string, string>;
23
+ }
24
+
25
+ class TableHistoryFormatter extends AbstractFormatter<HistoryFormatterOptions> {
26
+ format(options: HistoryFormatterOptions): void {
27
+ const { channelName, messages, users } = options;
28
+
29
+ console.log(chalk.bold(`\nMessage History for #${channelName}:`));
30
+
31
+ if (messages.length === 0) {
32
+ console.log(chalk.yellow('No messages found'));
33
+ return;
34
+ }
35
+
36
+ console.log('');
37
+ messages.forEach((message) => {
38
+ const timestamp = formatTimestampFixed(message.ts);
39
+ const username = this.getUsername(message, users);
40
+
41
+ console.log(`${chalk.gray(`[${timestamp}]`)} ${chalk.cyan(username)}`);
42
+ const text = message.text ? formatMessageWithMentions(message.text, users) : '(no text)';
43
+ console.log(text);
44
+ console.log('');
45
+ });
46
+
47
+ console.log(chalk.green(`✓ Displayed ${messages.length} message(s)`));
48
+ }
49
+
50
+ private getUsername(message: SlackMessage, users: Map<string, string>): string {
51
+ if (message.user) {
52
+ return users.get(message.user) || 'Unknown User';
53
+ }
54
+ if (message.bot_id) {
55
+ return 'Bot';
56
+ }
57
+ return 'Unknown';
58
+ }
59
+ }
60
+
61
+ class SimpleHistoryFormatter extends AbstractFormatter<HistoryFormatterOptions> {
62
+ format(options: HistoryFormatterOptions): void {
63
+ const { messages, users } = options;
64
+
65
+ if (messages.length === 0) {
66
+ console.log('No messages found');
67
+ return;
68
+ }
69
+
70
+ messages.forEach((message) => {
71
+ const timestamp = formatTimestampFixed(message.ts);
72
+ const username = this.getUsername(message, users);
73
+ const text = message.text ? formatMessageWithMentions(message.text, users) : '(no text)';
74
+ console.log(`[${timestamp}] ${username}: ${text}`);
75
+ });
76
+ }
77
+
78
+ private getUsername(message: SlackMessage, users: Map<string, string>): string {
79
+ if (message.user) {
80
+ return users.get(message.user) || 'Unknown User';
81
+ }
82
+ if (message.bot_id) {
83
+ return 'Bot';
84
+ }
85
+ return 'Unknown';
86
+ }
87
+ }
88
+
89
+ class JsonHistoryFormatter extends JsonFormatter<HistoryFormatterOptions> {
90
+ protected transform(options: HistoryFormatterOptions) {
91
+ const { channelName, messages, users } = options;
92
+
93
+ return {
94
+ channel: channelName,
95
+ messages: messages.map((message) => ({
96
+ timestamp: formatTimestampFixed(message.ts),
97
+ user: this.getUsername(message, users),
98
+ text: message.text || '(no text)',
99
+ })),
100
+ total: messages.length,
101
+ };
102
+ }
103
+
104
+ private getUsername(message: SlackMessage, users: Map<string, string>): string {
105
+ if (message.user) {
106
+ return users.get(message.user) || 'Unknown User';
107
+ }
108
+ if (message.bot_id) {
109
+ return 'Bot';
110
+ }
111
+ return 'Unknown';
112
+ }
113
+ }
114
+
115
+ const historyFormatterFactory = createFormatterFactory<HistoryFormatterOptions>({
116
+ table: new TableHistoryFormatter(),
117
+ simple: new SimpleHistoryFormatter(),
118
+ json: new JsonHistoryFormatter(),
119
+ });
120
+
121
+ export function createHistoryFormatter(format: string) {
122
+ return historyFormatterFactory.create(format);
123
+ }
@@ -190,6 +190,19 @@ export const optionValidators = {
190
190
  }
191
191
  return null;
192
192
  },
193
+
194
+ /**
195
+ * Validates format option
196
+ */
197
+ format: (options: Record<string, unknown>): string | null => {
198
+ if (options.format) {
199
+ const validFormats = ['table', 'simple', 'json'];
200
+ if (!validFormats.includes(options.format as string)) {
201
+ return `Invalid format '${options.format}'. Must be one of: ${validFormats.join(', ')}`;
202
+ }
203
+ }
204
+ return null;
205
+ },
193
206
  };
194
207
 
195
208
  /**
@@ -217,6 +217,121 @@ describe('history command', () => {
217
217
  });
218
218
 
219
219
  describe('output formatting', () => {
220
+ describe('format options', () => {
221
+ it('should display messages in JSON format when --format json is specified', async () => {
222
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
223
+ token: 'test-token',
224
+ updatedAt: new Date().toISOString()
225
+ });
226
+
227
+ const mockMessages = [
228
+ {
229
+ type: 'message',
230
+ text: 'Hello world',
231
+ user: 'U123456',
232
+ ts: '1609459200.000100',
233
+ },
234
+ {
235
+ type: 'message',
236
+ text: 'Another message',
237
+ user: 'U789012',
238
+ ts: '1609459300.000200',
239
+ },
240
+ ];
241
+
242
+ vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
243
+ messages: mockMessages,
244
+ users: new Map([
245
+ ['U123456', 'john.doe'],
246
+ ['U789012', 'jane.smith']
247
+ ])
248
+ });
249
+
250
+ await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--format', 'json']);
251
+
252
+ const expectedOutput = {
253
+ channel: 'general',
254
+ messages: [
255
+ {
256
+ timestamp: '2021-01-01 00:01:40',
257
+ user: 'jane.smith',
258
+ text: 'Another message'
259
+ },
260
+ {
261
+ timestamp: '2021-01-01 00:00:00',
262
+ user: 'john.doe',
263
+ text: 'Hello world'
264
+ }
265
+ ],
266
+ total: 2
267
+ };
268
+
269
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(JSON.stringify(expectedOutput, null, 2));
270
+ });
271
+
272
+ it('should display messages in simple format when --format simple is specified', async () => {
273
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
274
+ token: 'test-token',
275
+ updatedAt: new Date().toISOString()
276
+ });
277
+
278
+ const mockMessages = [
279
+ {
280
+ type: 'message',
281
+ text: 'Hello world',
282
+ user: 'U123456',
283
+ ts: '1609459200.000100',
284
+ },
285
+ ];
286
+
287
+ vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
288
+ messages: mockMessages,
289
+ users: new Map([['U123456', 'john.doe']])
290
+ });
291
+
292
+ await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general', '--format', 'simple']);
293
+
294
+ expect(mockConsole.logSpy).toHaveBeenCalledWith('[2021-01-01 00:00:00] john.doe: Hello world');
295
+ });
296
+
297
+ it('should display messages in table format by default', async () => {
298
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
299
+ token: 'test-token',
300
+ updatedAt: new Date().toISOString()
301
+ });
302
+
303
+ const mockMessages = [
304
+ {
305
+ type: 'message',
306
+ text: 'Hello world',
307
+ user: 'U123456',
308
+ ts: '1609459200.000100',
309
+ },
310
+ ];
311
+
312
+ vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
313
+ messages: mockMessages,
314
+ users: new Map([['U123456', 'john.doe']])
315
+ });
316
+
317
+ await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'general']);
318
+
319
+ // Should display in table format (current format)
320
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Message History for #general'));
321
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('john.doe'));
322
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('Hello world'));
323
+ });
324
+
325
+ it('should handle invalid format option', async () => {
326
+ const historyCommand = setupHistoryCommand();
327
+ historyCommand.exitOverride();
328
+
329
+ await expect(
330
+ historyCommand.parseAsync(['-c', 'general', '--format', 'invalid'], { from: 'user' })
331
+ ).rejects.toThrow();
332
+ });
333
+ });
334
+
220
335
  it('should format messages with user names and timestamps', async () => {
221
336
  vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
222
337
  token: 'test-token',
@@ -4,7 +4,7 @@ import { readFileSync } from 'fs';
4
4
  import { join } from 'path';
5
5
 
6
6
  describe('slack-cli version', () => {
7
- it('should display the correct version from package.json', () => {
7
+ it('should display the correct version from package.json', { timeout: 20000 }, () => {
8
8
  // Read the expected version from package.json
9
9
  const packageJson = JSON.parse(
10
10
  readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')
@@ -21,7 +21,7 @@ describe('slack-cli version', () => {
21
21
  expect(output).toBe(expectedVersion);
22
22
  });
23
23
 
24
- it('should display version with -V flag', () => {
24
+ it('should display version with -V flag', { timeout: 20000 }, () => {
25
25
  // Read the expected version from package.json
26
26
  const packageJson = JSON.parse(
27
27
  readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')
package/.eslintrc.json DELETED
@@ -1,25 +0,0 @@
1
- {
2
- "parser": "@typescript-eslint/parser",
3
- "extends": [
4
- "eslint:recommended",
5
- "plugin:@typescript-eslint/recommended",
6
- "prettier"
7
- ],
8
- "plugins": ["@typescript-eslint"],
9
- "parserOptions": {
10
- "ecmaVersion": 2020,
11
- "sourceType": "module",
12
- "project": "./tsconfig.json"
13
- },
14
- "env": {
15
- "node": true,
16
- "es2020": true
17
- },
18
- "rules": {
19
- "@typescript-eslint/explicit-function-return-type": "off",
20
- "@typescript-eslint/no-explicit-any": "warn",
21
- "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
22
- "no-console": "off"
23
- },
24
- "ignorePatterns": ["dist", "node_modules", "coverage", "vitest.config.ts"]
25
- }
@@ -1,10 +0,0 @@
1
- import type { Config, ConfigOptions } from '../types/config';
2
- export declare class ConfigManager {
3
- private configPath;
4
- constructor(options?: ConfigOptions);
5
- setToken(token: string): Promise<void>;
6
- getConfig(): Promise<Config | null>;
7
- clearConfig(): Promise<void>;
8
- maskToken(token: string): string;
9
- }
10
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE7D,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,GAAE,aAAkB;IAKjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatC,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqBnC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAUlC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAUjC"}