@rocket.chat/apps-engine
Version:
The engine code for the Rocket.Chat Apps which manages, runs, translates, coordinates and all of that.
217 lines (173 loc) • 6.83 kB
text/typescript
import { v1 as uuid } from 'uuid';
import type {
BlockType as _BlockType,
IActionsBlock,
IBlock,
IConditionalBlock,
IConditionalBlockFilters,
IContextBlock,
IImageBlock,
IInputBlock,
ISectionBlock,
} from '@rocket.chat/apps-engine/definition/uikit/blocks/Blocks.ts';
import type {
BlockElementType as _BlockElementType,
IBlockElement,
IButtonElement,
IImageElement,
IInputElement,
IInteractiveElement,
IMultiStaticSelectElement,
IOverflowMenuElement,
IPlainTextInputElement,
ISelectElement,
IStaticSelectElement,
} from '@rocket.chat/apps-engine/definition/uikit/blocks/Elements.ts';
import type { ITextObject, TextObjectType as _TextObjectType } from '@rocket.chat/apps-engine/definition/uikit/blocks/Objects.ts';
import { AppObjectRegistry } from '../../../AppObjectRegistry.ts';
import { require } from '../../../lib/require.ts';
const { BlockType } = require('@rocket.chat/apps-engine/definition/uikit/blocks/Blocks.js') as { BlockType: typeof _BlockType };
const { BlockElementType } = require('@rocket.chat/apps-engine/definition/uikit/blocks/Elements.js') as { BlockElementType: typeof _BlockElementType };
const { TextObjectType } = require('@rocket.chat/apps-engine/definition/uikit/blocks/Objects.js') as { TextObjectType: typeof _TextObjectType };
type BlockFunctionParameter<T extends IBlock> = Omit<T, 'type'>;
type ElementFunctionParameter<T extends IBlockElement> = T extends IInteractiveElement
? Omit<T, 'type' | 'actionId'> | Partial<Pick<T, 'actionId'>>
: Omit<T, 'type'>;
type SectionBlockParam = BlockFunctionParameter<ISectionBlock>;
type ImageBlockParam = BlockFunctionParameter<IImageBlock>;
type ActionsBlockParam = BlockFunctionParameter<IActionsBlock>;
type ContextBlockParam = BlockFunctionParameter<IContextBlock>;
type InputBlockParam = BlockFunctionParameter<IInputBlock>;
type ButtonElementParam = ElementFunctionParameter<IButtonElement>;
type ImageElementParam = ElementFunctionParameter<IImageElement>;
type OverflowMenuElementParam = ElementFunctionParameter<IOverflowMenuElement>;
type PlainTextInputElementParam = ElementFunctionParameter<IPlainTextInputElement>;
type StaticSelectElementParam = ElementFunctionParameter<IStaticSelectElement>;
type MultiStaticSelectElementParam = ElementFunctionParameter<IMultiStaticSelectElement>;
/**
* @deprecated please prefer the rocket.chat/ui-kit components
*/
export class BlockBuilder {
private readonly blocks: Array<IBlock>;
private readonly appId: string;
constructor() {
this.blocks = [];
this.appId = String(AppObjectRegistry.get('id'));
}
public addSectionBlock(block: SectionBlockParam): BlockBuilder {
this.addBlock({ type: BlockType.SECTION, ...block } as ISectionBlock);
return this;
}
public addImageBlock(block: ImageBlockParam): BlockBuilder {
this.addBlock({ type: BlockType.IMAGE, ...block } as IImageBlock);
return this;
}
public addDividerBlock(): BlockBuilder {
this.addBlock({ type: BlockType.DIVIDER });
return this;
}
public addActionsBlock(block: ActionsBlockParam): BlockBuilder {
this.addBlock({ type: BlockType.ACTIONS, ...block } as IActionsBlock);
return this;
}
public addContextBlock(block: ContextBlockParam): BlockBuilder {
this.addBlock({ type: BlockType.CONTEXT, ...block } as IContextBlock);
return this;
}
public addInputBlock(block: InputBlockParam): BlockBuilder {
this.addBlock({ type: BlockType.INPUT, ...block } as IInputBlock);
return this;
}
public addConditionalBlock(innerBlocks: BlockBuilder | Array<IBlock>, condition?: IConditionalBlockFilters): BlockBuilder {
const render = innerBlocks instanceof BlockBuilder ? innerBlocks.getBlocks() : innerBlocks;
this.addBlock({
type: BlockType.CONDITIONAL,
render,
when: condition,
} as IConditionalBlock);
return this;
}
public getBlocks() {
return this.blocks;
}
public newPlainTextObject(text: string, emoji = false): ITextObject {
return {
type: TextObjectType.PLAINTEXT,
text,
emoji,
};
}
public newMarkdownTextObject(text: string): ITextObject {
return {
type: TextObjectType.MARKDOWN,
text,
};
}
public newButtonElement(info: ButtonElementParam): IButtonElement {
return this.newInteractiveElement({
type: BlockElementType.BUTTON,
...info,
} as IButtonElement);
}
public newImageElement(info: ImageElementParam): IImageElement {
return {
type: BlockElementType.IMAGE,
...info,
};
}
public newOverflowMenuElement(info: OverflowMenuElementParam): IOverflowMenuElement {
return this.newInteractiveElement({
type: BlockElementType.OVERFLOW_MENU,
...info,
} as IOverflowMenuElement);
}
public newPlainTextInputElement(info: PlainTextInputElementParam): IPlainTextInputElement {
return this.newInputElement({
type: BlockElementType.PLAIN_TEXT_INPUT,
...info,
} as IPlainTextInputElement);
}
public newStaticSelectElement(info: StaticSelectElementParam): IStaticSelectElement {
return this.newSelectElement({
type: BlockElementType.STATIC_SELECT,
...info,
} as IStaticSelectElement);
}
public newMultiStaticElement(info: MultiStaticSelectElementParam): IMultiStaticSelectElement {
return this.newSelectElement({
type: BlockElementType.MULTI_STATIC_SELECT,
...info,
} as IMultiStaticSelectElement);
}
private newInteractiveElement<T extends IInteractiveElement>(element: T): T {
if (!element.actionId) {
element.actionId = this.generateActionId();
}
return element;
}
private newInputElement<T extends IInputElement>(element: T): T {
if (!element.actionId) {
element.actionId = this.generateActionId();
}
return element;
}
private newSelectElement<T extends ISelectElement>(element: T): T {
if (!element.actionId) {
element.actionId = this.generateActionId();
}
return element;
}
private addBlock(block: IBlock): void {
if (!block.blockId) {
block.blockId = this.generateBlockId();
}
block.appId = this.appId;
this.blocks.push(block);
}
private generateBlockId(): string {
return uuid();
}
private generateActionId(): string {
return uuid();
}
}