-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmsg.ts
More file actions
135 lines (113 loc) · 4.37 KB
/
msg.ts
File metadata and controls
135 lines (113 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { Command } from 'commander'
import { getTwistClient } from '../lib/api.js'
import { formatRelativeDate } from '../lib/dates.js'
import { openEditor, readStdin } from '../lib/input.js'
import { renderMarkdown } from '../lib/markdown.js'
import type { MutationOptions, ViewOptions } from '../lib/options.js'
import { colors, formatJson, formatNdjson } from '../lib/output.js'
import { resolveMessageId } from '../lib/refs.js'
type UpdateOptions = MutationOptions
type DeleteOptions = MutationOptions
async function viewMessage(ref: string, options: ViewOptions): Promise<void> {
const messageId = resolveMessageId(ref)
const client = await getTwistClient()
const message = await client.conversationMessages.getMessage(messageId)
const userResponse = await client.workspaceUsers.getUserById(
{ workspaceId: message.workspaceId, userId: message.creator },
{ batch: false },
)
const creatorName = userResponse.name
if (options.json) {
const output = { ...message, creatorName }
console.log(formatJson(output, options.full ? undefined : 'message', options.full))
return
}
if (options.ndjson) {
const output = { ...message, creatorName }
console.log(formatNdjson([output], options.full ? undefined : 'message', options.full))
return
}
const author = colors.author(creatorName)
const time = colors.timestamp(formatRelativeDate(message.posted))
console.log(`${author} ${time} ${colors.timestamp(`id:${message.id}`)}`)
console.log(options.raw ? message.content : renderMarkdown(message.content))
console.log('')
}
async function updateMessage(
ref: string,
content: string | undefined,
options: UpdateOptions,
): Promise<void> {
const messageId = resolveMessageId(ref)
let newContent = await readStdin()
if (!newContent && content) {
newContent = content
}
if (!newContent) {
newContent = await openEditor()
}
if (!newContent || newContent.trim() === '') {
console.error('No content provided.')
process.exit(1)
}
if (options.dryRun) {
console.log(`Dry run: would update message ${messageId}`)
console.log('')
console.log(newContent)
return
}
const client = await getTwistClient()
const message = await client.conversationMessages.updateMessage({
id: messageId,
content: newContent,
})
if (options.json) {
console.log(formatJson(message, 'message', options.full))
return
}
console.log(`Message updated: ${message.url}`)
}
async function deleteMessage(ref: string, options: DeleteOptions): Promise<void> {
const messageId = resolveMessageId(ref)
if (options.dryRun) {
console.log(`Dry run: would delete message ${messageId}`)
return
}
const client = await getTwistClient()
await client.conversationMessages.deleteMessage(messageId)
if (options.json) {
console.log(formatJson({ id: messageId, deleted: true }))
return
}
console.log(`Message ${messageId} deleted.`)
}
export function registerMsgCommand(program: Command): void {
const msg = program
.command('msg')
.alias('message')
.description('Conversation message operations (view, update, delete)')
msg.command('view [message-ref]', { isDefault: true })
.description('View a single conversation message')
.option('--raw', 'Show raw markdown instead of rendered')
.option('--json', 'Output as JSON')
.option('--ndjson', 'Output as newline-delimited JSON')
.option('--full', 'Include all fields in JSON output')
.action((ref, options) => {
if (!ref) {
msg.help()
return
}
return viewMessage(ref, options)
})
msg.command('update <message-ref> [content]')
.description('Edit a conversation message')
.option('--dry-run', 'Show what would be updated without updating')
.option('--json', 'Output updated message as JSON')
.option('--full', 'Include all fields in JSON output')
.action(updateMessage)
msg.command('delete <message-ref>')
.description('Delete a conversation message')
.option('--dry-run', 'Show what would happen without executing')
.option('--json', 'Output result as JSON')
.action(deleteMessage)
}