@urugus/slack-cli 0.2.6 → 0.2.8
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.
- package/dist/commands/history-display.d.ts +1 -1
- package/dist/commands/history-display.d.ts.map +1 -1
- package/dist/commands/history-display.js +8 -28
- package/dist/commands/history-display.js.map +1 -1
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +15 -8
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/send.d.ts.map +1 -1
- package/dist/commands/send.js +5 -18
- package/dist/commands/send.js.map +1 -1
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/utils/formatters/history-formatters.d.ts +8 -0
- package/dist/utils/formatters/history-formatters.d.ts.map +1 -0
- package/dist/utils/formatters/history-formatters.js +105 -0
- package/dist/utils/formatters/history-formatters.js.map +1 -0
- package/dist/utils/profile-config.d.ts.map +1 -1
- package/dist/utils/profile-config.js +2 -6
- package/dist/utils/profile-config.js.map +1 -1
- package/dist/utils/slack-operations/channel-operations.d.ts +9 -0
- package/dist/utils/slack-operations/channel-operations.d.ts.map +1 -1
- package/dist/utils/slack-operations/channel-operations.js +77 -50
- package/dist/utils/slack-operations/channel-operations.js.map +1 -1
- package/dist/utils/token-utils.d.ts +7 -0
- package/dist/utils/token-utils.d.ts.map +1 -0
- package/dist/utils/token-utils.js +18 -0
- package/dist/utils/token-utils.js.map +1 -0
- package/dist/utils/validators.d.ts +83 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +187 -0
- package/dist/utils/validators.js.map +1 -0
- package/package.json +1 -1
- package/src/commands/history-display.ts +9 -28
- package/src/commands/history.ts +25 -13
- package/src/commands/send.ts +8 -19
- package/src/types/commands.ts +1 -0
- package/src/utils/formatters/history-formatters.ts +123 -0
- package/src/utils/profile-config.ts +3 -15
- package/src/utils/slack-operations/channel-operations.ts +91 -54
- package/src/utils/token-utils.ts +17 -0
- package/src/utils/validators.ts +225 -0
- package/tests/commands/history.test.ts +115 -0
- package/tests/utils/option-parsers.test.ts +173 -0
- package/tests/utils/profile-config.test.ts +282 -0
- package/tests/utils/slack-operations/channel-operations-refactored.test.ts +179 -0
- package/tests/utils/token-utils.test.ts +33 -0
- package/tests/utils/validators.test.ts +307 -0
- package/src/utils/profile-config-refactored.ts +0 -161
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.maskToken = maskToken;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
/**
|
|
6
|
+
* Masks a token for display purposes, showing only first and last few characters
|
|
7
|
+
* @param token The token to mask
|
|
8
|
+
* @returns Masked token in format "xoxb-****-****-abcd"
|
|
9
|
+
*/
|
|
10
|
+
function maskToken(token) {
|
|
11
|
+
if (token.length <= constants_1.TOKEN_MIN_LENGTH) {
|
|
12
|
+
return '****';
|
|
13
|
+
}
|
|
14
|
+
const prefix = token.substring(0, constants_1.TOKEN_MASK_LENGTH);
|
|
15
|
+
const suffix = token.substring(token.length - constants_1.TOKEN_MASK_LENGTH);
|
|
16
|
+
return `${prefix}-****-****-${suffix}`;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=token-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-utils.js","sourceRoot":"","sources":["../../src/utils/token-utils.ts"],"names":[],"mappings":";;AAOA,8BASC;AAhBD,2CAAkE;AAElE;;;;GAIG;AACH,SAAgB,SAAS,CAAC,KAAa;IACrC,IAAI,KAAK,CAAC,MAAM,IAAI,4BAAgB,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,6BAAiB,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,6BAAiB,CAAC,CAAC;IAEjE,OAAO,GAAG,MAAM,cAAc,MAAM,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Common validation functions for CLI commands
|
|
4
|
+
*/
|
|
5
|
+
export interface ValidationRule<T = unknown> {
|
|
6
|
+
validate: (value: T) => boolean | string;
|
|
7
|
+
errorMessage?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ValidationOptions {
|
|
10
|
+
required?: boolean;
|
|
11
|
+
rules?: ValidationRule[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Validates that a value exists (not undefined, null, or empty string)
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateRequired(value: unknown, fieldName: string): string | null;
|
|
17
|
+
/**
|
|
18
|
+
* Validates mutually exclusive options
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateMutuallyExclusive(options: Record<string, unknown>, fields: string[], errorMessage?: string): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Validates string format using regex
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateFormat(value: string, pattern: RegExp, errorMessage: string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Validates numeric range
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateRange(value: number, min?: number, max?: number, fieldName?: string): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Validates date format
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateDateFormat(dateString: string): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Common format validators
|
|
35
|
+
*/
|
|
36
|
+
export declare const formatValidators: {
|
|
37
|
+
/**
|
|
38
|
+
* Validates Slack thread timestamp format (1234567890.123456)
|
|
39
|
+
*/
|
|
40
|
+
threadTimestamp: (value: string) => string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Validates Slack channel ID format (C1234567890, D1234567890, G1234567890)
|
|
43
|
+
*/
|
|
44
|
+
channelId: (value: string) => string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Validates output format options
|
|
47
|
+
*/
|
|
48
|
+
outputFormat: (value: string) => string | null;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Creates a preAction hook for command validation
|
|
52
|
+
*/
|
|
53
|
+
export declare function createValidationHook(validations: Array<(options: Record<string, unknown>, command: Command) => string | null>): (thisCommand: Command) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Common command option validators
|
|
56
|
+
*/
|
|
57
|
+
export declare const optionValidators: {
|
|
58
|
+
/**
|
|
59
|
+
* Validates message/file options for send command
|
|
60
|
+
*/
|
|
61
|
+
messageOrFile: (options: Record<string, unknown>) => string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Validates thread timestamp if provided
|
|
64
|
+
*/
|
|
65
|
+
threadTimestamp: (options: Record<string, unknown>) => string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Validates message count for history command
|
|
68
|
+
*/
|
|
69
|
+
messageCount: (options: Record<string, unknown>) => string | null;
|
|
70
|
+
/**
|
|
71
|
+
* Validates date format for history command
|
|
72
|
+
*/
|
|
73
|
+
sinceDate: (options: Record<string, unknown>) => string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Validates format option
|
|
76
|
+
*/
|
|
77
|
+
format: (options: Record<string, unknown>) => string | null;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Creates a validated option parser
|
|
81
|
+
*/
|
|
82
|
+
export declare function createOptionParser<T>(parser: (value: string | undefined, defaultValue: T) => T, validator?: (value: T) => string | null): (value: string | undefined, defaultValue: T) => T;
|
|
83
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;GAEG;AAEH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,MAAM,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKjF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,MAAM,EAAE,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CASf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,MAAM,GAAG,IAAI,CAKf;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,SAAU,GAClB,MAAM,GAAG,IAAI,CAQf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMpE;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;6BACsB,MAAM,KAAG,MAAM,GAAG,IAAI;IAK/C;;OAEG;uBACgB,MAAM,KAAG,MAAM,GAAG,IAAI;IAKzC;;OAEG;0BACmB,MAAM,KAAG,MAAM,GAAG,IAAI;CAO7C,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC,GACxF,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAYhC;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;6BACsB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAAI;IAUhE;;OAEG;+BACwB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAAI;IAOlE;;OAEG;4BACqB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAAI;IAW/D;;OAEG;yBACkB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAAI;IAU5D;;OAEG;sBACe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,IAAI;CAS1D,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,CAAC,KAAK,CAAC,EACzD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,GACtC,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,CAAC,KAAK,CAAC,CAWnD"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.optionValidators = exports.formatValidators = void 0;
|
|
4
|
+
exports.validateRequired = validateRequired;
|
|
5
|
+
exports.validateMutuallyExclusive = validateMutuallyExclusive;
|
|
6
|
+
exports.validateFormat = validateFormat;
|
|
7
|
+
exports.validateRange = validateRange;
|
|
8
|
+
exports.validateDateFormat = validateDateFormat;
|
|
9
|
+
exports.createValidationHook = createValidationHook;
|
|
10
|
+
exports.createOptionParser = createOptionParser;
|
|
11
|
+
const constants_1 = require("./constants");
|
|
12
|
+
/**
|
|
13
|
+
* Validates that a value exists (not undefined, null, or empty string)
|
|
14
|
+
*/
|
|
15
|
+
function validateRequired(value, fieldName) {
|
|
16
|
+
if (value === undefined || value === null || value === '') {
|
|
17
|
+
return `${fieldName} is required`;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validates mutually exclusive options
|
|
23
|
+
*/
|
|
24
|
+
function validateMutuallyExclusive(options, fields, errorMessage) {
|
|
25
|
+
const presentFields = fields.filter((field) => options[field] !== undefined);
|
|
26
|
+
if (presentFields.length > 1) {
|
|
27
|
+
return errorMessage || `Cannot use both ${presentFields.join(' and ')}`;
|
|
28
|
+
}
|
|
29
|
+
if (presentFields.length === 0) {
|
|
30
|
+
return errorMessage || `Must specify one of: ${fields.join(', ')}`;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validates string format using regex
|
|
36
|
+
*/
|
|
37
|
+
function validateFormat(value, pattern, errorMessage) {
|
|
38
|
+
if (!pattern.test(value)) {
|
|
39
|
+
return errorMessage;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validates numeric range
|
|
45
|
+
*/
|
|
46
|
+
function validateRange(value, min, max, fieldName = 'Value') {
|
|
47
|
+
if (min !== undefined && value < min) {
|
|
48
|
+
return `${fieldName} must be at least ${min}`;
|
|
49
|
+
}
|
|
50
|
+
if (max !== undefined && value > max) {
|
|
51
|
+
return `${fieldName} must be at most ${max}`;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Validates date format
|
|
57
|
+
*/
|
|
58
|
+
function validateDateFormat(dateString) {
|
|
59
|
+
const date = new Date(dateString);
|
|
60
|
+
if (isNaN(date.getTime())) {
|
|
61
|
+
return 'Invalid date format';
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Common format validators
|
|
67
|
+
*/
|
|
68
|
+
exports.formatValidators = {
|
|
69
|
+
/**
|
|
70
|
+
* Validates Slack thread timestamp format (1234567890.123456)
|
|
71
|
+
*/
|
|
72
|
+
threadTimestamp: (value) => {
|
|
73
|
+
const pattern = /^\d{10}\.\d{6}$/;
|
|
74
|
+
return validateFormat(value, pattern, constants_1.ERROR_MESSAGES.INVALID_THREAD_TIMESTAMP);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* Validates Slack channel ID format (C1234567890, D1234567890, G1234567890)
|
|
78
|
+
*/
|
|
79
|
+
channelId: (value) => {
|
|
80
|
+
const pattern = /^[CDG][A-Z0-9]{10,}$/;
|
|
81
|
+
return validateFormat(value, pattern, 'Invalid channel ID format');
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Validates output format options
|
|
85
|
+
*/
|
|
86
|
+
outputFormat: (value) => {
|
|
87
|
+
const validFormats = ['table', 'simple', 'json', 'compact'];
|
|
88
|
+
if (!validFormats.includes(value)) {
|
|
89
|
+
return `Invalid format. Must be one of: ${validFormats.join(', ')}`;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Creates a preAction hook for command validation
|
|
96
|
+
*/
|
|
97
|
+
function createValidationHook(validations) {
|
|
98
|
+
return (thisCommand) => {
|
|
99
|
+
const options = thisCommand.opts();
|
|
100
|
+
for (const validation of validations) {
|
|
101
|
+
const error = validation(options, thisCommand);
|
|
102
|
+
if (error) {
|
|
103
|
+
thisCommand.error(`Error: ${error}`);
|
|
104
|
+
break; // Stop processing after first error
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Common command option validators
|
|
111
|
+
*/
|
|
112
|
+
exports.optionValidators = {
|
|
113
|
+
/**
|
|
114
|
+
* Validates message/file options for send command
|
|
115
|
+
*/
|
|
116
|
+
messageOrFile: (options) => {
|
|
117
|
+
if (!options.message && !options.file) {
|
|
118
|
+
return constants_1.ERROR_MESSAGES.NO_MESSAGE_OR_FILE;
|
|
119
|
+
}
|
|
120
|
+
if (options.message && options.file) {
|
|
121
|
+
return constants_1.ERROR_MESSAGES.BOTH_MESSAGE_AND_FILE;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Validates thread timestamp if provided
|
|
127
|
+
*/
|
|
128
|
+
threadTimestamp: (options) => {
|
|
129
|
+
if (options.thread) {
|
|
130
|
+
return exports.formatValidators.threadTimestamp(options.thread);
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* Validates message count for history command
|
|
136
|
+
*/
|
|
137
|
+
messageCount: (options) => {
|
|
138
|
+
if (options.number) {
|
|
139
|
+
const count = parseInt(options.number, 10);
|
|
140
|
+
if (isNaN(count)) {
|
|
141
|
+
return 'Message count must be a number';
|
|
142
|
+
}
|
|
143
|
+
return validateRange(count, 1, 1000, 'Message count');
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
},
|
|
147
|
+
/**
|
|
148
|
+
* Validates date format for history command
|
|
149
|
+
*/
|
|
150
|
+
sinceDate: (options) => {
|
|
151
|
+
if (options.since) {
|
|
152
|
+
const error = validateDateFormat(options.since);
|
|
153
|
+
if (error) {
|
|
154
|
+
return 'Invalid date format. Use YYYY-MM-DD HH:MM:SS';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* Validates format option
|
|
161
|
+
*/
|
|
162
|
+
format: (options) => {
|
|
163
|
+
if (options.format) {
|
|
164
|
+
const validFormats = ['table', 'simple', 'json'];
|
|
165
|
+
if (!validFormats.includes(options.format)) {
|
|
166
|
+
return `Invalid format '${options.format}'. Must be one of: ${validFormats.join(', ')}`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Creates a validated option parser
|
|
174
|
+
*/
|
|
175
|
+
function createOptionParser(parser, validator) {
|
|
176
|
+
return (value, defaultValue) => {
|
|
177
|
+
const parsed = parser(value, defaultValue);
|
|
178
|
+
if (validator) {
|
|
179
|
+
const error = validator(parsed);
|
|
180
|
+
if (error) {
|
|
181
|
+
throw new Error(error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return parsed;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,38 +1,19 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import { Message } from '../utils/slack-api-client';
|
|
3
|
-
import {
|
|
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()
|
|
20
|
-
const timestamp = formatSlackTimestamp(message.ts);
|
|
21
|
-
let author = 'Unknown';
|
|
11
|
+
const orderedMessages = [...messages].reverse();
|
|
22
12
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
}
|
package/src/commands/history.ts
CHANGED
|
@@ -4,11 +4,10 @@ import { wrapCommand } from '../utils/command-wrapper';
|
|
|
4
4
|
import { createSlackClient } from '../utils/client-factory';
|
|
5
5
|
import { HistoryOptions } from '../types/commands';
|
|
6
6
|
import { API_LIMITS } from '../utils/constants';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from './history-validators';
|
|
7
|
+
import { parseCount, parseProfile } from '../utils/option-parsers';
|
|
8
|
+
import { createValidationHook, optionValidators } from '../utils/validators';
|
|
9
|
+
import { parseFormat } from '../utils/option-parsers';
|
|
10
|
+
import { prepareSinceTimestamp } from './history-validators';
|
|
12
11
|
import { displayHistoryResults } from './history-display';
|
|
13
12
|
|
|
14
13
|
export function setupHistoryCommand(): Command {
|
|
@@ -21,18 +20,30 @@ export function setupHistoryCommand(): Command {
|
|
|
21
20
|
API_LIMITS.DEFAULT_MESSAGE_COUNT.toString()
|
|
22
21
|
)
|
|
23
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')
|
|
24
24
|
.option('--profile <profile>', 'Use specific workspace profile')
|
|
25
|
-
.hook(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
.hook(
|
|
26
|
+
'preAction',
|
|
27
|
+
createValidationHook([
|
|
28
|
+
optionValidators.messageCount,
|
|
29
|
+
optionValidators.sinceDate,
|
|
30
|
+
optionValidators.format,
|
|
31
|
+
])
|
|
32
|
+
)
|
|
30
33
|
.action(
|
|
31
34
|
wrapCommand(async (options: HistoryOptions) => {
|
|
32
|
-
const
|
|
35
|
+
const profile = parseProfile(options.profile);
|
|
36
|
+
const client = await createSlackClient(profile);
|
|
37
|
+
|
|
38
|
+
const limit = parseCount(
|
|
39
|
+
options.number,
|
|
40
|
+
API_LIMITS.DEFAULT_MESSAGE_COUNT,
|
|
41
|
+
API_LIMITS.MIN_MESSAGE_COUNT,
|
|
42
|
+
API_LIMITS.MAX_MESSAGE_COUNT
|
|
43
|
+
);
|
|
33
44
|
|
|
34
45
|
const historyOptions: ApiHistoryOptions = {
|
|
35
|
-
limit
|
|
46
|
+
limit,
|
|
36
47
|
};
|
|
37
48
|
|
|
38
49
|
const oldest = prepareSinceTimestamp(options.since);
|
|
@@ -41,7 +52,8 @@ export function setupHistoryCommand(): Command {
|
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
const { messages, users } = await client.getHistory(options.channel, historyOptions);
|
|
44
|
-
|
|
55
|
+
const format = parseFormat(options.format);
|
|
56
|
+
displayHistoryResults(messages, users, options.channel, format);
|
|
45
57
|
})
|
|
46
58
|
);
|
|
47
59
|
|
package/src/commands/send.ts
CHANGED
|
@@ -6,14 +6,10 @@ import { createSlackClient } from '../utils/client-factory';
|
|
|
6
6
|
import { FileError } from '../utils/errors';
|
|
7
7
|
import { SendOptions } from '../types/commands';
|
|
8
8
|
import { extractErrorMessage } from '../utils/error-utils';
|
|
9
|
+
import { parseProfile } from '../utils/option-parsers';
|
|
10
|
+
import { createValidationHook, optionValidators } from '../utils/validators';
|
|
9
11
|
import * as fs from 'fs/promises';
|
|
10
12
|
|
|
11
|
-
function isValidThreadTimestamp(timestamp: string): boolean {
|
|
12
|
-
// Slack timestamp format: 1234567890.123456
|
|
13
|
-
const timestampRegex = /^\d{10}\.\d{6}$/;
|
|
14
|
-
return timestampRegex.test(timestamp);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
13
|
export function setupSendCommand(): Command {
|
|
18
14
|
const sendCommand = new Command('send')
|
|
19
15
|
.description('Send a message to a Slack channel')
|
|
@@ -22,18 +18,10 @@ export function setupSendCommand(): Command {
|
|
|
22
18
|
.option('-f, --file <file>', 'File containing message content')
|
|
23
19
|
.option('-t, --thread <thread>', 'Thread timestamp to reply to')
|
|
24
20
|
.option('--profile <profile>', 'Use specific workspace profile')
|
|
25
|
-
.hook(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
if (options.message && options.file) {
|
|
31
|
-
thisCommand.error(`Error: ${ERROR_MESSAGES.BOTH_MESSAGE_AND_FILE}`);
|
|
32
|
-
}
|
|
33
|
-
if (options.thread && !isValidThreadTimestamp(options.thread)) {
|
|
34
|
-
thisCommand.error(`Error: ${ERROR_MESSAGES.INVALID_THREAD_TIMESTAMP}`);
|
|
35
|
-
}
|
|
36
|
-
})
|
|
21
|
+
.hook(
|
|
22
|
+
'preAction',
|
|
23
|
+
createValidationHook([optionValidators.messageOrFile, optionValidators.threadTimestamp])
|
|
24
|
+
)
|
|
37
25
|
.action(
|
|
38
26
|
wrapCommand(async (options: SendOptions) => {
|
|
39
27
|
// Get message content
|
|
@@ -51,7 +39,8 @@ export function setupSendCommand(): Command {
|
|
|
51
39
|
}
|
|
52
40
|
|
|
53
41
|
// Send message
|
|
54
|
-
const
|
|
42
|
+
const profile = parseProfile(options.profile);
|
|
43
|
+
const client = await createSlackClient(profile);
|
|
55
44
|
await client.sendMessage(options.channel, messageContent, options.thread);
|
|
56
45
|
|
|
57
46
|
console.log(chalk.green(`✓ ${SUCCESS_MESSAGES.MESSAGE_SENT(options.channel)}`));
|
package/src/types/commands.ts
CHANGED
|
@@ -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
|
+
}
|
|
@@ -2,13 +2,8 @@ import * as fs from 'fs/promises';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import type { Config, ConfigOptions, ConfigStore, Profile } from '../types/config';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
TOKEN_MIN_LENGTH,
|
|
8
|
-
DEFAULT_PROFILE_NAME,
|
|
9
|
-
ERROR_MESSAGES,
|
|
10
|
-
FILE_PERMISSIONS,
|
|
11
|
-
} from './constants';
|
|
5
|
+
import { DEFAULT_PROFILE_NAME, ERROR_MESSAGES, FILE_PERMISSIONS } from './constants';
|
|
6
|
+
import { maskToken } from './token-utils';
|
|
12
7
|
|
|
13
8
|
export class ProfileConfigManager {
|
|
14
9
|
private configPath: string;
|
|
@@ -98,14 +93,7 @@ export class ProfileConfigManager {
|
|
|
98
93
|
}
|
|
99
94
|
|
|
100
95
|
maskToken(token: string): string {
|
|
101
|
-
|
|
102
|
-
return '****';
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const prefix = token.substring(0, TOKEN_MASK_LENGTH);
|
|
106
|
-
const suffix = token.substring(token.length - TOKEN_MASK_LENGTH);
|
|
107
|
-
|
|
108
|
-
return `${prefix}-****-****-${suffix}`;
|
|
96
|
+
return maskToken(token);
|
|
109
97
|
}
|
|
110
98
|
|
|
111
99
|
private async getConfigStore(): Promise<ConfigStore> {
|