botbuilder-dialogs-adaptive
Version:
Rule system for the Microsoft BotBuilder dialog system.
345 lines • 14.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpRequest = exports.Result = exports.HttpMethod = exports.ResponsesTypes = void 0;
/**
* @module botbuilder-dialogs-adaptive
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
const botbuilder_core_1 = require("botbuilder-core");
const node_fetch_1 = __importStar(require("node-fetch"));
const jsonExtensions_1 = require("../jsonExtensions");
const adaptive_expressions_1 = require("adaptive-expressions");
const botbuilder_dialogs_1 = require("botbuilder-dialogs");
/**
* [HeadersInput](xref:botbuilder-dialogs-adaptive.HeadersInput) or [HeadersOutput](xref:botbuilder-dialogs-adaptive.HeadersOutput) to [HttpHeader](xref:botbuilder-dialogs-adaptive.HttpHeader) converter.
*/
class HttpHeadersConverter {
/**
* Converts a [HeadersInput](xref:botbuilder-dialogs-adaptive.HeadersInput) or [HeadersOutput](xref:botbuilder-dialogs-adaptive.HeadersOutput) to [HttpHeader](xref:botbuilder-dialogs-adaptive.HttpHeader).
*
* @param value [HeadersInput](xref:botbuilder-dialogs-adaptive.HeadersInput) or [HeadersOutput](xref:botbuilder-dialogs-adaptive.HeadersOutput) to convert.
* @returns The [HttpHeader](xref:botbuilder-dialogs-adaptive.HttpHeader).
*/
convert(value) {
return Object.entries(value).reduce((headers, [key, value]) => {
return Object.assign(Object.assign({}, headers), { [key]: value instanceof adaptive_expressions_1.StringExpression ? value : new adaptive_expressions_1.StringExpression(value) });
}, {});
}
}
var ResponsesTypes;
(function (ResponsesTypes) {
/**
* No response expected
*/
ResponsesTypes[ResponsesTypes["None"] = 0] = "None";
/**
* Plain JSON response
*/
ResponsesTypes[ResponsesTypes["Json"] = 1] = "Json";
/**
* JSON Activity object to send to the user
*/
ResponsesTypes[ResponsesTypes["Activity"] = 2] = "Activity";
/**
* Json Array of activity objects to send to the user
*/
ResponsesTypes[ResponsesTypes["Activities"] = 3] = "Activities";
/**
* Binary data parsing from http response content
*/
ResponsesTypes[ResponsesTypes["Binary"] = 4] = "Binary";
})(ResponsesTypes = exports.ResponsesTypes || (exports.ResponsesTypes = {}));
var HttpMethod;
(function (HttpMethod) {
/**
* Http GET
*/
HttpMethod["GET"] = "GET";
/**
* Http POST
*/
HttpMethod["POST"] = "POST";
/**
* Http PATCH
*/
HttpMethod["PATCH"] = "PATCH";
/**
* Http PUT
*/
HttpMethod["PUT"] = "PUT";
/**
* Http DELETE
*/
HttpMethod["DELETE"] = "DELETE";
/**
* Http HEAD
*/
HttpMethod["HEAD"] = "HEAD";
})(HttpMethod = exports.HttpMethod || (exports.HttpMethod = {}));
/**
* Result data of HTTP operation.
*/
class Result {
/**
* Initialize a new instance of Result class.
*
* @param headers Response headers.
*/
constructor(headers) {
/**
* The headers from the response to HTTP operation.
*/
this.headers = {};
if (headers) {
headers.forEach((value, name) => {
this.headers[name] = value;
});
}
}
}
exports.Result = Result;
/**
* Action for performing an `HttpRequest`.
*/
class HttpRequest extends botbuilder_dialogs_1.Dialog {
/**
* Initializes a new instance of the [HttpRequest](xref:botbuilder-dialogs-adaptive.HttpRequest) class.
*
* @param method Optional. The [HttpMethod](xref:botbuilder-dialogs-adaptive.HttpMethod), for example POST, GET, DELETE or PUT.
* @param url Optional. URL for the request.
* @param headers Optional. The headers of the request.
* @param body Optional. The raw body of the request.
*/
constructor(method, url, headers, body) {
super();
/**
* Http Method
*/
this.method = HttpMethod.GET;
/**
* Content type of request body
*/
this.contentType = new adaptive_expressions_1.StringExpression('application/json');
/**
* Http Headers
*/
this.headers = {};
/**
* The response type of the response
*/
this.responseType = new adaptive_expressions_1.EnumExpression(ResponsesTypes.Json);
/**
* Gets or sets the property expression to store the HTTP response in.
*/
this.resultProperty = new adaptive_expressions_1.StringExpression('turn.results');
this.method = method || HttpMethod.GET;
this.url = new adaptive_expressions_1.StringExpression(url);
if (headers) {
this.headers = {};
for (const key in headers) {
this.headers[key] = new adaptive_expressions_1.StringExpression(headers[key]);
}
}
this.body = new adaptive_expressions_1.ValueExpression(body);
}
/**
* @param property The key of the conditional selector configuration.
* @returns The converter for the selector configuration.
*/
getConverter(property) {
switch (property) {
case 'contentType':
return new adaptive_expressions_1.StringExpressionConverter();
case 'url':
return new adaptive_expressions_1.StringExpressionConverter();
case 'headers':
return new HttpHeadersConverter();
case 'body':
return new adaptive_expressions_1.ValueExpressionConverter();
case 'responseType':
return new adaptive_expressions_1.EnumExpressionConverter(ResponsesTypes);
case 'resultProperty':
return new adaptive_expressions_1.StringExpressionConverter();
case 'disabled':
return new adaptive_expressions_1.BoolExpressionConverter();
default:
return super.getConverter(property);
}
}
/**
* Starts a new [Dialog](xref:botbuilder-dialogs.Dialog) and pushes it onto the dialog stack.
*
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @param _options Optional. Initial information to pass to the dialog.
* @returns A `Promise` representing the asynchronous operation.
*/
beginDialog(dc, _options) {
return __awaiter(this, void 0, void 0, function* () {
if (this.disabled && this.disabled.getValue(dc.state)) {
return yield dc.endDialog();
}
const instanceUrl = this.url.getValue(dc.state);
const instanceMethod = this.method.toString();
const instanceHeaders = {};
for (let key in this.headers) {
if (key.toLowerCase() === 'content-type') {
key = 'Content-Type';
}
instanceHeaders[key] = this.headers[key].getValue(dc.state);
}
const contentType = this.contentType.getValue(dc.state) || 'application/json';
instanceHeaders['Content-Type'] = contentType;
let instanceBody;
let traceInfo;
try {
const body = (0, jsonExtensions_1.evaluateExpression)(dc.state, this.body);
if (body) {
if (typeof body === 'string') {
instanceBody = body;
}
else {
instanceBody = JSON.stringify(Object.assign({}, body));
}
}
traceInfo = {
request: {
method: instanceMethod,
url: instanceUrl,
headers: instanceHeaders,
content: instanceBody,
},
response: undefined,
};
let response;
switch (this.method) {
case HttpMethod.DELETE:
case HttpMethod.GET:
case HttpMethod.HEAD:
response = yield (0, node_fetch_1.default)(instanceUrl, {
method: instanceMethod,
headers: instanceHeaders,
});
break;
case HttpMethod.PUT:
case HttpMethod.PATCH:
case HttpMethod.POST:
response = yield (0, node_fetch_1.default)(instanceUrl, {
method: instanceMethod,
headers: instanceHeaders,
body: instanceBody,
});
break;
}
const result = new Result(response.headers);
result.statusCode = response.status;
result.reasonPhrase = response.statusText;
switch (this.responseType.getValue(dc.state)) {
case ResponsesTypes.Activity:
result.content = yield response.json();
dc.context.sendActivity(result.content);
break;
case ResponsesTypes.Activities:
result.content = yield response.json();
dc.context.sendActivities(result.content);
break;
case ResponsesTypes.Json: {
const content = yield response.text();
try {
result.content = JSON.parse(content);
}
catch (_a) {
result.content = content;
}
break;
}
case ResponsesTypes.Binary: {
const buffer = yield response.arrayBuffer();
result.content = new Uint8Array(buffer);
break;
}
case ResponsesTypes.None:
default:
break;
}
return yield this.endDialogWithResult(dc, result, traceInfo);
}
catch (err) {
if (err instanceof node_fetch_1.FetchError) {
const result = new Result();
result.content = err.message;
result.statusCode = botbuilder_core_1.StatusCodes.NOT_FOUND;
return yield this.endDialogWithResult(dc, result, traceInfo);
}
else {
throw err;
}
}
});
}
/**
* Writes Trace Activity for the http request and response values and returns the actionResult as the result of this operation.
*
* @param dc The [DialogContext](xref:botbuilder-dialogs.DialogContext) for the current turn of conversation.
* @param result Value returned from the dialog that was called. The type
* of the value returned is dependent on the child dialog.
* @param traceInfo Trace information to be written.
* @returns A `Promise` representing the asynchronous operation.
*/
endDialogWithResult(dc, result, traceInfo) {
return __awaiter(this, void 0, void 0, function* () {
traceInfo.response = result;
// Write trace activity for http request and response values.
yield dc.context.sendTraceActivity('HttpRequest', traceInfo, 'Microsoft.HttpRequest', this.id);
if (this.resultProperty) {
dc.state.setValue(this.resultProperty.getValue(dc.state), result);
}
return yield dc.endDialog(result);
});
}
/**
* @protected
* Builds the compute Id for the [Dialog](xref:botbuilder-dialogs.Dialog).
* @returns A `string` representing the compute Id.
*/
onComputeId() {
return `HttpRequest[${this.method} ${this.url}]`;
}
}
exports.HttpRequest = HttpRequest;
HttpRequest.$kind = 'Microsoft.HttpRequest';
//# sourceMappingURL=httpRequest.js.map