reblock
Version:
Build interactive Slack surfaces with React
79 lines (78 loc) • 2.16 kB
JavaScript
import { Temporal } from 'temporal-polyfill'
export function assertNoChildren(element) {
if (element.children.length > 0) {
throw new Error(
`Element ${element.element} should not have children: ${element.children}`
)
}
}
export function getTextChild(element) {
const children = element.children
if (children.find((child) => child.type !== 'text')) {
throw new Error('Only text children allowed')
}
const string = children.map((child) => child.text).join('')
return string
}
export function getTextProperty(value, assert = false) {
if (typeof value === 'string') {
return value
}
if (assert) {
throw new Error('Expected string')
}
if (value === undefined || value === null) {
return undefined
}
throw new Error('Expected string or undefined')
}
export function dateToSlackTimestamp(input) {
if (typeof input === 'number') {
return input
}
if (typeof input === 'string') {
return Temporal.Instant.from(input).epochSeconds
}
if (input instanceof Date) {
return input.getTime() / 1000
}
if (input instanceof Temporal.Instant) {
return input.epochSeconds
}
return undefined
}
export function plainDateToString(input) {
if (typeof input === 'string') {
return input
}
if (input instanceof Date) {
return Temporal.Instant.fromEpochMilliseconds(input.getTime())
.toZonedDateTimeISO('UTC')
.toPlainDate()
.toString()
}
if (input instanceof Temporal.PlainDate) {
return input.toString()
}
return undefined
}
export function jsxToImageObject(jsx) {
const sourceString = String(jsx.props.src)
if (!sourceString) {
throw new Error('Image must have a source')
}
const source = !sourceString.startsWith('http')
? { slack_file: { id: sourceString } }
: sourceString.startsWith('https://files.slack.com')
? { slack_file: { url: sourceString } }
: { image_url: sourceString }
return {
type: 'image',
...source,
alt_text: getTextProperty(jsx.props.alt, true),
title:
typeof jsx.props.title === 'string'
? { type: 'plain_text', text: jsx.props.title }
: undefined,
}
}