@urugus/slack-cli 0.2.11 → 0.2.13

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 (97) hide show
  1. package/README.md +4 -0
  2. package/dist/commands/history-display.d.ts +5 -1
  3. package/dist/commands/history-display.d.ts.map +1 -1
  4. package/dist/commands/history-display.js +3 -3
  5. package/dist/commands/history-display.js.map +1 -1
  6. package/dist/commands/history.d.ts.map +1 -1
  7. package/dist/commands/history.js +28 -11
  8. package/dist/commands/history.js.map +1 -1
  9. package/dist/types/commands.d.ts +1 -0
  10. package/dist/types/commands.d.ts.map +1 -1
  11. package/dist/utils/slack-api-client.d.ts +1 -0
  12. package/dist/utils/slack-api-client.d.ts.map +1 -1
  13. package/dist/utils/slack-api-client.js +3 -0
  14. package/dist/utils/slack-api-client.js.map +1 -1
  15. package/dist/utils/slack-operations/message-operations.d.ts +1 -0
  16. package/dist/utils/slack-operations/message-operations.d.ts.map +1 -1
  17. package/dist/utils/slack-operations/message-operations.js +21 -0
  18. package/dist/utils/slack-operations/message-operations.js.map +1 -1
  19. package/package.json +5 -2
  20. package/.claude/settings.local.json +0 -75
  21. package/.github/dependabot.yml +0 -18
  22. package/.github/workflows/ci.yml +0 -70
  23. package/.github/workflows/pr-validation.yml +0 -41
  24. package/.prettierignore +0 -11
  25. package/.prettierrc +0 -10
  26. package/CHANGELOG.md +0 -61
  27. package/CLAUDE.md +0 -16
  28. package/eslint.config.js +0 -38
  29. package/src/commands/channels.ts +0 -50
  30. package/src/commands/config-subcommands.ts +0 -63
  31. package/src/commands/config.ts +0 -50
  32. package/src/commands/history-display.ts +0 -19
  33. package/src/commands/history-validators.ts +0 -46
  34. package/src/commands/history.ts +0 -61
  35. package/src/commands/scheduled.ts +0 -71
  36. package/src/commands/send.ts +0 -69
  37. package/src/commands/unread.ts +0 -122
  38. package/src/index.ts +0 -27
  39. package/src/types/commands.ts +0 -58
  40. package/src/types/config.ts +0 -20
  41. package/src/utils/channel-formatter.ts +0 -45
  42. package/src/utils/channel-resolver.ts +0 -82
  43. package/src/utils/client-factory.ts +0 -10
  44. package/src/utils/command-wrapper.ts +0 -27
  45. package/src/utils/config/config-file-manager.ts +0 -56
  46. package/src/utils/config/profile-manager.ts +0 -79
  47. package/src/utils/config/token-crypto-service.ts +0 -80
  48. package/src/utils/config-helper.ts +0 -21
  49. package/src/utils/constants.ts +0 -78
  50. package/src/utils/date-utils.ts +0 -8
  51. package/src/utils/error-utils.ts +0 -6
  52. package/src/utils/errors.ts +0 -33
  53. package/src/utils/format-utils.ts +0 -9
  54. package/src/utils/formatters/base-formatter.ts +0 -34
  55. package/src/utils/formatters/channel-formatters.ts +0 -71
  56. package/src/utils/formatters/channels-list-formatters.ts +0 -55
  57. package/src/utils/formatters/history-formatters.ts +0 -123
  58. package/src/utils/formatters/message-formatters.ts +0 -85
  59. package/src/utils/mention-utils.ts +0 -47
  60. package/src/utils/option-parsers.ts +0 -100
  61. package/src/utils/profile-config.ts +0 -161
  62. package/src/utils/schedule-utils.ts +0 -41
  63. package/src/utils/slack-api-client.ts +0 -135
  64. package/src/utils/slack-operations/base-client.ts +0 -30
  65. package/src/utils/slack-operations/channel-operations.ts +0 -161
  66. package/src/utils/slack-operations/index.ts +0 -3
  67. package/src/utils/slack-operations/message-operations.ts +0 -176
  68. package/src/utils/slack-patterns.ts +0 -9
  69. package/src/utils/token-utils.ts +0 -17
  70. package/src/utils/validators.ts +0 -263
  71. package/tests/commands/channels.test.ts +0 -250
  72. package/tests/commands/config.test.ts +0 -158
  73. package/tests/commands/history.test.ts +0 -403
  74. package/tests/commands/scheduled.test.ts +0 -131
  75. package/tests/commands/send.test.ts +0 -414
  76. package/tests/commands/unread.test.ts +0 -492
  77. package/tests/index.test.ts +0 -40
  78. package/tests/test-utils.ts +0 -28
  79. package/tests/utils/channel-resolver.test.ts +0 -161
  80. package/tests/utils/config/config-file-manager.test.ts +0 -118
  81. package/tests/utils/config/profile-manager.test.ts +0 -266
  82. package/tests/utils/config/token-crypto-service.test.ts +0 -98
  83. package/tests/utils/config.test.ts +0 -400
  84. package/tests/utils/date-utils.test.ts +0 -30
  85. package/tests/utils/error-utils.test.ts +0 -34
  86. package/tests/utils/format-utils.test.ts +0 -61
  87. package/tests/utils/mention-utils.test.ts +0 -100
  88. package/tests/utils/option-parsers.test.ts +0 -173
  89. package/tests/utils/profile-config.test.ts +0 -282
  90. package/tests/utils/schedule-utils.test.ts +0 -63
  91. package/tests/utils/slack-api-client.test.ts +0 -313
  92. package/tests/utils/slack-operations/channel-operations.test.ts +0 -248
  93. package/tests/utils/slack-operations/message-operations.test.ts +0 -163
  94. package/tests/utils/token-utils.test.ts +0 -33
  95. package/tests/utils/validators.test.ts +0 -307
  96. package/tsconfig.json +0 -22
  97. package/vitest.config.ts +0 -27
@@ -1,163 +0,0 @@
1
- import { beforeEach, describe, it, expect, vi } from 'vitest';
2
- import { MessageOperations } from '../../../src/utils/slack-operations/message-operations';
3
- import { channelResolver } from '../../../src/utils/channel-resolver';
4
-
5
- vi.mock('@slack/web-api', () => ({
6
- WebClient: vi.fn().mockImplementation(() => ({
7
- conversations: {
8
- history: vi.fn(),
9
- },
10
- users: {
11
- info: vi.fn(),
12
- },
13
- chat: {
14
- postMessage: vi.fn(),
15
- scheduleMessage: vi.fn(),
16
- scheduledMessages: {
17
- list: vi.fn(),
18
- },
19
- },
20
- })),
21
- LogLevel: {
22
- ERROR: 'error',
23
- },
24
- }));
25
-
26
- vi.mock('../../../src/utils/channel-resolver');
27
-
28
- describe('MessageOperations', () => {
29
- let messageOps: MessageOperations;
30
- let mockClient: any;
31
-
32
- beforeEach(() => {
33
- vi.clearAllMocks();
34
- messageOps = new MessageOperations('test-token');
35
- mockClient = (messageOps as any).client;
36
- });
37
-
38
- describe('scheduleMessage', () => {
39
- it('should call chat.scheduleMessage with post_at', async () => {
40
- mockClient.chat.scheduleMessage.mockResolvedValue({
41
- ok: true,
42
- scheduled_message_id: 'Q123',
43
- });
44
-
45
- await messageOps.scheduleMessage('C1234567890', 'Hello', 1770855000);
46
-
47
- expect(mockClient.chat.scheduleMessage).toHaveBeenCalledWith({
48
- channel: 'C1234567890',
49
- text: 'Hello',
50
- post_at: 1770855000,
51
- });
52
- });
53
- });
54
-
55
- describe('listScheduledMessages', () => {
56
- it('should call chat.scheduledMessages.list', async () => {
57
- mockClient.chat.scheduledMessages.list.mockResolvedValue({
58
- ok: true,
59
- scheduled_messages: [
60
- { id: 'Q123', channel_id: 'C123', post_at: 1770855000, date_created: 1770854400 },
61
- ],
62
- });
63
-
64
- const result = await messageOps.listScheduledMessages(undefined, 20);
65
-
66
- expect(mockClient.chat.scheduledMessages.list).toHaveBeenCalledWith({ limit: 20 });
67
- expect(result).toHaveLength(1);
68
- });
69
- });
70
-
71
- describe('getHistory with mentions', () => {
72
- it('should fetch user info for mentioned users in message text', async () => {
73
- const mockMessages = [
74
- {
75
- type: 'message',
76
- text: 'Hello <@U123456789> can you check this?',
77
- user: 'U987654321',
78
- ts: '1234567890.123456',
79
- },
80
- {
81
- type: 'message',
82
- text: '<@U111111111> and <@U222222222> please review',
83
- user: 'U333333333',
84
- ts: '1234567891.123456',
85
- },
86
- ];
87
-
88
- const mockUsersInfo = {
89
- U123456789: { ok: true, user: { name: 'john.doe' } },
90
- U987654321: { ok: true, user: { name: 'jane.smith' } },
91
- U111111111: { ok: true, user: { name: 'alice.brown' } },
92
- U222222222: { ok: true, user: { name: 'bob.wilson' } },
93
- U333333333: { ok: true, user: { name: 'charlie.davis' } },
94
- };
95
-
96
- mockClient.conversations.history.mockResolvedValue({
97
- ok: true,
98
- messages: mockMessages,
99
- });
100
-
101
- mockClient.users.info.mockImplementation(({ user }: { user: string }) => {
102
- return Promise.resolve(mockUsersInfo[user] || { ok: false });
103
- });
104
-
105
- vi.mocked(channelResolver.resolveChannelId).mockResolvedValue('C123456789');
106
-
107
- const result = await messageOps.getHistory('test-channel', { limit: 10 });
108
-
109
- // Verify all user IDs were fetched (both message authors and mentioned users)
110
- expect(mockClient.users.info).toHaveBeenCalledTimes(5);
111
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U987654321' });
112
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U333333333' });
113
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U123456789' });
114
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U111111111' });
115
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U222222222' });
116
-
117
- // Verify the returned users map contains all users
118
- expect(result.users.get('U123456789')).toBe('john.doe');
119
- expect(result.users.get('U987654321')).toBe('jane.smith');
120
- expect(result.users.get('U111111111')).toBe('alice.brown');
121
- expect(result.users.get('U222222222')).toBe('bob.wilson');
122
- expect(result.users.get('U333333333')).toBe('charlie.davis');
123
- });
124
-
125
- it('should handle messages with own mentions correctly', async () => {
126
- const mockMessages = [
127
- {
128
- type: 'message',
129
- text: '<@U07L5D50RAL> please check this task',
130
- user: 'U123456789',
131
- ts: '1234567890.123456',
132
- },
133
- ];
134
-
135
- const mockUsersInfo = {
136
- U123456789: { ok: true, user: { name: 'john.doe' } },
137
- U07L5D50RAL: { ok: true, user: { name: 'koguchi_s' } },
138
- };
139
-
140
- mockClient.conversations.history.mockResolvedValue({
141
- ok: true,
142
- messages: mockMessages,
143
- });
144
-
145
- mockClient.users.info.mockImplementation(({ user }: { user: string }) => {
146
- return Promise.resolve(mockUsersInfo[user] || { ok: false });
147
- });
148
-
149
- vi.mocked(channelResolver.resolveChannelId).mockResolvedValue('C123456789');
150
-
151
- const result = await messageOps.getHistory('test-channel', { limit: 10 });
152
-
153
- // Verify both users were fetched
154
- expect(mockClient.users.info).toHaveBeenCalledTimes(2);
155
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U123456789' });
156
- expect(mockClient.users.info).toHaveBeenCalledWith({ user: 'U07L5D50RAL' });
157
-
158
- // Verify the returned users map contains both users
159
- expect(result.users.get('U123456789')).toBe('john.doe');
160
- expect(result.users.get('U07L5D50RAL')).toBe('koguchi_s');
161
- });
162
- });
163
- });
@@ -1,33 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { maskToken } from '../../src/utils/token-utils';
3
-
4
- describe('token-utils', () => {
5
- describe('maskToken', () => {
6
- it('should mask short tokens completely', () => {
7
- expect(maskToken('short')).toBe('****');
8
- expect(maskToken('123456789')).toBe('****');
9
- expect(maskToken('')).toBe('****');
10
- });
11
-
12
- it('should mask long tokens showing prefix and suffix', () => {
13
- const token = 'test-1234567890-abcdefghijklmnop';
14
- expect(maskToken(token)).toBe('test-****-****-mnop');
15
- });
16
-
17
- it('should handle tokens of exactly minimum length + 1', () => {
18
- const token = '1234567890'; // 10 characters
19
- expect(maskToken(token)).toBe('1234-****-****-7890');
20
- });
21
-
22
- it('should handle various token formats', () => {
23
- expect(maskToken('test-123456789012345')).toBe('test-****-****-2345');
24
- expect(maskToken('demo-2-123456789012345')).toBe('demo-****-****-2345');
25
- expect(maskToken('1234567890123456789012345')).toBe('1234-****-****-2345');
26
- });
27
-
28
- it('should handle tokens with special characters', () => {
29
- expect(maskToken('test-token-with-dashes')).toBe('test-****-****-shes');
30
- expect(maskToken('token_with_underscores')).toBe('toke-****-****-ores');
31
- });
32
- });
33
- });
@@ -1,307 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import {
3
- validateRequired,
4
- validateMutuallyExclusive,
5
- validateFormat,
6
- validateRange,
7
- validateDateFormat,
8
- formatValidators,
9
- createValidationHook,
10
- optionValidators,
11
- createOptionParser,
12
- } from '../../src/utils/validators';
13
- import { Command } from 'commander';
14
-
15
- describe('validators', () => {
16
- describe('validateRequired', () => {
17
- it('should return null for valid values', () => {
18
- expect(validateRequired('value', 'field')).toBeNull();
19
- expect(validateRequired(123, 'field')).toBeNull();
20
- expect(validateRequired(true, 'field')).toBeNull();
21
- expect(validateRequired(0, 'field')).toBeNull();
22
- expect(validateRequired(false, 'field')).toBeNull();
23
- });
24
-
25
- it('should return error for invalid values', () => {
26
- expect(validateRequired(undefined, 'field')).toBe('field is required');
27
- expect(validateRequired(null, 'field')).toBe('field is required');
28
- expect(validateRequired('', 'field')).toBe('field is required');
29
- });
30
- });
31
-
32
- describe('validateMutuallyExclusive', () => {
33
- it('should return null when exactly one option is present', () => {
34
- expect(validateMutuallyExclusive({ a: 'value' }, ['a', 'b'])).toBeNull();
35
- expect(validateMutuallyExclusive({ b: 'value' }, ['a', 'b'])).toBeNull();
36
- });
37
-
38
- it('should return error when multiple options are present', () => {
39
- const result = validateMutuallyExclusive({ a: 'value', b: 'value' }, ['a', 'b']);
40
- expect(result).toBe('Cannot use both a and b');
41
- });
42
-
43
- it('should return error when no options are present', () => {
44
- const result = validateMutuallyExclusive({}, ['a', 'b']);
45
- expect(result).toBe('Must specify one of: a, b');
46
- });
47
-
48
- it('should use custom error message', () => {
49
- const result = validateMutuallyExclusive(
50
- { a: 'value', b: 'value' },
51
- ['a', 'b'],
52
- 'Custom error'
53
- );
54
- expect(result).toBe('Custom error');
55
- });
56
- });
57
-
58
- describe('validateFormat', () => {
59
- it('should return null for valid format', () => {
60
- expect(validateFormat('123', /^\d+$/, 'error')).toBeNull();
61
- expect(validateFormat('abc', /^[a-z]+$/, 'error')).toBeNull();
62
- });
63
-
64
- it('should return error for invalid format', () => {
65
- expect(validateFormat('abc', /^\d+$/, 'Must be numbers')).toBe('Must be numbers');
66
- expect(validateFormat('123', /^[a-z]+$/, 'Must be letters')).toBe('Must be letters');
67
- });
68
- });
69
-
70
- describe('validateRange', () => {
71
- it('should return null for values within range', () => {
72
- expect(validateRange(5, 1, 10)).toBeNull();
73
- expect(validateRange(1, 1, 10)).toBeNull();
74
- expect(validateRange(10, 1, 10)).toBeNull();
75
- });
76
-
77
- it('should return error for values below minimum', () => {
78
- expect(validateRange(0, 1, 10)).toBe('Value must be at least 1');
79
- expect(validateRange(-5, 0, 10, 'Count')).toBe('Count must be at least 0');
80
- });
81
-
82
- it('should return error for values above maximum', () => {
83
- expect(validateRange(11, 1, 10)).toBe('Value must be at most 10');
84
- expect(validateRange(1001, 1, 1000, 'Limit')).toBe('Limit must be at most 1000');
85
- });
86
-
87
- it('should handle only min or only max', () => {
88
- expect(validateRange(100, 50)).toBeNull();
89
- expect(validateRange(100, undefined, 200)).toBeNull();
90
- expect(validateRange(30, 50)).toBe('Value must be at least 50');
91
- expect(validateRange(300, undefined, 200)).toBe('Value must be at most 200');
92
- });
93
- });
94
-
95
- describe('validateDateFormat', () => {
96
- it('should return null for valid dates', () => {
97
- expect(validateDateFormat('2024-01-01')).toBeNull();
98
- expect(validateDateFormat('2024-01-01 10:30:00')).toBeNull();
99
- expect(validateDateFormat('January 1, 2024')).toBeNull();
100
- });
101
-
102
- it('should return error for invalid dates', () => {
103
- expect(validateDateFormat('invalid')).toBe('Invalid date format');
104
- expect(validateDateFormat('2024-13-01')).toBe('Invalid date format');
105
- expect(validateDateFormat('')).toBe('Invalid date format');
106
- });
107
- });
108
-
109
- describe('formatValidators', () => {
110
- describe('threadTimestamp', () => {
111
- it('should validate correct timestamp format', () => {
112
- expect(formatValidators.threadTimestamp('1234567890.123456')).toBeNull();
113
- expect(formatValidators.threadTimestamp('9999999999.999999')).toBeNull();
114
- });
115
-
116
- it('should reject invalid timestamp format', () => {
117
- expect(formatValidators.threadTimestamp('123')).toBe('Invalid thread timestamp format');
118
- expect(formatValidators.threadTimestamp('1234567890')).toBe('Invalid thread timestamp format');
119
- expect(formatValidators.threadTimestamp('1234567890.12')).toBe('Invalid thread timestamp format');
120
- });
121
- });
122
-
123
- describe('channelId', () => {
124
- it('should validate correct channel ID format', () => {
125
- expect(formatValidators.channelId('C1234567890')).toBeNull();
126
- expect(formatValidators.channelId('D1234567890')).toBeNull();
127
- expect(formatValidators.channelId('G1234567890')).toBeNull();
128
- expect(formatValidators.channelId('C12345678901234')).toBeNull();
129
- });
130
-
131
- it('should reject invalid channel ID format', () => {
132
- expect(formatValidators.channelId('A1234567890')).toBe('Invalid channel ID format');
133
- expect(formatValidators.channelId('C123')).toBe('Invalid channel ID format');
134
- expect(formatValidators.channelId('general')).toBe('Invalid channel ID format');
135
- });
136
- });
137
-
138
- describe('outputFormat', () => {
139
- it('should validate correct output formats', () => {
140
- expect(formatValidators.outputFormat('table')).toBeNull();
141
- expect(formatValidators.outputFormat('simple')).toBeNull();
142
- expect(formatValidators.outputFormat('json')).toBeNull();
143
- expect(formatValidators.outputFormat('compact')).toBeNull();
144
- });
145
-
146
- it('should reject invalid output formats', () => {
147
- expect(formatValidators.outputFormat('xml')).toBe(
148
- 'Invalid format. Must be one of: table, simple, json, compact'
149
- );
150
- expect(formatValidators.outputFormat('csv')).toBe(
151
- 'Invalid format. Must be one of: table, simple, json, compact'
152
- );
153
- });
154
- });
155
- });
156
-
157
- describe('createValidationHook', () => {
158
- it('should call command.error when validation fails', () => {
159
- const mockCommand = {
160
- opts: vi.fn().mockReturnValue({ test: 'value' }),
161
- error: vi.fn(),
162
- } as unknown as Command;
163
-
164
- const validation = vi.fn().mockReturnValue('Validation error');
165
- const hook = createValidationHook([validation]);
166
-
167
- hook(mockCommand);
168
-
169
- expect(mockCommand.opts).toHaveBeenCalled();
170
- expect(validation).toHaveBeenCalledWith({ test: 'value' }, mockCommand);
171
- expect(mockCommand.error).toHaveBeenCalledWith('Error: Validation error');
172
- });
173
-
174
- it('should not call command.error when all validations pass', () => {
175
- const mockCommand = {
176
- opts: vi.fn().mockReturnValue({ test: 'value' }),
177
- error: vi.fn(),
178
- } as unknown as Command;
179
-
180
- const validation1 = vi.fn().mockReturnValue(null);
181
- const validation2 = vi.fn().mockReturnValue(null);
182
- const hook = createValidationHook([validation1, validation2]);
183
-
184
- hook(mockCommand);
185
-
186
- expect(validation1).toHaveBeenCalled();
187
- expect(validation2).toHaveBeenCalled();
188
- expect(mockCommand.error).not.toHaveBeenCalled();
189
- });
190
-
191
- it('should stop at first validation error', () => {
192
- const mockCommand = {
193
- opts: vi.fn().mockReturnValue({ test: 'value' }),
194
- error: vi.fn(),
195
- } as unknown as Command;
196
-
197
- const validation1 = vi.fn().mockReturnValue('First error');
198
- const validation2 = vi.fn().mockReturnValue('Second error');
199
- const hook = createValidationHook([validation1, validation2]);
200
-
201
- hook(mockCommand);
202
-
203
- expect(validation1).toHaveBeenCalled();
204
- expect(validation2).not.toHaveBeenCalled();
205
- expect(mockCommand.error).toHaveBeenCalledWith('Error: First error');
206
- });
207
- });
208
-
209
- describe('optionValidators', () => {
210
- describe('messageOrFile', () => {
211
- it('should pass when message is provided', () => {
212
- expect(optionValidators.messageOrFile({ message: 'text' })).toBeNull();
213
- });
214
-
215
- it('should pass when file is provided', () => {
216
- expect(optionValidators.messageOrFile({ file: 'path.txt' })).toBeNull();
217
- });
218
-
219
- it('should fail when neither is provided', () => {
220
- expect(optionValidators.messageOrFile({})).toBe(
221
- 'You must specify either --message or --file'
222
- );
223
- });
224
-
225
- it('should fail when both are provided', () => {
226
- expect(optionValidators.messageOrFile({ message: 'text', file: 'path.txt' })).toBe(
227
- 'Cannot use both --message and --file'
228
- );
229
- });
230
- });
231
-
232
- describe('threadTimestamp', () => {
233
- it('should pass when no thread is provided', () => {
234
- expect(optionValidators.threadTimestamp({})).toBeNull();
235
- });
236
-
237
- it('should validate thread format when provided', () => {
238
- expect(optionValidators.threadTimestamp({ thread: '1234567890.123456' })).toBeNull();
239
- expect(optionValidators.threadTimestamp({ thread: 'invalid' })).toBe(
240
- 'Invalid thread timestamp format'
241
- );
242
- });
243
- });
244
-
245
- describe('messageCount', () => {
246
- it('should pass when no number is provided', () => {
247
- expect(optionValidators.messageCount({})).toBeNull();
248
- });
249
-
250
- it('should validate number range when provided', () => {
251
- expect(optionValidators.messageCount({ number: '50' })).toBeNull();
252
- expect(optionValidators.messageCount({ number: '0' })).toBe(
253
- 'Message count must be at least 1'
254
- );
255
- expect(optionValidators.messageCount({ number: '1001' })).toBe(
256
- 'Message count must be at most 1000'
257
- );
258
- expect(optionValidators.messageCount({ number: 'abc' })).toBe(
259
- 'Message count must be a number'
260
- );
261
- });
262
- });
263
-
264
- describe('sinceDate', () => {
265
- it('should pass when no date is provided', () => {
266
- expect(optionValidators.sinceDate({})).toBeNull();
267
- });
268
-
269
- it('should validate date format when provided', () => {
270
- expect(optionValidators.sinceDate({ since: '2024-01-01' })).toBeNull();
271
- expect(optionValidators.sinceDate({ since: 'invalid' })).toBe('Invalid date format. Use YYYY-MM-DD HH:MM:SS');
272
- });
273
- });
274
- });
275
-
276
- describe('createOptionParser', () => {
277
- it('should parse value and return it when validation passes', () => {
278
- const parser = vi.fn().mockReturnValue(50);
279
- const validator = vi.fn().mockReturnValue(null);
280
- const optionParser = createOptionParser(parser, validator);
281
-
282
- const result = optionParser('50', 100);
283
-
284
- expect(parser).toHaveBeenCalledWith('50', 100);
285
- expect(validator).toHaveBeenCalledWith(50);
286
- expect(result).toBe(50);
287
- });
288
-
289
- it('should throw error when validation fails', () => {
290
- const parser = vi.fn().mockReturnValue(50);
291
- const validator = vi.fn().mockReturnValue('Validation failed');
292
- const optionParser = createOptionParser(parser, validator);
293
-
294
- expect(() => optionParser('50', 100)).toThrow('Validation failed');
295
- });
296
-
297
- it('should work without validator', () => {
298
- const parser = vi.fn().mockReturnValue(50);
299
- const optionParser = createOptionParser(parser);
300
-
301
- const result = optionParser('50', 100);
302
-
303
- expect(parser).toHaveBeenCalledWith('50', 100);
304
- expect(result).toBe(50);
305
- });
306
- });
307
- });
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "noImplicitAny": true,
13
- "resolveJsonModule": true,
14
- "declaration": true,
15
- "declarationMap": true,
16
- "sourceMap": true,
17
- "moduleResolution": "node",
18
- "allowSyntheticDefaultImports": true
19
- },
20
- "include": ["src/**/*"],
21
- "exclude": ["node_modules", "dist", "tests"]
22
- }
package/vitest.config.ts DELETED
@@ -1,27 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: 'node',
7
- coverage: {
8
- provider: 'v8',
9
- reporter: ['text', 'json', 'html'],
10
- exclude: [
11
- 'node_modules/',
12
- 'dist/',
13
- '**/*.d.ts',
14
- '**/*.config.*',
15
- '**/mockData/**',
16
- '**/tests/**',
17
- ],
18
- },
19
- include: ['tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
20
- testTimeout: 10000,
21
- },
22
- resolve: {
23
- alias: {
24
- '@': '/src',
25
- },
26
- },
27
- });