diff --git a/Composer/packages/types/src/runtime.ts b/Composer/packages/types/src/runtime.ts index be9661605a..1e83e835f1 100644 --- a/Composer/packages/types/src/runtime.ts +++ b/Composer/packages/types/src/runtime.ts @@ -1,6 +1,5 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. - import { IBotProject } from './server'; import { DialogSetting } from './settings'; @@ -63,7 +62,7 @@ export type RuntimeTemplate = { eject?: (project: IBotProject, localDisk?: any, isReplace?: boolean) => Promise; /** build method used for local publish */ - build: (runtimePath: string, project: IBotProject) => Promise; + build: (runtimePath: string, project: IBotProject, fullSettings?: DialogSetting, port?: number) => Promise; run: (project: IBotProject, localDisk?: any) => Promise; diff --git a/extensions/localPublish/src/index.ts b/extensions/localPublish/src/index.ts index acb0bda604..363b572850 100644 --- a/extensions/localPublish/src/index.ts +++ b/extensions/localPublish/src/index.ts @@ -128,8 +128,21 @@ class LocalPublisher implements PublishPlugin { ); }; - private publishAsync = async (botId: string, version: string, fullSettings: any, project: any, user) => { + private publishAsync = async (botId: string, version: string, fullSettings: DialogSetting, project: any, user) => { try { + let port; + if (LocalPublisher.runningBots[botId]) { + this.composer.log('Bot already running. Stopping bot...'); + // this may or may not be set based on the status of the bot + port = LocalPublisher.runningBots[botId].port; + await this.stopBot(botId); + } + if (!port) { + // Portfinder is the stablest amongst npm libraries for finding ports. https://github.com/http-party/node-portfinder/issues/61. It does not support supplying an array of ports to pick from as we can have a race conidtion when starting multiple bots at the same time. As a result, getting the max port number out of the range and starting the range from the max. + const maxPort = max(map(LocalPublisher.runningBots, 'port')) ?? 3979; + port = await portfinder.getPortPromise({ port: maxPort + 1, stopPort: 6000 }); + } + // if enableCustomRuntime is not true, initialize the runtime code in a tmp folder // and export the content into that folder as well. const runtime = this.composer.getRuntimeByProject(project); @@ -140,11 +153,11 @@ class LocalPublisher implements PublishPlugin { await this.saveContent(botId, version, project.dataDir, user); } else if (project.settings.runtime.path && project.settings.runtime.command) { const runtimePath = project.getRuntimePath(); - await runtime.build(runtimePath, project); + await runtime.build(runtimePath, project, fullSettings, port); } else { throw new Error('Custom runtime settings are incomplete. Please specify path and command.'); } - await this.setBot(botId, version, fullSettings, project); + await this.setBot(botId, version, fullSettings, project, port); } catch (error) { await this.stopBot(botId); this.setBotStatus(botId, { @@ -332,22 +345,9 @@ class LocalPublisher implements PublishPlugin { }; // start bot in current version - private setBot = async (botId: string, version: string, settings: any, project: any) => { + private setBot = async (botId: string, version: string, settings: any, project: any, port: number) => { // get port, and stop previous bot if exist try { - let port; - if (LocalPublisher.runningBots[botId]) { - this.composer.log('Bot already running. Stopping bot...'); - // this may or may not be set based on the status of the bot - port = LocalPublisher.runningBots[botId].port; - await this.stopBot(botId); - } - if (!port) { - // Portfinder is the stablest amongst npm libraries for finding ports. https://github.com/http-party/node-portfinder/issues/61. It does not support supplying an array of ports to pick from as we can have a race conidtion when starting multiple bots at the same time. As a result, getting the max port number out of the range and starting the range from the max. - const maxPort = max(map(LocalPublisher.runningBots, 'port')) ?? 3979; - port = await portfinder.getPortPromise({ port: maxPort + 1, stopPort: 6000 }); - } - // if not using custom runtime, update assets in tmp older if (!settings.runtime || settings.runtime.customRuntime !== true) { this.composer.log('Updating bot assets'); diff --git a/extensions/runtimes/package.json b/extensions/runtimes/package.json index ce9f5babbe..8da451c108 100644 --- a/extensions/runtimes/package.json +++ b/extensions/runtimes/package.json @@ -10,6 +10,7 @@ "watch": "yarn build --watch" }, "dependencies": { + "@botframework-composer/types": "file:../../Composer/packages/types", "fs-extra": "^9.0.1", "path": "^0.12.7", "rimraf": "^3.0.2" diff --git a/extensions/runtimes/src/index.ts b/extensions/runtimes/src/index.ts index 0555740a1f..f1795a29b6 100644 --- a/extensions/runtimes/src/index.ts +++ b/extensions/runtimes/src/index.ts @@ -5,6 +5,7 @@ import path from 'path'; import { promisify } from 'util'; import { exec } from 'child_process'; +import { DialogSetting, IBotProject } from '@botframework-composer/types'; import rimraf from 'rimraf'; import * as fs from 'fs-extra'; @@ -14,6 +15,52 @@ import { IFileStorage } from './interface'; const execAsync = promisify(exec); const removeDirAndFiles = promisify(rimraf); +/** + * Used to set values for Azure Functions runtime environment variables + * This is used to set the "sensitive values" when using Azure Functions + * @param name name of key + * @param value value of key + * @param cwd path where the command will be run + */ +const writeLocalFunctionsSetting = async (name: string, value: string, cwd: string, log) => { + // only set if there is both a setting and a value. + if (name && value && cwd) { + const { stderr: err } = await execAsync(`func settings add ${name} ${value}`, { cwd: cwd }); + if (err) { + log('Error calling func settings add', err); + throw new Error(err); + } + } +}; + +const writeAllLocalFunctionsSettings = async (fullSettings: DialogSetting, port: number, runtimePath: string, log) => { + await writeLocalFunctionsSetting('MicrosoftAppPassword', fullSettings.MicrosoftAppPassword, runtimePath, log); + await writeLocalFunctionsSetting( + 'luis:endpointKey', + fullSettings.luis?.endpointKey || fullSettings.luis?.authoringKey, + runtimePath, + log + ); + await writeLocalFunctionsSetting('qna:endpointKey', fullSettings.qna?.endpointKey, runtimePath, log); + let skillHostEndpoint; + if (isSkillHostUpdateRequired(fullSettings?.skillHostEndpoint)) { + // Update skillhost endpoint only if ngrok url not set meaning empty or localhost url + skillHostEndpoint = `http://127.0.0.1:${port}/api/skills`; + } + await writeLocalFunctionsSetting('SkillHostEndpoint', skillHostEndpoint, runtimePath, log); +}; + +// eslint-disable-next-line security/detect-unsafe-regex +const localhostRegex = /^https?:\/\/(localhost|127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|::1)/; + +const isLocalhostUrl = (matchUrl: string) => { + return localhostRegex.test(matchUrl); +}; + +const isSkillHostUpdateRequired = (skillHostEndpoint?: string) => { + return !skillHostEndpoint || isLocalhostUrl(skillHostEndpoint); +}; + export default async (composer: any): Promise => { const dotnetTemplatePath = path.resolve(__dirname, '../../../runtime/dotnet'); const nodeTemplatePath = path.resolve(__dirname, '../../../runtime/node'); @@ -27,7 +74,7 @@ export default async (composer: any): Promise => { name: 'C#', startCommand: 'dotnet run --project azurewebapp', path: dotnetTemplatePath, - build: async (runtimePath: string, _project: any) => { + build: async (runtimePath: string, _project: IBotProject) => { composer.log(`BUILD THIS C# PROJECT! at ${runtimePath}...`); composer.log('Run dotnet user-secrets init...'); // TODO: capture output of this and store it somewhere useful @@ -49,7 +96,7 @@ export default async (composer: any): Promise => { packageName: string, version: string, source: string, - _project: any, + _project: IBotProject, isPreview = false ): Promise => { // run dotnet install on the project @@ -78,10 +125,15 @@ export default async (composer: any): Promise => { identifyManifest: (runtimePath: string, projName?: string): string => { return path.join(runtimePath, 'azurewebapp', 'Microsoft.BotFramework.Composer.WebApp.csproj'); }, - run: async (project: any, localDisk: IFileStorage) => { + run: async (project: IBotProject, localDisk: IFileStorage) => { composer.log('RUN THIS C# PROJECT!'); }, - buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + buildDeploy: async ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ): Promise => { composer.log('BUILD FOR DEPLOY TO AZURE!'); let csproj = ''; @@ -147,7 +199,7 @@ export default async (composer: any): Promise => { // return the location of the build artifiacts return publishFolder; }, - eject: async (project, localDisk: IFileStorage, isReplace: boolean) => { + eject: async (project: IBotProject, localDisk: IFileStorage, isReplace: boolean) => { const sourcePath = dotnetTemplatePath; const destPath = path.join(project.dir, 'runtime'); if ((await project.fileStorage.exists(destPath)) && isReplace) { @@ -201,7 +253,7 @@ export default async (composer: any): Promise => { name: 'JS (preview)', startCommand: 'node ./lib/webapp.js', path: nodeTemplatePath, - build: async (runtimePath: string, _project: any) => { + build: async (runtimePath: string, _project: IBotProject) => { // do stuff composer.log('BUILD THIS JS PROJECT'); // install dev dependencies in production, make sure typescript is installed @@ -228,7 +280,7 @@ export default async (composer: any): Promise => { packageName: string, version: string, source: string, - _project: any + _project: IBotProject ): Promise => { // run dotnet install on the project const { stderr: installError, stdout: installOutput } = await execAsync( @@ -258,10 +310,15 @@ export default async (composer: any): Promise => { identifyManifest: (runtimePath: string, projName?: string): string => { return path.join(runtimePath, 'package.json'); }, - run: async (project: any, localDisk: IFileStorage) => { + run: async (project: IBotProject, localDisk: IFileStorage) => { // do stuff }, - buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + buildDeploy: async ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ): Promise => { // do stuff composer.log('BUILD THIS JS PROJECT'); const { stderr: installErr } = await execAsync('npm install', { @@ -286,7 +343,7 @@ export default async (composer: any): Promise => { composer.log('BUILD COMPLETE'); return path.resolve(runtimePath, '../'); }, - eject: async (project: any, localDisk: IFileStorage, isReplace: boolean) => { + eject: async (project: IBotProject, localDisk: IFileStorage, isReplace: boolean) => { const sourcePath = nodeTemplatePath; const destPath = path.join(project.dir, 'runtime'); @@ -325,12 +382,12 @@ export default async (composer: any): Promise => { composer.addRuntimeTemplate({ key: 'adaptive-runtime-dotnet-webapp', name: 'C# - Web App', - build: async (runtimePath: string, _project: any) => { - composer.log(`BUILD THIS C# PROJECT! at ${runtimePath}...`); + build: async (runtimePath: string, project: IBotProject) => { + composer.log(`BUILD THIS C# WEBAPP PROJECT! at ${runtimePath}...`); composer.log('Run dotnet user-secrets init...'); // TODO: capture output of this and store it somewhere useful - const { stderr: initErr } = await execAsync(`dotnet user-secrets init --project ${_project.name}.csproj`, { + const { stderr: initErr } = await execAsync(`dotnet user-secrets init --project ${project.name}.csproj`, { cwd: runtimePath, }); if (initErr) { @@ -338,7 +395,7 @@ export default async (composer: any): Promise => { } composer.log('Run dotnet build...'); - const { stderr: buildErr } = await execAsync(`dotnet build ${_project.name}.csproj`, { cwd: runtimePath }); + const { stderr: buildErr } = await execAsync(`dotnet build ${project.name}.csproj`, { cwd: runtimePath }); if (buildErr) { throw new Error(buildErr); } @@ -349,11 +406,11 @@ export default async (composer: any): Promise => { packageName: string, version: string, source: string, - _project: any, + project: IBotProject, isPreview = false ): Promise => { // run dotnet install on the project - const command = `dotnet add ${_project.name}.csproj package "${packageName}"${ + const command = `dotnet add ${project.name}.csproj package "${packageName}"${ version ? ' --version="' + version + '"' : '' }${source ? ' --source="' + source + '"' : ''}${isPreview ? ' --prerelease' : ''}`; composer.log('EXEC:', command); @@ -365,11 +422,11 @@ export default async (composer: any): Promise => { } return installOutput; }, - uninstallComponent: async (runtimePath: string, packageName: string, _project: any): Promise => { + uninstallComponent: async (runtimePath: string, packageName: string, project: IBotProject): Promise => { // run dotnet install on the project - composer.log(`EXECUTE: dotnet remove ${_project.name}.csproj package ${packageName}`); + composer.log(`EXECUTE: dotnet remove ${project.name}.csproj package ${packageName}`); const { stderr: installError, stdout: installOutput } = await execAsync( - `dotnet remove ${_project.name}.csproj package ${packageName}`, + `dotnet remove ${project.name}.csproj package ${packageName}`, { cwd: path.join(runtimePath), } @@ -382,10 +439,15 @@ export default async (composer: any): Promise => { identifyManifest: (runtimePath: string, projName?: string): string => { return path.join(runtimePath, `${projName}.csproj`); }, - run: async (project: any, localDisk: IFileStorage) => { + run: async (project: IBotProject, localDisk: IFileStorage) => { composer.log('RUN THIS C# PROJECT!'); }, - buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + buildDeploy: async ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ): Promise => { composer.log('BUILD FOR DEPLOY TO AZURE!'); // find publishing profile in list @@ -456,12 +518,17 @@ export default async (composer: any): Promise => { name: 'C# - Functions', // startCommand: 'dotnet run', // path: dotnetTemplatePath, - build: async (runtimePath: string, _project: any) => { - composer.log(`BUILD THIS C# PROJECT! at ${runtimePath}...`); + build: async (runtimePath: string, project: IBotProject, fullSettings?: DialogSetting, port?: number) => { + composer.log(`BUILD THIS C# FUNCTIONS PROJECT! at ${runtimePath}...`); composer.log('Run dotnet user-secrets init...'); + if (fullSettings && port) { + // we need to update the local.settings.json file with sensitive settings + await writeAllLocalFunctionsSettings(fullSettings, port, runtimePath, composer.log); + } + // TODO: capture output of this and store it somewhere useful - const { stderr: initErr } = await execAsync(`dotnet user-secrets init --project ${_project.name}.csproj`, { + const { stderr: initErr } = await execAsync(`dotnet user-secrets init --project ${project.name}.csproj`, { cwd: runtimePath, }); if (initErr) { @@ -469,7 +536,7 @@ export default async (composer: any): Promise => { } composer.log('Run dotnet build...'); - const { stderr: buildErr } = await execAsync(`dotnet build ${_project.name}.csproj`, { cwd: runtimePath }); + const { stderr: buildErr } = await execAsync(`dotnet build ${project.name}.csproj`, { cwd: runtimePath }); if (buildErr) { throw new Error(buildErr); } @@ -480,11 +547,11 @@ export default async (composer: any): Promise => { packageName: string, version: string, source: string, - _project: any, + project: IBotProject, isPreview = false ): Promise => { // run dotnet install on the project - const command = `dotnet add ${_project.name}.csproj package "${packageName}"${ + const command = `dotnet add ${project.name}.csproj package "${packageName}"${ version ? ' --version="' + version + '"' : '' }${source ? ' --source="' + source + '"' : ''}${isPreview ? ' --prerelease' : ''}`; composer.log('EXEC:', command); @@ -496,11 +563,11 @@ export default async (composer: any): Promise => { } return installOutput; }, - uninstallComponent: async (runtimePath: string, packageName: string, _project: any): Promise => { + uninstallComponent: async (runtimePath: string, packageName: string, project: IBotProject): Promise => { // run dotnet install on the project - composer.log(`EXECUTE: dotnet remove ${_project.name}.csproj package ${packageName}`); + composer.log(`EXECUTE: dotnet remove ${project.name}.csproj package ${packageName}`); const { stderr: installError, stdout: installOutput } = await execAsync( - `dotnet remove ${_project.name}.csproj package ${packageName}`, + `dotnet remove ${project.name}.csproj package ${packageName}`, { cwd: path.join(runtimePath), } @@ -513,10 +580,15 @@ export default async (composer: any): Promise => { identifyManifest: (runtimePath: string, projName?: string): string => { return path.join(runtimePath, `${projName}.csproj`); }, - run: async (project: any, localDisk: IFileStorage) => { + run: async (project: IBotProject, localDisk: IFileStorage) => { composer.log('RUN THIS C# PROJECT!'); }, - buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + buildDeploy: async ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ): Promise => { composer.log('BUILD FOR DEPLOY TO AZURE!'); // find publishing profile in list @@ -561,7 +633,7 @@ export default async (composer: any): Promise => { name: 'JS - Web App (preview)', // startCommand: 'node ./lib/webapp.js', // path: nodeTemplatePath, - build: async (runtimePath: string, _project: any) => { + build: async (runtimePath: string, _project: IBotProject) => { // do stuff composer.log('BUILD THIS JS PROJECT'); // install dev dependencies in production, make sure typescript is installed @@ -581,7 +653,7 @@ export default async (composer: any): Promise => { packageName: string, version: string, source: string, - _project: any, + _project: IBotProject, isPreview = false ): Promise => { // run dotnet install on the project @@ -612,7 +684,12 @@ export default async (composer: any): Promise => { identifyManifest: (runtimePath: string, projName?: string): string => { return path.join(runtimePath, 'package.json'); }, - buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + buildDeploy: async ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ): Promise => { // do stuff composer.log(`BUILD THIS JS PROJECT in ${runtimePath}`); const { stderr: installErr } = await execAsync('npm install', { @@ -629,7 +706,7 @@ export default async (composer: any): Promise => { composer.addRuntimeTemplate({ key: 'adaptive-runtime-js-functions', name: 'JS - Functions (preview)', - build: async (runtimePath: string, _project: any) => { + build: async (runtimePath: string, _project: IBotProject, fullSettings?: DialogSetting, port?: number) => { // do stuff composer.log('BUILD THIS JS PROJECT'); // install dev dependencies in production, make sure typescript is installed @@ -642,6 +719,11 @@ export default async (composer: any): Promise => { composer.log(`npm install timeout, ${installErr}`); } + if (fullSettings && port) { + // we need to update the local.settings.json file with sensitive settings + await writeAllLocalFunctionsSettings(fullSettings, port, runtimePath, composer.log); + } + composer.log('BUILD COMPLETE'); }, installComponent: async ( @@ -649,7 +731,7 @@ export default async (composer: any): Promise => { packageName: string, version: string, source: string, - _project: any, + _project: IBotProject, isPreview = false ): Promise => { // run dotnet install on the project @@ -680,7 +762,12 @@ export default async (composer: any): Promise => { identifyManifest: (runtimePath: string, projName?: string): string => { return path.join(runtimePath, 'package.json'); }, - buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + buildDeploy: async ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ): Promise => { // do stuff composer.log(`BUILD THIS JS PROJECT in ${runtimePath}`); const { stderr: installErr } = await execAsync('npm ci', { diff --git a/extensions/runtimes/yarn.lock b/extensions/runtimes/yarn.lock index d9f566fcb8..e81052d588 100644 --- a/extensions/runtimes/yarn.lock +++ b/extensions/runtimes/yarn.lock @@ -2,6 +2,31 @@ # yarn lockfile v1 +"@botframework-composer/types@file:../../Composer/packages/types": + version "0.0.2" + dependencies: + "@types/express" "^4.16.1" + "@types/passport" "^1.0.4" + axios "^0.21.1" + botframework-schema "^4.11.1" + express-serve-static-core "0.1.1" + json-schema "^0.2.5" + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.34" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901" + integrity sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ== + dependencies: + "@types/node" "*" + "@types/eslint-scope@^3.7.0": version "3.7.0" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" @@ -23,16 +48,65 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== +"@types/express-serve-static-core@^4.17.18": + version "4.17.19" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d" + integrity sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.16.1": + version "4.17.11" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545" + integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/json-schema@*", "@types/json-schema@^7.0.6": version "7.0.6" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/node@*", "@types/node@^14.14.6": version "14.14.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== +"@types/passport@^1.0.4": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.6.tgz#72343e49d65efa98cb328163cff5f127981947d7" + integrity sha512-9oKfrJXuAxvyxdrtMCxKkHgmd6DMO8NDOLvMJ1LvIWd6/xP+i81PAkpTaEca7VhJX9S009RciwZL/j6dsLsHrA== + dependencies: + "@types/express" "*" + +"@types/qs@*": + version "6.9.6" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.6.tgz#df9c3c8b31a247ec315e6996566be3171df4b3b1" + integrity sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.9" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.9.tgz#aacf28a85a05ee29a11fb7c3ead935ac56f33e4e" + integrity sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -242,6 +316,13 @@ at-least-node@^1.0.0: resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +axios@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -252,6 +333,18 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +botbuilder-stdlib@4.13.1-internal: + version "4.13.1-internal" + resolved "https://registry.yarnpkg.com/botbuilder-stdlib/-/botbuilder-stdlib-4.13.1-internal.tgz#498bc7aeca9a429d97aae332ff8e7c80d2ad5fdb" + integrity sha512-olwY7JWQy7JZ3CtW4Z7mxImDMe7yXAF1Ut++OWQ6PKPvx/9C8FsKrAc+M41QqF1y2yriSkHbaadsQqHqPP9fVw== + +botframework-schema@^4.11.1: + version "4.13.1" + resolved "https://registry.yarnpkg.com/botframework-schema/-/botframework-schema-4.13.1.tgz#581a5e7d0bc407c08e87f96170b091e6ae86abc8" + integrity sha512-UP9UVSPk0TxCWnk7hHp1CpglyHkt28MlkIsDgVkVUyABDEOSMmReTQRhK9uZuP8vRFDArnUSU2rN44ykDxAtbg== + dependencies: + botbuilder-stdlib "4.13.1-internal" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -472,6 +565,11 @@ execa@^4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +express-serve-static-core@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/express-serve-static-core/-/express-serve-static-core-0.1.1.tgz#222358112a79bc9fbe00838232e8cd2e3132ef37" + integrity sha1-IiNYESp5vJ++AIOCMujNLjEy7zc= + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -497,6 +595,11 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +follow-redirects@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== + fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -645,6 +748,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.5.tgz#97997f50972dd0500214e208c407efa4b5d7063b" + integrity sha512-gWJOWYFrhQ8j7pVm0EM8Slr+EPVq1Phf6lvzvD/WCeqkrx/f2xBI0xOsRRS9xCn3I4vKtP519dvs3TP09r24wQ== + json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"