UNPKG

reblock

Version:

Build interactive Slack surfaces with React

104 lines (100 loc) 3.06 kB
import { Temporal } from 'temporal-polyfill' import type { Instance } from './renderer' // magic Omit that works with union types, thanks o1 // eslint-disable-next-line @typescript-eslint/no-explicit-any export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never export function assertNoChildren(element: Instance) { if (element.children.length > 0) { throw new Error( `Element ${element.element} should not have children: ${element.children}` ) } } export function getTextChild(element: Instance): string { 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: unknown, assert: true): string export function getTextProperty( value: unknown, assert?: false ): string | undefined export function getTextProperty( value: unknown, assert = false ): string | undefined { 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: number | string | Temporal.Instant | Date ): number export function dateToSlackTimestamp(input: unknown): number | undefined export function dateToSlackTimestamp(input: unknown): number | undefined { 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: string | Temporal.PlainDate | Date ): string export function plainDateToString(input: unknown): string | undefined export function plainDateToString(input: unknown): string | undefined { 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: Instance) { 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' as const, ...source, alt_text: getTextProperty(jsx.props.alt, true), title: typeof jsx.props.title === 'string' ? { type: 'plain_text' as const, text: jsx.props.title } : undefined, } }