@microsoft/botbuilder-m365
Version:
M365 extensions for Microsoft BotBuilder, Alpha release.
104 lines (86 loc) • 3.48 kB
text/typescript
/**
* @module botbuilder-m365
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { TurnContext } from 'botbuilder';
import { DefaultTempState, DefaultTurnState } from '../DefaultTurnStateManager';
import { PromptManager } from '../Prompts';
import { TurnState } from '../TurnState';
import { Block, BlockTypes } from './Block';
import { VarBlock } from './VarBlock';
/**
* @private
*/
export class CodeBlock extends Block {
private _validated = false;
constructor(content: string) {
super();
this.content = content;
}
public get type(): BlockTypes {
return BlockTypes.Code;
}
public isValid(): { valid: boolean; error?: string } {
let valid = true;
let errorMessage: string | undefined;
const partsToValidate = this.content.split(/[ \t\r\n]+/).filter((x) => x.trim() !== '');
for (let index = 0; index < partsToValidate.length; index++) {
// TODO:
// eslint-disable-next-line security/detect-object-injection
const part = partsToValidate[index];
if (index === 0) {
// There is only a function name
if (VarBlock.hasVarPrefix(part)) {
errorMessage = `Variables cannot be used as function names [\`${part}\`]`;
valid = false;
}
if (!/^[a-zA-Z0-9_.]*$/.test(part)) {
errorMessage = `The function name \`${part}\` contains invalid characters`;
valid = false;
}
} else {
// The function has parameters
if (!VarBlock.hasVarPrefix(part)) {
errorMessage = `\`${part}\` is not a valid function parameter: parameters must be variables.`;
valid = false;
}
if (part.length < 2) {
errorMessage = `\`${part}\` is not a valid variable.`;
valid = false;
}
if (!VarBlock.isValidVarName(part.substring(1))) {
errorMessage = `\`${part}\` variable name is not valid.`;
valid = false;
}
}
}
this._validated = true;
return { valid, error: errorMessage };
}
public render(context: TurnContext, state: TurnState): string {
throw new Error('Code blocks rendering requires IFunctionRegistryReader. Incorrect method call.');
}
public async renderCode(
context: TurnContext,
state: TurnState,
promptManager: PromptManager<TurnState>
): Promise<string> {
if (!this._validated) {
const { valid, error } = this.isValid();
if (!valid) {
throw new Error(error);
}
}
const parts = this.content.split(/[ \t\r\n]+/).filter((x) => x.trim() !== '');
const functionName = parts[0];
const result = await promptManager.invokeFunction(context, state, functionName);
const output = VarBlock.formatValue(result);
// Save output to $temp.output and then return
const temp = (state as DefaultTurnState)?.temp?.value ?? ({} as DefaultTempState);
temp.output = output;
return output;
}
}