diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f4313ad248..d6bde3d1c4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,7 +49,7 @@ jobs: base-path: ./Composer botproject: - name: BotProject + name: BotProject-dotnet runs-on: windows-latest timeout-minutes: 20 @@ -67,11 +67,31 @@ jobs: run: dotnet test working-directory: runtime/dotnet/tests + nodejs: + name: BotProject-nodejs + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set Node Version + uses: actions/setup-node@v1 + with: + node-version: 12.13.0 + - name: npm install + run: npm install + working-directory: runtime/node + - name: npm build + run: npm run build + working-directory: runtime/node + - name: npm test + run: npm run test + working-directory: runtime/node # docker-build: # name: Docker Build # timeout-minutes: 20 # runs-on: ubuntu-latest - # steps: # - name: Checkout # uses: actions/checkout@v2 diff --git a/.vscode/launch.json b/.vscode/launch.json index 7a83704957..b7c8245d2b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -22,7 +22,7 @@ ], "sourceMaps": true, "cwd": "${workspaceFolder}/Composer/packages/tools/language-servers/language-understanding/demo/src", - "protocol": "inspector", + "protocol": "inspector" }, { "name": "LG LSP Server", @@ -38,20 +38,16 @@ ], "sourceMaps": true, "cwd": "${workspaceFolder}/Composer/packages/tools/language-servers/language-generation/demo/src", - "protocol": "inspector", + "protocol": "inspector" }, { "type": "node", "request": "launch", "name": "Server: Launch", - "args": [ - "./build/server.js" - ], + "args": ["./build/server.js"], "preLaunchTask": "server: build", "restart": true, - "outFiles": [ - "./build/*" - ], + "outFiles": ["./build/*"], "envFile": "${workspaceFolder}/Composer/packages/server/.env", "outputCapture": "std", "cwd": "${workspaceFolder}/Composer/packages/server" @@ -63,14 +59,8 @@ "name": "Jest Debug", "program": "${workspaceRoot}/Composer/node_modules/jest/bin/jest", "stopOnEntry": false, - "args": [ - "--runInBand", - "--env=jsdom", - "--config=jest.config.js" - ], - "runtimeArgs": [ - "--inspect-brk" - ], + "args": ["--runInBand", "--env=jsdom", "--config=jest.config.js"], + "runtimeArgs": ["--inspect-brk"], "cwd": "${workspaceRoot}/Composer/packages/server", "sourceMaps": true, "console": "integratedTerminal" @@ -87,11 +77,9 @@ "request": "launch", "name": "Electron Main Process", "runtimeExecutable": "${workspaceRoot}/Composer/node_modules/.bin/electron", - "args": [ - "${workspaceRoot}/Composer/packages/electron-server", - ], + "args": ["${workspaceRoot}/Composer/packages/electron-server"], "env": { - "NODE_ENV": "development", + "NODE_ENV": "development" }, "outputCapture": "std" }, diff --git a/Composer/.npmrc b/Composer/.npmrc index 2ae06b6797..764364f5c9 100644 --- a/Composer/.npmrc +++ b/Composer/.npmrc @@ -1 +1,2 @@ @bfcomposer:registry=https://botbuilder.myget.org/F/botbuilder-declarative/npm/ +scripts-prepend-node-path=true diff --git a/Composer/cypress/integration/LuisDeploy.spec.ts b/Composer/cypress/integration/LuisDeploy.spec.ts index 467fd4743e..fac2abfa85 100644 --- a/Composer/cypress/integration/LuisDeploy.spec.ts +++ b/Composer/cypress/integration/LuisDeploy.spec.ts @@ -4,9 +4,9 @@ context('Luis Deploy', () => { beforeEach(() => { cy.server(); - cy.route('POST', '/api/publish/*/publish/default', { endpointURL: 'anything' }); + cy.route('POST', '/api/publish/*/publish/default', { endpointURL: 'anything', status: 202 }); cy.route('POST', '/api/projects/*/settings', 'OK'); - cy.route('GET', '/api/publish/*/status/default', { endpointURL: 'anything' }); + cy.route('GET', '/api/publish/*/status/default', { endpointURL: 'anything', status: 200 }); cy.visit('/home'); cy.createBot('ToDoBotWithLuisSample'); }); diff --git a/Composer/package.json b/Composer/package.json index e419b99b20..a8b19b5f9f 100644 --- a/Composer/package.json +++ b/Composer/package.json @@ -41,7 +41,11 @@ "build:server": "yarn workspace @bfc/server build", "build:client": "yarn workspace @bfc/client build", "build:tools": "yarn workspace @bfc/tools build:all", - "build:plugins": "cd plugins && yarn install && yarn build:all", + "build:plugins": "yarn build:plugins:localpublish && yarn build:plugins:samples && yarn build:plugins:azurePublish && yarn build:plugins:runtimes", + "build:plugins:localpublish": "cd plugins/localPublish && yarn install && yarn build", + "build:plugins:samples": "cd plugins/samples && yarn install && yarn build", + "build:plugins:azurePublish": "cd plugins/azurePublish && yarn install && yarn build", + "build:plugins:runtimes": "cd plugins/runtimes && yarn install && yarn build", "start": "cross-env NODE_ENV=production PORT=3000 yarn start:server", "startall": "yarn start", "start:dev": "concurrently \"npm:start:client\" \"npm:start:server:dev\"", diff --git a/Composer/packages/client/src/components/TestController/TestController.tsx b/Composer/packages/client/src/components/TestController/TestController.tsx index 7f15115a8b..a0422f7011 100644 --- a/Composer/packages/client/src/components/TestController/TestController.tsx +++ b/Composer/packages/client/src/components/TestController/TestController.tsx @@ -8,8 +8,8 @@ import { jsx, css } from '@emotion/core'; import { PrimaryButton } from 'office-ui-fabric-react/lib/Button'; import formatMessage from 'format-message'; import { useRecoilValue } from 'recoil'; +import { defaultPublishConfig } from '@bfc/shared'; -import { DefaultPublishConfig } from '../../constants'; import { botNameState, botStatusState, @@ -49,10 +49,12 @@ export const botButton = css` `; // -------------------- TestController -------------------- // - +const POLLING_INTERVAL = 2500; export const TestController: React.FC = () => { const [modalOpen, setModalOpen] = useState(false); const [calloutVisible, setCalloutVisible] = useState(false); + const [botStatusInterval, setBotStatusInterval] = useState(undefined); + const botActionRef = useRef(null); const notifications = useNotifications(); const botName = useRecoilValue(botNameState); @@ -82,7 +84,7 @@ export const TestController: React.FC = () => { useEffect(() => { if (projectId) { - getPublishStatus(projectId, DefaultPublishConfig); + getPublishStatus(projectId, defaultPublishConfig); } }, [projectId]); @@ -90,12 +92,26 @@ export const TestController: React.FC = () => { switch (botStatus) { case BotStatus.failed: openCallout(); + stopPollingRuntime(); setBotStatus(BotStatus.pending); break; case BotStatus.published: + stopPollingRuntime(); handleLoadBot(); break; + case BotStatus.reloading: + startPollingRuntime(); + break; + default: + case BotStatus.connected: + stopPollingRuntime(); + break; } + // return the stoppolling function so the component will clean up + return () => { + stopPollingRuntime(); + return; + }; }, [botStatus]); function dismissDialog() { @@ -114,6 +130,23 @@ export const TestController: React.FC = () => { setCalloutVisible(true); } + function startPollingRuntime() { + if (!botStatusInterval) { + const cancelInterval = setInterval(() => { + // get publish status + getPublishStatus(projectId, defaultPublishConfig); + }, POLLING_INTERVAL); + setBotStatusInterval(cancelInterval); + } + } + + function stopPollingRuntime() { + if (botStatusInterval) { + clearInterval(botStatusInterval); + setBotStatusInterval(undefined); + } + } + async function handlePublishLuis(luisConfig) { setBotStatus(BotStatus.publishing); dismissDialog(); @@ -124,7 +157,7 @@ export const TestController: React.FC = () => { async function handleLoadBot() { setBotStatus(BotStatus.reloading); const sensitiveSettings = settingsStorage.get(projectId); - await publishToTarget(projectId, DefaultPublishConfig, { comment: '' }, sensitiveSettings); + await publishToTarget(projectId, defaultPublishConfig, { comment: '' }, sensitiveSettings); } function isLuisConfigComplete(config) { diff --git a/Composer/packages/client/src/constants.ts b/Composer/packages/client/src/constants.ts index e3c24ffc21..e2792cc7fd 100644 --- a/Composer/packages/client/src/constants.ts +++ b/Composer/packages/client/src/constants.ts @@ -179,11 +179,6 @@ export enum AppUpdaterStatus { UPDATE_SUCCEEDED, } -export const DefaultPublishConfig = { - name: 'default', - type: 'localpublish', -}; - export const EmptyBotTemplateId = 'EmptyBot'; export const nameRegex = /^[a-zA-Z0-9-_]+$/; diff --git a/Composer/packages/client/src/pages/publish/Publish.tsx b/Composer/packages/client/src/pages/publish/Publish.tsx index e398a23c8c..f0118526df 100644 --- a/Composer/packages/client/src/pages/publish/Publish.tsx +++ b/Composer/packages/client/src/pages/publish/Publish.tsx @@ -8,8 +8,8 @@ import { RouteComponentProps } from '@reach/router'; import formatMessage from 'format-message'; import { Dialog, DialogType } from 'office-ui-fabric-react/lib/Dialog'; import { TextField } from 'office-ui-fabric-react/lib/TextField'; -import { useRecoilValue } from 'recoil'; import { PublishTarget } from '@bfc/shared'; +import { useRecoilValue } from 'recoil'; import settingsStorage from '../../utils/dialogSettingStorage'; import { projectContainer } from '../design/styles'; @@ -224,7 +224,7 @@ const Publish: React.FC = (props) => { }, ]); } - }, [publishHistory, selectedTargetName]); + }, [publishHistory, selectedTargetName, settings.publishTargets]); // check history to see if a 202 is found useEffect(() => { diff --git a/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx b/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx index 48b09f61f6..6d5c26ca2a 100644 --- a/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx +++ b/Composer/packages/client/src/pages/setting/runtime-settings/RuntimeSettings.tsx @@ -20,6 +20,7 @@ import { dispatcherState, ejectRuntimeSelector, boilerplateVersionState, + isEjectRuntimeExistState, } from '../../../recoilModel'; import { OpenConfirmModal } from '../../../components/Modal/ConfirmDialog'; import { LoadingSpinner } from '../../../components/LoadingSpinner'; @@ -33,10 +34,14 @@ export const RuntimeSettings: React.FC = () => { const settings = useRecoilValue(settingsState); const projectId = useRecoilValue(projectIdState); const boilerplateVersion = useRecoilValue(boilerplateVersionState); - - const { setCustomRuntime, setRuntimeField, getBoilerplateVersion, updateBoilerplate } = useRecoilValue( - dispatcherState - ); + const isEjectRuntimeExist = useRecoilValue(isEjectRuntimeExistState); + const { + setCustomRuntime, + setRuntimeField, + getBoilerplateVersion, + updateBoilerplate, + stopPublishBot, + } = useRecoilValue(dispatcherState); const runtimeEjection = useRecoilValue(ejectRuntimeSelector); const [formDataErrors, setFormDataErrors] = useState({ command: '', path: '' }); @@ -44,6 +49,7 @@ export const RuntimeSettings: React.FC = () => { const [working, setWorking] = useState(false); const [ejecting, setEjecting] = useState(false); const [needsUpdate, setNeedsUpdate] = useState(false); + const [templateKey, setTemplateKey] = useState(''); useEffect(() => { // check the status of the boilerplate material and see if it requires an update @@ -54,6 +60,13 @@ export const RuntimeSettings: React.FC = () => { setNeedsUpdate(boilerplateVersion.updateRequired || false); }, [boilerplateVersion.updateRequired]); + useEffect(() => { + if (isEjectRuntimeExist && templateKey) { + confirmReplaceEject(templateKey); + setTemplateKey(''); + } + }, [isEjectRuntimeExist, templateKey]); + const handleChangeToggle = (_, isOn = false) => { setCustomRuntime(projectId, isOn); }; @@ -104,6 +117,7 @@ export const RuntimeSettings: React.FC = () => { closeEjectModal(); await runtimeEjection?.onAction(projectId, templateKey); setEjecting(false); + setTemplateKey(templateKey); }; const callUpdateBoilerplate = async () => { @@ -125,6 +139,20 @@ export const RuntimeSettings: React.FC = () => { } }; + const confirmReplaceEject = async (templateKey: string) => { + const title = formatMessage('Runtime already exists'); + const msg = formatMessage('Are you sure you want to stop current runtime and replace them?'); + const res = await OpenConfirmModal(title, msg); + if (res) { + setEjecting(true); + // stop runtime + await stopPublishBot(projectId); + // replace the runtime + await runtimeEjection?.onAction(projectId, templateKey, true); + setEjecting(false); + } + }; + return botName ? (
{header()} diff --git a/Composer/packages/client/src/pages/setting/runtime-settings/ejectModal.tsx b/Composer/packages/client/src/pages/setting/runtime-settings/ejectModal.tsx index 881020bf5c..f93ddf23c8 100644 --- a/Composer/packages/client/src/pages/setting/runtime-settings/ejectModal.tsx +++ b/Composer/packages/client/src/pages/setting/runtime-settings/ejectModal.tsx @@ -22,6 +22,7 @@ export interface EjectModalProps { export const EjectModal: React.FC = (props) => { const [selectedTemplate, setSelectedTemplate] = useState(); + const runtimeTemplates = useRecoilValue(runtimeTemplatesState); const { fetchRuntimeTemplates } = useRecoilValue(dispatcherState); diff --git a/Composer/packages/client/src/recoilModel/atoms/botState.ts b/Composer/packages/client/src/recoilModel/atoms/botState.ts index caee3a625a..bc77242005 100644 --- a/Composer/packages/client/src/recoilModel/atoms/botState.ts +++ b/Composer/packages/client/src/recoilModel/atoms/botState.ts @@ -17,7 +17,6 @@ import { BotLoadError, DesignPageLocation } from '../../recoilModel/types'; import { PublishType, BreadcrumbItem } from './../../recoilModel/types'; import { BotStatus } from './../../constants'; - const getFullyQualifiedKey = (value: string) => { return `Bot_${value}_State`; }; @@ -204,3 +203,8 @@ export const onDelLanguageDialogCompleteState = atom({ key: getFullyQualifiedKey('onDelLanguageDialogComplete'), default: { func: undefined }, }); + +export const isEjectRuntimeExistState = atom({ + key: getFullyQualifiedKey('isEjectRuntimeExist'), + default: false, +}); diff --git a/Composer/packages/client/src/recoilModel/dispatchers/__tests__/setting.test.tsx b/Composer/packages/client/src/recoilModel/dispatchers/__tests__/setting.test.tsx index a2b4537f0a..9c387a4090 100644 --- a/Composer/packages/client/src/recoilModel/dispatchers/__tests__/setting.test.tsx +++ b/Composer/packages/client/src/recoilModel/dispatchers/__tests__/setting.test.tsx @@ -120,12 +120,14 @@ describe('setting dispatcher', () => { it('should update RuntimeSettings', async () => { await act(async () => { - await dispatcher.setRuntimeSettings('', 'path', 'command'); + await dispatcher.setRuntimeSettings('', { path: 'path', command: 'command', key: 'key', name: 'name' }); }); expect(renderedComponent.current.settings.runtime.customRuntime).toBeTruthy(); expect(renderedComponent.current.settings.runtime.path).toBe('path'); expect(renderedComponent.current.settings.runtime.command).toBe('command'); + expect(renderedComponent.current.settings.runtime.key).toBe('key'); + expect(renderedComponent.current.settings.runtime.name).toBe('name'); }); it('should update customRuntime', async () => { diff --git a/Composer/packages/client/src/recoilModel/dispatchers/publisher.ts b/Composer/packages/client/src/recoilModel/dispatchers/publisher.ts index 7bab646389..73ecbd54ae 100644 --- a/Composer/packages/client/src/recoilModel/dispatchers/publisher.ts +++ b/Composer/packages/client/src/recoilModel/dispatchers/publisher.ts @@ -4,18 +4,29 @@ import formatMessage from 'format-message'; import { CallbackInterface, useRecoilCallback } from 'recoil'; - -import { publishTypesState, botStatusState, publishHistoryState, botLoadErrorState } from '../atoms/botState'; +import { defaultPublishConfig } from '@bfc/shared'; + +import { + publishTypesState, + botStatusState, + publishHistoryState, + botLoadErrorState, + isEjectRuntimeExistState, +} from '../atoms/botState'; import filePersistence from '../persistence/FilePersistence'; import { botEndpointsState } from '../atoms'; import { BotStatus, Text } from './../../constants'; import httpClient from './../../utils/httpUtil'; -import { logMessage } from './shared'; +import { logMessage, setError } from './shared'; + +const PUBLISH_SUCCESS = 200; +const PUBLISH_PENDING = 202; +const PUBLISH_FAILED = 500; export const publisherDispatcher = () => { const publishFailure = async ({ set }: CallbackInterface, title: string, error, target) => { - if (target.name === 'default') { + if (target.name === defaultPublishConfig.name) { set(botStatusState, BotStatus.failed); set(botLoadErrorState, { ...error, title }); } @@ -31,10 +42,14 @@ export const publisherDispatcher = () => { }; const publishSuccess = async ({ set }: CallbackInterface, projectId: string, data, target) => { - const { endpointURL } = data; - if (target.name === 'default' && endpointURL) { - set(botStatusState, BotStatus.connected); - set(botEndpointsState, (botEndpoints) => ({ ...botEndpoints, [projectId]: `${endpointURL}/api/messages` })); + const { endpointURL, status } = data; + if (target.name === defaultPublishConfig.name) { + if (status === PUBLISH_SUCCESS && endpointURL) { + set(botStatusState, BotStatus.connected); + set(botEndpointsState, (botEndpoints) => ({ ...botEndpoints, [projectId]: `${endpointURL}/api/messages` })); + } else { + set(botStatusState, BotStatus.reloading); + } } set(publishHistoryState, (publishHistory) => { @@ -57,12 +72,19 @@ export const publisherDispatcher = () => { const { endpointURL, status, id } = data; // the action below only applies to when a bot is being started using the "start bot" button // a check should be added to this that ensures this ONLY applies to the "default" profile. - if (target.name === 'default' && endpointURL) { - set(botStatusState, BotStatus.connected); - set(botEndpointsState, (botEndpoints) => ({ - ...botEndpoints, - [projectId]: `${endpointURL}/api/messages`, - })); + if (target.name === defaultPublishConfig.name) { + if (status === PUBLISH_SUCCESS && endpointURL) { + set(botStatusState, BotStatus.connected); + set(botEndpointsState, (botEndpoints) => ({ + ...botEndpoints, + [projectId]: `${endpointURL}/api/messages`, + })); + } else if (status === PUBLISH_PENDING) { + set(botStatusState, BotStatus.reloading); + } else if (status === PUBLISH_FAILED) { + set(botStatusState, BotStatus.failed); + set(botLoadErrorState, { ...data, title: formatMessage('Start bot failed') }); + } } if (status !== 404) { @@ -154,7 +176,6 @@ export const publisherDispatcher = () => { const response = await httpClient.get(`/publish/${projectId}/status/${target.name}`); updatePublishStatus(callbackHelpers, projectId, target, response.data); } catch (err) { - console.log(err); updatePublishStatus(callbackHelpers, projectId, target, err.response.data); } } @@ -172,16 +193,35 @@ export const publisherDispatcher = () => { })); } catch (err) { //TODO: error - logMessage(callbackHelpers, err.message); + logMessage(callbackHelpers, err.response?.data?.message || err.message); } } ); + const setEjectRuntimeExist = useRecoilCallback(({ set }: CallbackInterface) => async (isExist: boolean) => { + set(isEjectRuntimeExistState, isExist); + }); + + // only support local publish + const stopPublishBot = useRecoilCallback( + (callbackHelpers: CallbackInterface) => async (projectId: string, target: any = defaultPublishConfig) => { + const { set } = callbackHelpers; + try { + await httpClient.post(`/publish/${projectId}/stopPublish/${target.name}`); + set(botStatusState, BotStatus.unConnected); + } catch (err) { + setError(callbackHelpers, err); + logMessage(callbackHelpers, err.message); + } + } + ); return { getPublishTargetTypes, publishToTarget, + stopPublishBot, rollbackToVersion, getPublishStatus, getPublishHistory, + setEjectRuntimeExist, }; }; diff --git a/Composer/packages/client/src/recoilModel/dispatchers/setting.ts b/Composer/packages/client/src/recoilModel/dispatchers/setting.ts index 3d5c139580..0dda82bdba 100644 --- a/Composer/packages/client/src/recoilModel/dispatchers/setting.ts +++ b/Composer/packages/client/src/recoilModel/dispatchers/setting.ts @@ -34,13 +34,15 @@ export const settingsDispatcher = () => { ); const setRuntimeSettings = useRecoilCallback( - ({ set }: CallbackInterface) => async (_, path: string, command: string) => { + ({ set }: CallbackInterface) => async ( + _, + runtime: { path: string; command: string; key: string; name: string } + ) => { set(settingsState, (currentSettingsState) => ({ ...currentSettingsState, runtime: { + ...runtime, customRuntime: true, - path, - command, }, })); } diff --git a/Composer/packages/client/src/recoilModel/selectors/eject.ts b/Composer/packages/client/src/recoilModel/selectors/eject.ts index a42e73d361..66bdb9bbaa 100644 --- a/Composer/packages/client/src/recoilModel/selectors/eject.ts +++ b/Composer/packages/client/src/recoilModel/selectors/eject.ts @@ -13,22 +13,32 @@ import { StateError } from '../../recoilModel/types'; // Actions const ejectRuntimeAction = (dispatcher: Dispatcher) => { return { - onAction: async (projectId: string, name: string) => { + onAction: async (projectId: string, name: string, replace = false) => { try { - const response = await httpClient.post(`/runtime/eject/${projectId}/${name}`); + dispatcher.setEjectRuntimeExist(false); + const response = await httpClient.post(`/runtime/eject/${projectId}/${name}`, { isReplace: replace }); if (!lodashGet(response, 'data.settings.path', '') || !lodashGet(response, 'data.settings.startCommand', '')) { throw new Error('Runtime cannot be ejected'); } - const path = response.data.settings.path; - const command = response.data.settings.startCommand; - dispatcher.setRuntimeSettings(projectId, path, command); + dispatcher.setRuntimeSettings(projectId, { + ...response.data.settings, + command: response.data.settings.startCommand, + }); } catch (ex) { - const errorToShow: StateError = { - message: ex.response?.data?.message || ex.message, - summary: formatMessage('Error occured ejecting runtime!'), - status: ex.response?.data?.status || ex.status, - }; - dispatcher.setApplicationLevelError(errorToShow); + if ( + ex.response?.data?.message && + typeof ex.response.data.message === 'string' && + ex.response.data.message.includes('Runtime already exists') + ) { + dispatcher.setEjectRuntimeExist(true); + } else { + const errorToShow: StateError = { + message: ex.response?.data?.message || ex.response?.data || ex.message, + summary: formatMessage('Error occured ejecting runtime!'), + status: ex.response?.data?.status || ex.status, + }; + dispatcher.setApplicationLevelError(errorToShow); + } } }, }; diff --git a/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts b/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts index 74b5d291e1..10975e026c 100644 --- a/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts +++ b/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts @@ -3,7 +3,6 @@ import { RequestHandler } from 'express-serve-static-core'; import { Debugger } from 'debug'; -import { JSONSchema7 } from 'json-schema'; import { PluginLoader } from './pluginLoader'; import log from './logger'; @@ -56,13 +55,16 @@ export class ComposerPluginRegistration { /************************************************************************************** * Publish related features *************************************************************************************/ - public async addPublishMethod(plugin: PublishPlugin, schema?: JSONSchema7, instructions?: string) { + public async addPublishMethod(plugin: PublishPlugin) { log('registering publish method', this.name); - this.loader.extensions.publish[this.name] = { - plugin: this, - instructions: instructions, + this.loader.extensions.publish[plugin.customName || this.name] = { + plugin: { + name: plugin.customName || this.name, + description: plugin.customDescription || this.description, + instructions: plugin.instructions, + schema: plugin.schema, + }, methods: plugin, - schema: schema, }; } @@ -89,6 +91,20 @@ export class ComposerPluginRegistration { this.loader.extensions.runtimeTemplates.push(plugin); } + /************************************************************************************** + * Get current runtime from project + *************************************************************************************/ + public getRuntimeByProject(project): RuntimeTemplate { + return this.loader.getRuntimeByProject(project); + } + + /************************************************************************************** + * Get current runtime by type + *************************************************************************************/ + public getRuntime(type: string | undefined): RuntimeTemplate { + return this.loader.getRuntime(type); + } + /************************************************************************************** * Add Bot Template (aka, SampleBot) *************************************************************************************/ diff --git a/Composer/packages/extensions/plugin-loader/src/pluginLoader.ts b/Composer/packages/extensions/plugin-loader/src/pluginLoader.ts index ed168bf6c5..b4245309e6 100644 --- a/Composer/packages/extensions/plugin-loader/src/pluginLoader.ts +++ b/Composer/packages/extensions/plugin-loader/src/pluginLoader.ts @@ -8,9 +8,10 @@ import passport from 'passport'; import { Express } from 'express'; import { pathToRegexp } from 'path-to-regexp'; import glob from 'globby'; +import formatMessage from 'format-message'; import { ComposerPluginRegistration } from './composerPluginRegistration'; -import { UserIdentity, ExtensionCollection } from './types'; +import { UserIdentity, ExtensionCollection, RuntimeTemplate, DEFAULT_RUNTIME } from './types'; import log from './logger'; export class PluginLoader { @@ -80,7 +81,7 @@ export class PluginLoader { // the module exported an object with an initialize method thisPlugin.initialize.call(null, pluginRegistration); } else { - throw new Error('Could not init plugin'); + throw new Error(formatMessage('Could not init plugin')); } } @@ -109,6 +110,30 @@ export class PluginLoader { } } + // get the runtime template currently used from project + public getRuntimeByProject(project): RuntimeTemplate { + const type = project.settings.runtime?.key || DEFAULT_RUNTIME; + const template = this.extensions.runtimeTemplates.find((t) => t.key === type); + if (template) { + return template; + } else { + throw new Error(formatMessage(`Support for runtime with name ${type} not available`)); + } + } + + // get the runtime template currently used by type + public getRuntime(type: string | undefined): RuntimeTemplate { + if (!type) { + type = DEFAULT_RUNTIME; + } + const template = this.extensions.runtimeTemplates.find((t) => t.key === type); + if (template) { + return template; + } else { + throw new Error(formatMessage(`Support for runtime type ${type} not available`)); + } + } + static async getUserFromRequest(req): Promise { return req.user || undefined; } diff --git a/Composer/packages/extensions/plugin-loader/src/types.ts b/Composer/packages/extensions/plugin-loader/src/types.ts index d6795e26a1..5d71c6a8c0 100644 --- a/Composer/packages/extensions/plugin-loader/src/types.ts +++ b/Composer/packages/extensions/plugin-loader/src/types.ts @@ -2,11 +2,9 @@ // Licensed under the MIT License. import { RequestHandler } from 'express-serve-static-core'; import { JSONSchema7 } from 'json-schema'; +import { DialogSetting } from '@bfc/shared'; import { IBotProject } from '@bfc/shared'; // TODO: this will be possible when ifilestorage is in a shared module -// import { IFileStorage } from '../../../server/src/models/storage/interface'; - -import { ComposerPluginRegistration } from './composerPluginRegistration'; export interface PublishResult { message: string; @@ -37,6 +35,7 @@ export interface BotTemplate { // TODO: Add types for project, metadata export interface PublishPlugin { + // methods plugins should support publish: (config: Config, project: IBotProject, metadata: any, user?: UserIdentity) => Promise; getStatus?: (config: Config, project: IBotProject, user?: UserIdentity) => Promise; getHistory?: (config: Config, project: IBotProject, user?: UserIdentity) => Promise; @@ -46,12 +45,45 @@ export interface PublishPlugin { rollbackToVersion: string, user?: UserIdentity ) => Promise; + + // other properties + schema?: JSONSchema7; + instructions?: string; + customName?: string; + customDescription?: string; [key: string]: any; } +export const DEFAULT_RUNTIME = 'csharp-azurewebapp'; + export interface RuntimeTemplate { /** method used to eject the runtime into a project. returns resulting path of runtime! */ - eject: (project: IBotProject, localDisk?: any) => Promise; + eject: (project: IBotProject, localDisk?: any, isReplace?: boolean) => Promise; + + /** build method used for local publish */ + build: (runtimePath: string, project: IBotProject) => Promise; + + run: (project: IBotProject, localDisk?: any) => Promise; + + /** build for deploy method */ + buildDeploy: ( + runtimePath: string, + project: IBotProject, + settings: DialogSetting, + profileName: string + ) => Promise; + + /** set skill manifest, different folder for different runtime */ + setSkillManifest: ( + dstRuntimePath: string, + dstStorage: IFileStorage, + srcManifestDir: string, + srcStorage: IFileStorage, + mode: string + ) => Promise; + + /** path to code template */ + path: string; /** internal use key */ key: string; @@ -74,12 +106,15 @@ export interface ExtensionCollection { }; publish: { [key: string]: { - plugin: ComposerPluginRegistration; + plugin: { + name: string; + description: string; + /** (Optional instructions displayed in the UI) */ + instructions?: string; + /** (Optional) Schema for publishing configuration. */ + schema?: JSONSchema7; + }; methods: PublishPlugin; - /** (Optional instructions displayed in the UI) */ - instructions?: string; - /** (Optional) Schema for publishing configuration. */ - schema?: JSONSchema7; }; }; authentication: { @@ -93,3 +128,39 @@ export interface ExtensionCollection { botTemplates: BotTemplate[]; baseTemplates: BotTemplate[]; } + +export interface FileInfo { + name: string; + content: string; + path: string; + relativePath: string; + lastModified: string; +} + +interface IFileStorage { + stat(path: string): Promise; + readFile(path: string): Promise; + readDir(path: string): Promise; + exists(path: string): Promise; + writeFile(path: string, content: any): Promise; + removeFile(path: string): Promise; + mkDir(path: string, options?: MakeDirectoryOptions): Promise; + rmDir(path: string): Promise; + rmrfDir(path: string): Promise; + glob(pattern: string | string[], path: string): Promise; + copyFile(src: string, dest: string): Promise; + rename(oldPath: string, newPath: string): Promise; + zip(source: string, cb: any): unknown; +} + +interface Stat { + isDir: boolean; + isFile: boolean; + isWritable: boolean; + lastModified: string; + size: string; +} + +interface MakeDirectoryOptions { + recursive?: boolean; +} diff --git a/Composer/packages/lib/shared/src/constant.ts b/Composer/packages/lib/shared/src/constant.ts index 1b3815561f..409e837eb7 100644 --- a/Composer/packages/lib/shared/src/constant.ts +++ b/Composer/packages/lib/shared/src/constant.ts @@ -10,6 +10,11 @@ export const FieldNames = { DefaultCase: 'default', Cases: 'cases', }; +export const defaultPublishConfig = { + name: 'default', + type: 'localpublish', + configuration: JSON.stringify({}), +}; export const LUISLocales = [ 'en-us', diff --git a/Composer/packages/lib/shared/src/types/sdk.ts b/Composer/packages/lib/shared/src/types/sdk.ts index 8846ad5eb2..9708746155 100644 --- a/Composer/packages/lib/shared/src/types/sdk.ts +++ b/Composer/packages/lib/shared/src/types/sdk.ts @@ -47,7 +47,7 @@ export interface IChoiceObject { export type IChoice = IChoiceObject[] | string; -type IListStyle = 'None' | 'Auto' | 'Inline' | 'List' | 'SuggestedAction' | 'HeroCard'; +type IListStyle = 'none' | 'auto' | 'inline' | 'list' | 'suggestedAction' | 'heroCard'; export interface IChoiceOption { /** Character used to separate individual choices when there are more than 2 choices */ diff --git a/Composer/packages/server/__tests__/controllers/eject.test.ts b/Composer/packages/server/__tests__/controllers/eject.test.ts index 1a2fe2a64a..f2f6310f16 100644 --- a/Composer/packages/server/__tests__/controllers/eject.test.ts +++ b/Composer/packages/server/__tests__/controllers/eject.test.ts @@ -52,7 +52,12 @@ beforeAll(async () => { key: 'azurewebapp', name: 'C#', startCommand: 'dotnet run --project azurewebapp', + path: './', eject: jest.fn(), + build: jest.fn(), + run: jest.fn(), + buildDeploy: jest.fn(), + setSkillManifest: jest.fn(), }); const currentProjectId = await BotProjectService.openProject(location1); const currentProject = await BotProjectService.getProjectById(currentProjectId); diff --git a/Composer/packages/server/src/controllers/eject.ts b/Composer/packages/server/src/controllers/eject.ts index af4a283511..93f750c134 100644 --- a/Composer/packages/server/src/controllers/eject.ts +++ b/Composer/packages/server/src/controllers/eject.ts @@ -19,7 +19,7 @@ export const EjectController = { if (template) { let runtimePath; try { - runtimePath = await template.eject(currentProject, new LocalDiskStorage()); + runtimePath = await template.eject(currentProject, new LocalDiskStorage(), req.body?.isReplace); // init bot project, make sure it include customize schema files await currentProject.init(); } catch (err) { @@ -31,6 +31,8 @@ export const EjectController = { res.json({ settings: { + key: template.key, + name: template.name, path: runtimePath, startCommand: template.startCommand, }, diff --git a/Composer/packages/server/src/controllers/publisher.ts b/Composer/packages/server/src/controllers/publisher.ts index 24cfd8d243..d36a05f0c0 100644 --- a/Composer/packages/server/src/controllers/publisher.ts +++ b/Composer/packages/server/src/controllers/publisher.ts @@ -1,33 +1,25 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import path from 'path'; - import merge from 'lodash/merge'; import { pluginLoader, PluginLoader } from '@bfc/plugin-loader'; +import { defaultPublishConfig } from '@bfc/shared'; import { BotProjectService } from '../services/project'; -import { runtimeFolder } from '../settings/env'; -const defaultPublishConfig = { - name: 'default', - type: 'localpublish', - configuration: JSON.stringify({}), -}; -const DEFAULT_RUNTIME = 'dotnet'; export const PublishController = { getTypes: async (req, res) => { res.json( Object.values(pluginLoader.extensions.publish) .filter((extension) => extension.plugin.name !== defaultPublishConfig.type) .map((extension) => { - const { plugin, methods, schema, instructions } = extension; + const { plugin, methods } = extension; return { name: plugin.name, description: plugin.description, - instructions: instructions, - schema, + instructions: plugin.instructions, + schema: plugin.schema, features: { history: typeof methods.history === 'function', publish: typeof methods.publish === 'function', @@ -51,14 +43,13 @@ export const PublishController = { const profiles = allTargets.filter((t) => t.name === target); const profile = profiles.length ? profiles[0] : undefined; - const method = profile ? profile.type : undefined; + const method = profile ? profile.type : undefined; // get the publish plugin key if (profile && method && pluginLoader?.extensions?.publish[method]?.methods?.publish) { // append config from client(like sensitive settings) const configuration = { profileName: profile.name, fullSettings: merge({}, currentProject.settings, sensitiveSettings), - templatePath: path.resolve(runtimeFolder, DEFAULT_RUNTIME), ...JSON.parse(profile.configuration), }; @@ -101,7 +92,7 @@ export const PublishController = { const profiles = allTargets.filter((t) => t.name === target); const profile = profiles.length ? profiles[0] : undefined; - + // get the publish plugin key const method = profile ? profile.type : undefined; if ( profile && @@ -148,7 +139,7 @@ export const PublishController = { const profiles = allTargets.filter((t) => t.name === target); const profile = profiles.length ? profiles[0] : undefined; - + // get the publish plugin key const method = profile ? profile.type : undefined; if ( @@ -192,6 +183,7 @@ export const PublishController = { const profiles = allTargets.filter((t) => t.name === target); const profile = profiles.length ? profiles[0] : undefined; + // get the publish plugin key const method = profile ? profile.type : undefined; if ( @@ -205,7 +197,6 @@ export const PublishController = { const configuration = { profileName: profile.name, fullSettings: merge({}, currentProject.settings, sensitiveSettings), - templatePath: path.resolve(runtimeFolder, DEFAULT_RUNTIME), ...JSON.parse(profile.configuration), }; // get the externally defined method @@ -243,6 +234,7 @@ export const PublishController = { const method = profile.type; if ( profile && + method && pluginLoader.extensions.publish[method] && pluginLoader.extensions.publish[method].methods && pluginLoader.extensions.publish[method].methods.stopBot @@ -283,4 +275,34 @@ export const PublishController = { message: `${method} is not a valid publishing target type. There may be a missing plugin.`, }); }, + + stopBot: async (req, res) => { + const projectId = req.params.projectId; + const profile = defaultPublishConfig; + const method = profile.type; + if ( + profile && + method && + pluginLoader.extensions.publish[method] && + pluginLoader.extensions.publish[method].methods && + pluginLoader.extensions.publish[method].methods.stopBot + ) { + const pluginMethod = pluginLoader.extensions.publish[method].methods.stopBot; + if (typeof pluginMethod === 'function') { + try { + await pluginMethod.call(null, projectId); + return res.status(200).json({ message: 'stop bot success' }); + } catch (err) { + return res.status(500).json({ + statusCode: '500', + message: err.message, + }); + } + } + } + res.status(400).json({ + statusCode: '400', + message: `${method} is not a valid publishing target type. There may be a missing plugin.`, + }); + }, }; diff --git a/Composer/packages/server/src/models/bot/botProject.ts b/Composer/packages/server/src/models/bot/botProject.ts index ca74437098..6ca23b4808 100644 --- a/Composer/packages/server/src/models/bot/botProject.ts +++ b/Composer/packages/server/src/models/bot/botProject.ts @@ -133,7 +133,7 @@ export class BotProject implements IBotProject { public init = async () => { this.diagnostics = []; this.settings = await this.getEnvSettings(false); - const { skillsParsed, diagnostics } = await extractSkillManifestUrl(this.settings?.skill || []); + const { skillsParsed, diagnostics } = await extractSkillManifestUrl(this.settings?.skill || ([] as any)); this.skills = skillsParsed; this.diagnostics.push(...diagnostics); this.files = await this._getFiles(); diff --git a/Composer/packages/server/src/models/settings/defaultSettingManager.ts b/Composer/packages/server/src/models/settings/defaultSettingManager.ts index db064cc1fc..2adeccf442 100644 --- a/Composer/packages/server/src/models/settings/defaultSettingManager.ts +++ b/Composer/packages/server/src/models/settings/defaultSettingManager.ts @@ -9,7 +9,6 @@ import { Path } from '../../utility/path'; import log from '../../logger'; import { FileSettingManager } from './fileSettingManager'; - const debug = log.extend('default-settings-manager'); export class DefaultSettingManager extends FileSettingManager { diff --git a/Composer/packages/server/src/router/api.ts b/Composer/packages/server/src/router/api.ts index 2a0f8f9877..7a75f0faf0 100644 --- a/Composer/packages/server/src/router/api.ts +++ b/Composer/packages/server/src/router/api.ts @@ -45,6 +45,7 @@ router.get('/publish/:projectId/status/:target', PublishController.status); router.post('/publish/:projectId/publish/:target', PublishController.publish); router.get('/publish/:projectId/history/:target', PublishController.history); router.post('/publish/:projectId/rollback/:target', PublishController.rollback); +router.post('/publish/:projectId/stopPublish/:target', PublishController.stopBot); router.get('/publish/:method', PublishController.publish); diff --git a/Composer/plugins/README.md b/Composer/plugins/README.md index 819bb69180..87e1971d9d 100644 --- a/Composer/plugins/README.md +++ b/Composer/plugins/README.md @@ -222,6 +222,11 @@ For middleware dealing with authentication, plugins must use `useAuthMiddleware( #### `composer.addPublishMethod(publishMechanism, schema, instructions)` +By default, the publish method will use the name and description from the package.json file. However, you may provide a customized name: +```ts +composer.addPublishMethod(publishMechanism, schema, instructions, customDisplayName, customDisplayDescription); +``` + Provide a new mechanism by which a bot project is transferred from Composer to some external service. The mechanisms can use whatever method necessary to process and transmit the bot project to the desired external service, though it must use a standard signature for the methods. In most cases, the plugin itself does NOT include the configuration information required to communicate with the external service. Configuration is provided by the Composer application at invocation time. @@ -237,12 +242,160 @@ Publishing plugins support the following features: ##### publish(config, project, metadata, user) +This method is responsible for publishing the `project` using the provided `config` using whatever method the plugin is implementing - for example, publish to Azure. This method is *required* for all publishing plugins. + +In order to publish a project, this method must perform any necessary actions such as: + +* The LUIS lubuild process +* Calling the appropriate runtime `buildDeploy` method +* Doing the actual deploy operation + + +**Parameters:** +| Parameter | Description +|-- |-- +| config | an object containing information from the publishing profile, as well as the bot's settings -- see below +| project | an object representing the bot project +| metadata | any comment passed by the user during publishing +| user | a user object if one has been provided by an authentication plugin + +Config will include: + +```ts +{ + templatePath: '/path/to/runtime/code', + fullSettings: { + // all of the bot's settings from project.settings, but also including sensitive keys managed in-app. + // this should be used instead of project.settings which may be incomplete + }, + profileName: 'name of publishing profile', + ... // All fields from the publishing profile +} +``` + +The project will include: +```ts +{ + id: 'bot id', + dataDir: '/path/to/bot/project', + files: // A map of files including the name, path and content + settings: { + // content of settings/appsettings.json + } +} +``` + +Below is an simplified implementation of this process: +```ts +const publish = async(config, project, metadata, user) => { + + const { fullSettings, profileName } = config; + + // Prepare a copy of the project to build + + // Run the lubuild process + + // Run the runtime.buildDeploy process + + // Now do the final actual deploy somehow... + +} +``` + ##### getStatus(config, project, user) +This method is used to check for the status of the most recent publish of `project` to a given publishing profile defined by the `config` field. This method is *required* for all publishing plugins. + +This endpoint uses a subset of HTTP status codes to report the status of the deploy: + +| Status | Meaning +|-- |-- +| 200 | Publish completed successfully +| 202 | Publish is underway +| 404 | No publish found +| 500 | Publish failed + +`config` will be in the form below. `config.profileName` can be used to identify the publishing profile being queried. + +```ts +{ + profileName: `name of the publishing profile`, + ... // all fields from the publishing profile +} +``` + +Should return an object in the form: + +```ts +{ + status: [200|202|404|500], + result: { + message: 'Status message to be displayed in publishing UI', + log: 'any log output from the process so far', + comment: 'the user specified comment associated with the publish', + endpointURL: 'URL to running bot for use with Emulator as appropriate', + id: 'a unique identifier of this published version', + } +} +``` + ##### getHistory(config, project, user) +This method is used to request a history of publish actions from a given `project` to a given publishing profile defined by the `config` field. This is an *optional* feature - publishing plugins may exclude this functionality if it is not supported. + +`config` will be in the form below. `config.profileName` can be used to identify the publishing profile being queried. + +```ts +{ + profileName: `name of the publishing profile`, + ... // all fields from the publishing profile +} +``` + +Should return in array containing recent publish actions along with their status and log output. + +```ts +[{ + status: [200|202|404|500], + result: { + message: 'Status message to be displayed in publishing UI', + log: 'any log output from the process so far', + comment: 'the user specified comment associated with the publish', + id: 'a unique identifier of this published version', + } +}] +``` + ##### rollback(config, project, rollbackToVersion, user) +This method is used to request a rollback _in the deployed environment_ to a previously published version. This DOES NOT affect the local version of the project. This is an *optional* feature - publishing plugins may exclude this functionality if it is not supported. + +`config` will be in the form below. `config.profileName` can be used to identify the publishing profile being queried. + +```ts +{ + profileName: `name of the publishing profile`, + ... // all fields from the publishing profile +} +``` + +`rollbackToVersion` will contain a version ID as found in the results from `getHistory`. + +Rollback should respond using the same format as `publish` or `getStatus` and should result in a new publishing task: + +```ts +{ + status: [200|202|404|500], + result: { + message: 'Status message to be displayed in publishing UI', + log: 'any log output from the process so far', + comment: 'the user specified comment associated with the publish', + endpointURL: 'URL to running bot for use with Emulator as appropriate', + id: 'a unique identifier of this published version', + } +} +``` + ### Runtime Templates #### `composer.addRuntimeTemplate(templateInfo)` @@ -254,13 +407,63 @@ to communicate with the Bot Framework Emulator. ```ts await composer.addRuntimeTemplate({ - key: 'azurewebapp', - name: 'C#', - path: __dirname + '/../../../../runtime/dotnet/azurewebapp', + key: 'myUniqueKey', + name: 'My Runtime', + path: __dirname + '/path/to/runtime/template/code', startCommand: 'dotnet run', + build: async(runtimePath, project) => { + // implement necessary actions that must happen before project can be run + }, + buildDeploy: async(runtimePath, project, settings, publishProfileName) => { + // implement necessary actions that must happen before project can be deployed to azure + + return pathToBuildArtifacts; + }, }); ``` +##### build(runtimePath, project) + +Perform any necessary steps required before the runtime can be executed from inside Composer when a user clicks the "Start Bot" button. Note this method *should not* actually start the runtime directly - only perform the build steps. + +For example, this would be used to call `dotnet build` in the runtime folder in order to build the application. + +##### buildDeploy (runtimePath, project, settings, publishProfileName) + +| parameter | description +|-- |-- +| runtimePath | the path to the runtime that needs to be built +| project | a bot project record +| settings | a full set of settings to be used by the built runtime +| publishProfileName | the name of the publishing profile that is the target of this build + +Perform any necessary steps required to prepare the runtime code to be deployed. This method should return a path to the build artifacts with the expectation that the publisher can perform a deploy of those artifacts "as is" and have them run successfully. To do this it should: + +* Perform any necessary build steps +* Install dependencies +* Write `settings` to the appropriate location and format + + +#### `composer.getRuntimeByProject(project)` + +Returns a reference to the appropriate runtime template based on the project's settings. + +```ts +// load the appropriate runtime config +const runtime = composer.getRuntimeByProject(project); + +// run the build step from the runtime, passing in the project as a parameter +await runtime.build(project.dataDir, project); +``` + +#### `composer.getRuntime(type)` + +Get a runtime template by its key. + +```ts +const dotnetRuntime = composer.getRuntime('csharp-azurewebapp'); +``` + ### Bot Project Templates Add a project template to the list available during the bot creation process. Plugins can bundle arbitrary bundle of content that will be copied into the bot project at create time. The template should contain a functioning bot project, along with any specializations and configuration defaults required to successfully run the project. diff --git a/Composer/plugins/azureFunctionsPublish/.gitignore b/Composer/plugins/azureFunctionsPublish/.gitignore deleted file mode 100644 index 70cf140132..0000000000 --- a/Composer/plugins/azureFunctionsPublish/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules -lib -publishHistory.txt -publishBots -cred.txt -provisionResult.json \ No newline at end of file diff --git a/Composer/plugins/azureFunctionsPublish/package.json b/Composer/plugins/azureFunctionsPublish/package.json deleted file mode 100644 index ce6954a0b1..0000000000 --- a/Composer/plugins/azureFunctionsPublish/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "azureFunctionsPublish", - "version": "1.0.0", - "description": "Publish bot to an Azure Functions (Preview)", - "main": "lib/index.js", - "license": "MIT", - "scripts": { - "build": "tsc" - }, - "extendsComposer": true, - "dependencies": { - "@azure/arm-resources": "2.1.0", - "@azure/ms-rest-nodeauth": "3.0.3", - "@bfc/botframeworkdeploy": "*", - "@bfc/plugin-loader": "../packages/extensions/plugin-loader", - "@types/archiver": "3.1.0", - "@types/fs-extra": "8.1.0", - "@types/request": "2.48.4", - "@types/request-promise": "4.1.45", - "adal-node": "0.2.1", - "md5": "2.2.1", - "minimist": "1.2.5", - "uuid": "7.0.3" - } -} diff --git a/Composer/plugins/azureFunctionsPublish/src/index.ts b/Composer/plugins/azureFunctionsPublish/src/index.ts deleted file mode 100644 index 76fc8cb46d..0000000000 --- a/Composer/plugins/azureFunctionsPublish/src/index.ts +++ /dev/null @@ -1,364 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import path from 'path'; - -import { BotProjectDeploy } from '@bfc/botframeworkdeploy'; -import { v4 as uuid } from 'uuid'; -import md5 from 'md5'; -import { copy, rmdir, emptyDir, readJson, pathExists, writeJson, mkdirSync, writeFileSync } from 'fs-extra'; -import { IBotProject } from '@bfc/shared'; - -import schema from './schema'; - -// This option controls whether the history is serialized to a file between sessions with Composer -// set to TRUE for history to be saved to disk -// set to FALSE for history to be cached in memory only -const PERSIST_HISTORY = false; -const DEFAULT_RUNTIME = 'azurefunctions'; - -const instructions = `To create a publish configuration, follow the instructions in the README file in your bot project folder.`; - -interface CreateAndDeployResources { - name: string; - environment: string; - hostname?: string; - luisResource?: string; - language?: string; - subscriptionID: string; -} - -interface PublishConfig { - fullSettings: any; - templatePath: string; - profileName: string; //profile name - [key: string]: any; -} - -class AzurePublisher { - private publishingBots: { [key: string]: any }; - private historyFilePath: string; - private histories: any; - private azDeployer: BotProjectDeploy; - private logMessages: any[]; - constructor() { - this.histories = {}; - this.historyFilePath = path.resolve(__dirname, '../publishHistory.txt'); - if (PERSIST_HISTORY) { - this.loadHistoryFromFile(); - } - this.publishingBots = {}; - this.logMessages = []; - } - - private baseRuntimeFolder = process.env.AZURE_PUBLISH_PATH || path.resolve(__dirname, `publishBots`); - - private getRuntimeFolder = (key: string) => { - return path.resolve(this.baseRuntimeFolder, `${key}`); - }; - private getProjectFolder = (key: string, template: string) => { - return path.resolve(this.baseRuntimeFolder, `${key}/${template}`); - }; - - private getBotFolder = (key: string, template: string) => - path.resolve(this.getProjectFolder(key, template), 'ComposerDialogs'); - private getSettingsPath = (key: string, template: string) => - path.resolve(this.getBotFolder(key, template), 'settings/appsettings.json'); - - private init = async (botFiles: any, settings: any, srcTemplate: string, resourcekey: string) => { - const runtimeExist = await pathExists(this.getRuntimeFolder(resourcekey)); - const botExist = await pathExists(this.getBotFolder(resourcekey, DEFAULT_RUNTIME)); - const botFolder = this.getBotFolder(resourcekey, DEFAULT_RUNTIME); - const runtimeFolder = this.getRuntimeFolder(resourcekey); - const settingsPath = this.getSettingsPath(resourcekey, DEFAULT_RUNTIME); - - // deploy resource exist - await emptyDir(runtimeFolder); - if (!runtimeExist) { - mkdirSync(runtimeFolder, { recursive: true }); - } - if (!botExist) { - mkdirSync(botFolder, { recursive: true }); - } - // save bot files - for (const file of botFiles) { - const filePath = path.resolve(botFolder, file.relativePath); - if (!(await pathExists(path.dirname(filePath)))) { - mkdirSync(path.dirname(filePath), { recursive: true }); - } - writeFileSync(filePath, file.content); - } - - // save the settings file - if (!(await pathExists(path.dirname(settingsPath)))) { - mkdirSync(path.dirname(settingsPath), { recursive: true }); - } - await writeJson(settingsPath, settings, { spaces: 4 }); - // copy bot and runtime into projFolder - await copy(srcTemplate, runtimeFolder); - }; - - private async cleanup(resourcekey: string) { - const projFolder = this.getRuntimeFolder(resourcekey); - await emptyDir(projFolder); - await rmdir(projFolder); - } - - private async loadHistoryFromFile() { - if (await pathExists(this.historyFilePath)) { - this.histories = await readJson(this.historyFilePath); - } - } - - private getHistory = async (botId: string, profileName: string) => { - if (this.histories && this.histories[botId] && this.histories[botId][profileName]) { - return this.histories[botId][profileName]; - } - return []; - }; - - private updateHistory = async (botId: string, profileName: string, newHistory: any) => { - if (!this.histories[botId]) { - this.histories[botId] = {}; - } - if (!this.histories[botId][profileName]) { - this.histories[botId][profileName] = []; - } - this.histories[botId][profileName].unshift(newHistory); - if (PERSIST_HISTORY) { - await writeJson(this.historyFilePath, this.histories); - } - }; - - private addLoadingStatus = (botId: string, profileName: string, newStatus) => { - // save in publishingBots - if (!this.publishingBots[botId]) { - this.publishingBots[botId] = {}; - } - if (!this.publishingBots[botId][profileName]) { - this.publishingBots[botId][profileName] = []; - } - this.publishingBots[botId][profileName].push(newStatus); - }; - private removeLoadingStatus = (botId: string, profileName: string, jobId: string) => { - if (this.publishingBots[botId] && this.publishingBots[botId][profileName]) { - const index = this.publishingBots[botId][profileName].findIndex((item) => item.result.id === jobId); - const status = this.publishingBots[botId][profileName][index]; - this.publishingBots[botId][profileName] = this.publishingBots[botId][profileName] - .slice(0, index) - .concat(this.publishingBots[botId][profileName].slice(index + 1)); - return status; - } - return; - }; - private getLoadingStatus = (botId: string, profileName: string, jobId = '') => { - if (this.publishingBots[botId] && this.publishingBots[botId][profileName].length > 0) { - // get current status - if (jobId) { - return this.publishingBots[botId][profileName].find((item) => item.result.id === jobId); - } - return this.publishingBots[botId][profileName][this.publishingBots[botId][profileName].length - 1]; - } - return undefined; - }; - - private createAndDeploy = async ( - botId: string, - profileName: string, - jobId: string, - resourcekey: string, - customizeConfiguration: CreateAndDeployResources - ) => { - const { name, environment, hostname, luisResource, language } = customizeConfiguration; - try { - // Perform the deploy - await this.azDeployer.deploy(name, environment, null, null, null, language, hostname, luisResource); - - // update status and history - const status = this.getLoadingStatus(botId, profileName, jobId); - - if (status) { - status.status = 200; - status.result.message = 'Success'; - status.result.log = this.logMessages.join('\n'); - await this.updateHistory(botId, profileName, { status: status.status, ...status.result }); - this.removeLoadingStatus(botId, profileName, jobId); - await this.cleanup(resourcekey); - } - } catch (error) { - console.log(error); - // update status and history - const status = this.getLoadingStatus(botId, profileName, jobId); - if (status) { - status.status = 500; - status.result.message = error ? error.message : 'publish error'; - status.result.log = this.logMessages.join('\n'); - await this.updateHistory(botId, profileName, { status: status.status, ...status.result }); - this.removeLoadingStatus(botId, profileName, jobId); - await this.cleanup(resourcekey); - } - } - }; - - /************************************************************************************************** - * plugin methods - *************************************************************************************************/ - publish = async (config: PublishConfig, project: IBotProject, metadata, user) => { - // templatePath point to the dotnet code - const { - fullSettings, - templatePath, - profileName, - subscriptionID, - name, - environment, - hostname, - luisResource, - language, - settings, - accessToken, - } = config; - - // point to the declarative assets (possibly in remote storage) - const botFiles = project.getProject().files; - - // get the bot id from the project - const botId = project.id; - - // generate an id to track this deploy - const jobId = uuid(); - - // resource key to map to one provision resource - const resourcekey = md5([project.name, name, environment, settings?.MicrosoftAppPassword].join()); - - // If the project is using an "ejected" runtime, use that version of the code instead of the built-in template - let runtimeCodePath = templatePath; - if ( - project.settings && - project.settings.runtime && - project.settings.runtime.customRuntime === true && - project.settings.runtime.path - ) { - runtimeCodePath = project.settings.runtime.path; - } - - await this.init(botFiles, fullSettings, runtimeCodePath, resourcekey); - - try { - // test creds, if not valid, return 500 - if (!accessToken) { - throw new Error('Required field `accessToken` is missing from publishing profile.'); - } - if (!settings) { - throw new Error( - 'no successful created resource in Azure according to your config, please run provision script included in your bot project.' - ); - } - - const customizeConfiguration: CreateAndDeployResources = { - subscriptionID, - name, - environment, - hostname, - luisResource, - language, - }; - - // append provision resource into file - // TODO: here is where we configure the template for the runtime, and should be parameterized when we - // implement interchangeable runtimes - const resourcePath = path.resolve( - this.getProjectFolder(resourcekey, DEFAULT_RUNTIME), - 'appsettings.deployment.json' - ); - const appSettings = await readJson(resourcePath); - await writeJson( - resourcePath, - { ...appSettings, ...settings }, - { - spaces: 4, - } - ); - - this.azDeployer = new BotProjectDeploy({ - subId: subscriptionID, - logger: (msg: any) => { - console.log(msg); - this.logMessages.push(JSON.stringify(msg, null, 2)); - }, - accessToken: accessToken, - projPath: this.getProjectFolder(resourcekey, DEFAULT_RUNTIME), - dotnetProjectPath: path.join( - this.getProjectFolder(resourcekey, DEFAULT_RUNTIME), - 'Microsoft.BotFramework.Composer.Functions.csproj' - ), - }); - - this.logMessages = ['Publish starting...']; - const response = { - status: 202, - result: { - id: jobId, - time: new Date(), - message: 'Accepted for publishing.', - log: this.logMessages.join('\n'), - comment: metadata.comment, - }, - }; - this.addLoadingStatus(botId, profileName, response); - - this.createAndDeploy(botId, profileName, jobId, resourcekey, customizeConfiguration); - - return response; - } catch (err) { - console.log(err); - this.logMessages.push(err.message); - const response = { - status: 500, - result: { - id: jobId, - time: new Date(), - message: 'Publish Fail', - log: this.logMessages.join('\n'), - comment: metadata.comment, - }, - }; - this.updateHistory(botId, profileName, { status: response.status, ...response.result }); - this.cleanup(resourcekey); - return response; - } - }; - - getStatus = async (config: PublishConfig, project: IBotProject, user) => { - const profileName = config.profileName; - const botId = project.id; - // return latest status - const status = this.getLoadingStatus(botId, profileName); - if (status) { - return status; - } else { - const current = await this.getHistory(botId, profileName); - if (current.length > 0) { - return { status: current[0].status, result: { ...current[0] } }; - } - return { - status: 404, - result: { - message: 'bot not published', - }, - }; - } - }; - - history = async (config: PublishConfig, project: IBotProject, user) => { - const profileName = config.profileName; - const botId = project.id; - return await this.getHistory(botId, profileName); - }; -} - -const azurePublish = new AzurePublisher(); - -export default async (composer: any): Promise => { - await composer.addPublishMethod(azurePublish, schema, instructions); -}; diff --git a/Composer/plugins/azureFunctionsPublish/src/schema.ts b/Composer/plugins/azureFunctionsPublish/src/schema.ts deleted file mode 100644 index 717ff5aa16..0000000000 --- a/Composer/plugins/azureFunctionsPublish/src/schema.ts +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -import { JSONSchema7 } from '@bfc/plugin-loader'; -const schema: JSONSchema7 = { - type: 'object', - properties: { - accessToken: { - type: 'string', - }, - name: { - type: 'string', - title: 'name', - }, - environment: { - type: 'string', - title: 'Environment', - }, - hostname: { - type: 'string', - title: 'Custom functions hostname (if not -)', - }, - luisResource: { - type: 'string', - title: 'Custom luis resource name ( if not --luis)', - }, - language: { - type: 'string', - title: 'Language for luis - default to en-us', - }, - settings: { - type: 'object', - title: 'Settings for Azure resources', - properties: { - applicationInsights: { - type: 'object', - properties: { - InstrumentationKey: { - type: 'string', - }, - }, - }, - cosmosDb: { - type: 'object', - properties: { - cosmosDBEndpoint: { - type: 'string', - }, - authKey: { - type: 'string', - }, - databaseId: { - type: 'string', - }, - collectionId: { - type: 'string', - }, - containerId: { - type: 'string', - }, - }, - required: ['cosmosDBEndpoint', 'authKey', 'databaseId', 'collectionId', 'containerId'], - }, - blobStorage: { - type: 'object', - properties: { - connectionString: { - type: 'string', - }, - container: { - type: 'string', - }, - }, - required: ['connectionString', 'container'], - }, - luis: { - type: 'object', - properties: { - endpoint: { - type: 'string', - }, - authoringEndpoint: { - type: 'string', - }, - endpointKey: { - type: 'string', - }, - authoringKey: { - type: 'string', - }, - region: { - type: 'string', - }, - }, - required: ['endpointKey', 'authoringKey', 'region'], - }, - MicrosoftAppId: { - type: 'string', - }, - MicrosoftAppPassword: { - type: 'string', - }, - }, - required: ['MicrosoftAppId', 'MicrosoftAppPassword'], - }, - }, - required: ['subscriptionID', 'publishName', 'provision', 'accessToken'], - default: { - accessToken: '', - name: '', - environment: 'dev', - settings: { - applicationInsights: { - InstrumentationKey: '', - }, - cosmosDb: { - cosmosDBEndpoint: '', - authKey: '', - databaseId: 'botstate-db', - collectionId: 'botstate-collection', - containerId: 'botstate-container', - }, - blobStorage: { - connectionString: '', - container: '', - }, - luis: { - authoringKey: '', - authoringEndpoint: '', - endpointKey: '', - endpoint: '', - region: 'westus', - }, - MicrosoftAppId: '', - MicrosoftAppPassword: '', - }, - }, -}; -export default schema; diff --git a/Composer/plugins/azurePublish/.gitignore b/Composer/plugins/azurePublish/.gitignore index 70cf140132..991f0dbd4b 100644 --- a/Composer/plugins/azurePublish/.gitignore +++ b/Composer/plugins/azurePublish/.gitignore @@ -3,4 +3,5 @@ lib publishHistory.txt publishBots cred.txt -provisionResult.json \ No newline at end of file +provisionResult.json + diff --git a/Composer/plugins/azurePublish/package.json b/Composer/plugins/azurePublish/package.json index 3ddadc2a73..48575a89e8 100644 --- a/Composer/plugins/azurePublish/package.json +++ b/Composer/plugins/azurePublish/package.json @@ -9,17 +9,30 @@ }, "extendsComposer": true, "dependencies": { + "@azure/arm-appinsights": "2.1.0", + "@azure/arm-appservice-profile-2019-03-01-hybrid": "1.0.0", + "@azure/arm-botservice": "1.0.0", + "@azure/arm-deploymentmanager": "3.0.0", "@azure/arm-resources": "2.1.0", + "@azure/arm-subscriptions": "2.0.0", + "@azure/cognitiveservices-luis-authoring": "4.0.0-preview.1", + "@azure/graph": "5.0.1", + "@azure/ms-rest-browserauth": "0.1.4", "@azure/ms-rest-nodeauth": "3.0.3", - "@bfc/botframeworkdeploy": "*", - "@bfc/plugin-loader": "../packages/extensions/plugin-loader", + "@microsoft/bf-lu": "^4.10.0-dev.20200728.930f45e", + "@microsoft/bf-luis-cli": "^4.10.0-dev.20200721.8bb21ac", "@types/archiver": "3.1.0", "@types/fs-extra": "8.1.0", "@types/request": "2.48.4", "@types/request-promise": "4.1.45", "adal-node": "0.2.1", + "archiver": "3.1.1", + "fs-extra": "8.1.0", + "lodash": "^4.17.20", "md5": "2.2.1", "minimist": "1.2.5", + "request": "2.88.2", + "request-promise": "4.2.5", "uuid": "7.0.3" } } diff --git a/Composer/plugins/lib/bot-deploy/src/botProjectDeployConfig.ts b/Composer/plugins/azurePublish/src/botProjectDeployConfig.ts similarity index 85% rename from Composer/plugins/lib/bot-deploy/src/botProjectDeployConfig.ts rename to Composer/plugins/azurePublish/src/botProjectDeployConfig.ts index b83b91dc76..082613e093 100644 --- a/Composer/plugins/lib/bot-deploy/src/botProjectDeployConfig.ts +++ b/Composer/plugins/azurePublish/src/botProjectDeployConfig.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import { BotProjectRuntimeType } from './botProjectRuntimeType'; + export interface BotProjectDeployConfig { // Subscription Id of Azure Account subId: string; @@ -17,9 +19,6 @@ export interface BotProjectDeployConfig { // Logger logger: (string) => any; - // Deployment settings file path - deploymentSettingsPath?: string; - // Deploy file path, default is .deployment file deployFilePath?: string; @@ -29,9 +28,6 @@ export interface BotProjectDeployConfig { // Publishing folder for 'dotnet publish' command, default is 'bin/Release/netcoreapp3.1' publishFolder?: string; - // The deployment settings file path, default is 'appsettings.deployment.json' - settingsPath?: string; - // The ARM template file path, default is 'DeploymentTemplates/template-with-preexisting-rg.json' templatePath?: string; @@ -44,5 +40,8 @@ export interface BotProjectDeployConfig { // Remote bot json dialog path, default is 'ComposerDialogs' remoteBotPath?: string; + // Runtime Type for botproject + runtimeType?: BotProjectRuntimeType; + [key: string]: any; } diff --git a/Composer/plugins/lib/bot-deploy/src/botProjectLoggerType.ts b/Composer/plugins/azurePublish/src/botProjectLoggerType.ts similarity index 100% rename from Composer/plugins/lib/bot-deploy/src/botProjectLoggerType.ts rename to Composer/plugins/azurePublish/src/botProjectLoggerType.ts diff --git a/Composer/plugins/azurePublish/src/botProjectRuntimeType.ts b/Composer/plugins/azurePublish/src/botProjectRuntimeType.ts new file mode 100644 index 0000000000..7caf0d547e --- /dev/null +++ b/Composer/plugins/azurePublish/src/botProjectRuntimeType.ts @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +export enum BotProjectRuntimeType { + CSHARP = 'CSHARP', + NODE = 'NODE', +} diff --git a/Composer/plugins/azurePublish/src/deploy.ts b/Composer/plugins/azurePublish/src/deploy.ts new file mode 100644 index 0000000000..4609409754 --- /dev/null +++ b/Composer/plugins/azurePublish/src/deploy.ts @@ -0,0 +1,177 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import * as path from 'path'; + +import * as fs from 'fs-extra'; +import * as rp from 'request-promise'; + +import { BotProjectDeployConfig } from './botProjectDeployConfig'; +import { BotProjectDeployLoggerType } from './botProjectLoggerType'; +import { LuisPublish } from './luis'; +import archiver = require('archiver'); + +export class BotProjectDeploy { + private accessToken: string; + private projPath: string; + private zipPath: string; + private logger: (string) => any; + private runtime: any; + + constructor(config: BotProjectDeployConfig) { + this.logger = config.logger; + this.accessToken = config.accessToken; + this.projPath = config.projPath; + // get the appropriate runtime + this.runtime = config.runtime; + + // path to the zipped assets + this.zipPath = config.zipPath ?? path.join(this.projPath, 'code.zip'); + } + + /*******************************************************************************************************************************/ + /* This section has to do with deploying to existing Azure resources + /*******************************************************************************************************************************/ + + /** + * Deploy a bot to a location + */ + public async deploy( + project: any, + settings: any, + profileName: string, + name: string, + environment: string, + language?: string, + hostname?: string, + luisResource?: string + ) { + try { + // STEP 1: CLEAN UP PREVIOUS BUILDS + // cleanup any previous build + if (await fs.pathExists(this.zipPath)) { + await fs.remove(this.zipPath); + } + + // STEP 2: UPDATE LUIS + // Do the LUIS build if LUIS settings are present + if (settings.luis) { + const luisAuthoringKey = settings.luis.authoringKey; + const luisAuthoringRegion = settings.luis.authoringRegion || settings.luis.region; + + if (luisAuthoringKey && luisAuthoringRegion) { + if (!language) { + language = 'en-us'; + } + const luis = new LuisPublish({ logger: this.logger }); + + // this function returns an object that contains the luis APP ids mapping + // each dialog to its matching app. + const luisAppIDs = await luis.publishLuis( + this.projPath, + name, + environment, + this.accessToken, + language, + settings.luis, + luisResource + ); + + // amend luis settings with newly generated values + settings.luis = { + ...settings.luis, + ...luisAppIDs, + }; + } + } + + // STEP 3: BUILD + // run any platform specific build steps. + // this returns a pathToArtifacts where the deployable version lives. + const pathToArtifacts = await this.runtime.buildDeploy(this.projPath, project, settings, profileName); + + // STEP 4: ZIP THE ASSETS + // Build a zip file of the project + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Packing up the bot service ...', + }); + await this.zipDirectory(pathToArtifacts, this.zipPath); + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Packing Service Success!', + }); + + // STEP 5: DEPLOY THE ZIP FILE TO AZURE + // Deploy the zip file to the web app + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Publishing to Azure ...', + }); + await this.deployZip(this.accessToken, this.zipPath, name, environment, hostname); + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_SUCCESS, + message: 'Publish To Azure Success!', + }); + } catch (error) { + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_ERROR, + message: JSON.stringify(error, Object.getOwnPropertyNames(error)), + }); + throw error; + } + } + + private async zipDirectory(source: string, out: string) { + const archive = archiver('zip', { zlib: { level: 9 } }); + const stream = fs.createWriteStream(out); + + return new Promise((resolve, reject) => { + archive + .glob('**/*', { + cwd: source, + dot: true, + ignore: ['**/code.zip', 'node_modules/**/*'], + }) + .on('error', (err) => reject(err)) + .pipe(stream); + + stream.on('close', () => resolve()); + archive.finalize(); + }); + } + + // Upload the zip file to Azure + // DOCS HERE: https://docs.microsoft.com/en-us/azure/app-service/deploy-zip + private async deployZip(token: string, zipPath: string, name: string, env: string, hostname?: string) { + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Retrieve publishing details ...', + }); + + const publishEndpoint = `https://${ + hostname ? hostname : name + '-' + env + }.scm.azurewebsites.net/zipdeploy/?isAsync=true`; + try { + const response = await rp.post({ + uri: publishEndpoint, + auth: { + bearer: token, + }, + body: fs.createReadStream(zipPath), + }); + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: response, + }); + } catch (err) { + if (err.statusCode === 403) { + throw new Error( + `Token expired, please run az account get-access-token, then replace the accessToken in your configuration` + ); + } else { + throw err; + } + } + } +} diff --git a/Composer/plugins/azurePublish/src/index.ts b/Composer/plugins/azurePublish/src/index.ts index d1d2180d12..cae3e56f0e 100644 --- a/Composer/plugins/azurePublish/src/index.ts +++ b/Composer/plugins/azurePublish/src/index.ts @@ -3,24 +3,28 @@ import path from 'path'; -import { BotProjectDeploy } from '@bfc/botframeworkdeploy'; import { v4 as uuid } from 'uuid'; import md5 from 'md5'; import { copy, rmdir, emptyDir, readJson, pathExists, writeJson, mkdirSync, writeFileSync } from 'fs-extra'; import { IBotProject } from '@bfc/shared'; +import { JSONSchema7 } from '@bfc/plugin-loader'; +import { Debugger } from 'debug'; +import { mergeDeep } from './mergeDeep'; +import { BotProjectDeploy } from './deploy'; import schema from './schema'; + // This option controls whether the history is serialized to a file between sessions with Composer // set to TRUE for history to be saved to disk // set to FALSE for history to be cached in memory only const PERSIST_HISTORY = false; -const DEFAULT_RUNTIME = 'azurewebapp'; const instructions = `To create a publish configuration, follow the instructions in the README file in your bot project folder.`; interface CreateAndDeployResources { name: string; environment: string; + accessToken: string; hostname?: string; luisResource?: string; subscriptionID: string; @@ -29,251 +33,329 @@ interface CreateAndDeployResources { interface PublishConfig { fullSettings: any; - templatePath: string; profileName: string; //profile name [key: string]: any; } -class AzurePublisher { - private publishingBots: { [key: string]: any }; - private historyFilePath: string; - private histories: any; - private azDeployer: BotProjectDeploy; - private logMessages: any[]; - constructor() { - this.histories = {}; - this.historyFilePath = path.resolve(__dirname, '../publishHistory.txt'); - if (PERSIST_HISTORY) { - this.loadHistoryFromFile(); - } - this.publishingBots = {}; - this.logMessages = []; - } - - private baseRuntimeFolder = process.env.AZURE_PUBLISH_PATH || path.resolve(__dirname, `publishBots`); - - private getRuntimeFolder = (key: string) => { - return path.resolve(this.baseRuntimeFolder, `${key}`); - }; - private getProjectFolder = (key: string, template: string) => { - return path.resolve(this.baseRuntimeFolder, `${key}/${template}`); - }; - private getBotFolder = (key: string, template: string) => - path.resolve(this.getProjectFolder(key, template), 'ComposerDialogs'); - private getSettingsPath = (key: string, template: string) => - path.resolve(this.getBotFolder(key, template), 'settings/appsettings.json'); - private getManifestDstDir = (key: string, template: string) => - path.resolve(this.getProjectFolder(key, template), 'wwwroot'); - - private init = async (botFiles: any, settings: any, srcTemplate: string, resourcekey: string) => { - const runtimeExist = await pathExists(this.getRuntimeFolder(resourcekey)); - const botExist = await pathExists(this.getBotFolder(resourcekey, DEFAULT_RUNTIME)); - const botFolder = this.getBotFolder(resourcekey, DEFAULT_RUNTIME); - const runtimeFolder = this.getRuntimeFolder(resourcekey); - const settingsPath = this.getSettingsPath(resourcekey, DEFAULT_RUNTIME); - const manifestPath = this.getManifestDstDir(resourcekey, DEFAULT_RUNTIME); - // deploy resource exist - await emptyDir(runtimeFolder); - if (!runtimeExist) { - mkdirSync(runtimeFolder, { recursive: true }); - } - if (!botExist) { - mkdirSync(botFolder, { recursive: true }); - } - // save bot files and manifest files - for (const file of botFiles) { - const pattern = /manifests\/[0-9A-z-]*.json/; - let filePath; - if (file.relativePath.match(pattern)) { - // save manifest files into wwwroot - filePath = path.resolve(manifestPath, file.relativePath); - } else { - // save bot files - filePath = path.resolve(botFolder, file.relativePath); - } - if (!(await pathExists(path.dirname(filePath)))) { - mkdirSync(path.dirname(filePath), { recursive: true }); +// Wrap the entire class definition in the export so the composer object can be available to it +export default async (composer: any): Promise => { + class AzurePublisher { + private publishingBots: { [key: string]: any }; + private historyFilePath: string; + private histories: any; + private logMessages: any[]; + private mode: string; + public schema: JSONSchema7; + public instructions: string; + public customName: string; + public customDescription: string; + public logger: Debugger; + + constructor(mode?: string, customName?: string, customDescription?: string) { + this.histories = {}; + this.historyFilePath = path.resolve(__dirname, '../publishHistory.txt'); + if (PERSIST_HISTORY) { + this.loadHistoryFromFile(); } - writeFileSync(filePath, file.content); + this.publishingBots = {}; + this.logMessages = []; + this.mode = mode || 'azurewebapp'; + this.schema = schema; + this.instructions = instructions; + this.customName = customName; + this.customDescription = customDescription; + this.logger = composer.log; } - // save the settings file - if (!(await pathExists(path.dirname(settingsPath)))) { - mkdirSync(path.dirname(settingsPath), { recursive: true }); - } - await writeJson(settingsPath, settings, { spaces: 4 }); - // copy bot and runtime into projFolder - await copy(srcTemplate, runtimeFolder); - }; - - private async cleanup(resourcekey: string) { - const projFolder = this.getRuntimeFolder(resourcekey); - await emptyDir(projFolder); - await rmdir(projFolder); - } + private baseRuntimeFolder = process.env.AZURE_PUBLISH_PATH || path.resolve(__dirname, `../publishBots`); - private async loadHistoryFromFile() { - if (await pathExists(this.historyFilePath)) { - this.histories = await readJson(this.historyFilePath); - } - } + /*******************************************************************************************************************************/ + /* These methods generate all the necessary paths to various files */ + /*******************************************************************************************************************************/ - private getHistory = async (botId: string, profileName: string) => { - if (this.histories && this.histories[botId] && this.histories[botId][profileName]) { - return this.histories[botId][profileName]; - } - return []; - }; + // path to working folder containing all the assets + private getRuntimeFolder = (key: string) => { + return path.resolve(this.baseRuntimeFolder, `${key}`); + }; - private updateHistory = async (botId: string, profileName: string, newHistory: any) => { - if (!this.histories[botId]) { - this.histories[botId] = {}; - } - if (!this.histories[botId][profileName]) { - this.histories[botId][profileName] = []; - } - this.histories[botId][profileName].unshift(newHistory); - if (PERSIST_HISTORY) { - await writeJson(this.historyFilePath, this.histories); - } - }; + // path to the runtime code inside the working folder + private getProjectFolder = (key: string, template: string) => { + return path.resolve(this.baseRuntimeFolder, `${key}/${template}`); + }; - private addLoadingStatus = (botId: string, profileName: string, newStatus) => { - // save in publishingBots - if (!this.publishingBots[botId]) { - this.publishingBots[botId] = {}; - } - if (!this.publishingBots[botId][profileName]) { - this.publishingBots[botId][profileName] = []; - } - this.publishingBots[botId][profileName].push(newStatus); - }; - private removeLoadingStatus = (botId: string, profileName: string, jobId: string) => { - if (this.publishingBots[botId] && this.publishingBots[botId][profileName]) { - const index = this.publishingBots[botId][profileName].findIndex((item) => item.result.id === jobId); - const status = this.publishingBots[botId][profileName][index]; - this.publishingBots[botId][profileName] = this.publishingBots[botId][profileName] - .slice(0, index) - .concat(this.publishingBots[botId][profileName].slice(index + 1)); - return status; - } - return; - }; - private getLoadingStatus = (botId: string, profileName: string, jobId = '') => { - if (this.publishingBots[botId] && this.publishingBots[botId][profileName].length > 0) { - // get current status - if (jobId) { - return this.publishingBots[botId][profileName].find((item) => item.result.id === jobId); + // path to the declarative assets + private getBotFolder = (key: string, template: string) => + path.resolve(this.getProjectFolder(key, template), 'ComposerDialogs'); + + /*******************************************************************************************************************************/ + /* These methods deal with the publishing history displayed in the Composer UI */ + /*******************************************************************************************************************************/ + private async loadHistoryFromFile() { + if (await pathExists(this.historyFilePath)) { + this.histories = await readJson(this.historyFilePath); } - return this.publishingBots[botId][profileName][this.publishingBots[botId][profileName].length - 1]; } - return undefined; - }; - - private createAndDeploy = async ( - botId: string, - profileName: string, - jobId: string, - resourcekey: string, - customizeConfiguration: CreateAndDeployResources - ) => { - const { name, environment, hostname, luisResource, language } = customizeConfiguration; - try { - // Perform the deploy - await this.azDeployer.deploy(name, environment, null, null, null, language, hostname, luisResource); - - // update status and history - const status = this.getLoadingStatus(botId, profileName, jobId); - if (status) { - status.status = 200; - status.result.message = 'Success'; - status.result.log = this.logMessages.join('\n'); - await this.updateHistory(botId, profileName, { status: status.status, ...status.result }); - this.removeLoadingStatus(botId, profileName, jobId); - await this.cleanup(resourcekey); + private getHistory = async (botId: string, profileName: string) => { + if (this.histories && this.histories[botId] && this.histories[botId][profileName]) { + return this.histories[botId][profileName]; } - } catch (error) { - console.log(error); - if (error instanceof Error) { - this.logMessages.push(error.message); - } else if (typeof error === 'object') { - this.logMessages.push(JSON.stringify(error)); - } else { - this.logMessages.push(error); + return []; + }; + + private updateHistory = async (botId: string, profileName: string, newHistory: any) => { + if (!this.histories[botId]) { + this.histories[botId] = {}; } - // update status and history - const status = this.getLoadingStatus(botId, profileName, jobId); - if (status) { - status.status = 500; - status.result.message = this.logMessages[this.logMessages.length - 1]; - status.result.log = this.logMessages.join('\n'); - await this.updateHistory(botId, profileName, { status: status.status, ...status.result }); - this.removeLoadingStatus(botId, profileName, jobId); - await this.cleanup(resourcekey); + if (!this.histories[botId][profileName]) { + this.histories[botId][profileName] = []; } - } - }; - - /************************************************************************************************** - * plugin methods - *************************************************************************************************/ - publish = async (config: PublishConfig, project: IBotProject, metadata, user) => { - // templatePath point to the dotnet code - const { - // these are provided by Composer - fullSettings, - templatePath, - profileName, - - // these are specific to the azure publish profile shape - subscriptionID, - name, - environment, - hostname, - luisResource, - language, - settings, - accessToken, - } = config; - - // point to the declarative assets (possibly in remote storage) - const botFiles = project.getProject().files; - - // get the bot id from the project - const botId = project.id; - - // generate an id to track this deploy - const jobId = uuid(); - - // resource key to map to one provision resource - const resourcekey = md5([project.name, name, environment, settings?.MicrosoftAppPassword].join()); - - // If the project is using an "ejected" runtime, use that version of the code instead of the built-in template - let runtimeCodePath = templatePath; - if ( - project.settings && - project.settings.runtime && - project.settings.runtime.customRuntime === true && - project.settings.runtime.path - ) { - runtimeCodePath = project.settings.runtime.path; + this.histories[botId][profileName].unshift(newHistory); + if (PERSIST_HISTORY) { + await writeJson(this.historyFilePath, this.histories); + } + }; + + /*******************************************************************************************************************************/ + /* These methods implement the publish actions */ + /*******************************************************************************************************************************/ + /** + * Prepare a bot to be built and deployed by copying the runtime and declarative assets into a temporary folder + * @param project + * @param settings + * @param srcTemplate + * @param resourcekey + */ + private init = async (project: any, srcTemplate: string, resourcekey: string, runtime: any) => { + // point to the declarative assets (possibly in remote storage) + const botFiles = project.getProject().files; + const botFolder = this.getBotFolder(resourcekey, this.mode); + const runtimeFolder = this.getRuntimeFolder(resourcekey); + + // clean up from any previous deploys + await this.cleanup(resourcekey); + + // create the temporary folder to contain this project + mkdirSync(runtimeFolder, { recursive: true }); + + // create the ComposerDialogs/ folder + mkdirSync(botFolder, { recursive: true }); + + let manifestPath; + for (const file of botFiles) { + const pattern = /manifests\/[0-9A-z-]*.json/; + if (file.relativePath.match(pattern)) { + manifestPath = path.dirname(file.path); + } + // save bot files + const filePath = path.resolve(botFolder, file.relativePath); + if (!(await pathExists(path.dirname(filePath)))) { + mkdirSync(path.dirname(filePath), { recursive: true }); + } + writeFileSync(filePath, file.content); + } + + // save manifest + runtime.setSkillManifest(runtimeFolder, project.fileStorage, manifestPath, project.fileStorage, this.mode); + + // copy bot and runtime into projFolder + await copy(srcTemplate, runtimeFolder); + }; + + /** + * Remove any previous version of a project's working files + * @param resourcekey + */ + private async cleanup(resourcekey: string) { + const projFolder = this.getRuntimeFolder(resourcekey); + await emptyDir(projFolder); + await rmdir(projFolder); } - await this.init(botFiles, fullSettings, runtimeCodePath, resourcekey); + /** + * Take the project from a given folder, build it, and push it to Azure. + * @param project + * @param runtime + * @param botId + * @param profileName + * @param jobId + * @param resourcekey + * @param customizeConfiguration + */ + private performDeploymentAction = async ( + project: IBotProject, + settings: any, + runtime: any, + botId: string, + profileName: string, + jobId: string, + resourcekey: string, + customizeConfiguration: CreateAndDeployResources + ) => { + const { + subscriptionID, + accessToken, + name, + environment, + hostname, + luisResource, + language, + } = customizeConfiguration; + try { + // Create the BotProjectDeploy object, which is used to carry out the deploy action. + const azDeployer = new BotProjectDeploy({ + subId: subscriptionID, // deprecate - not used + logger: (msg: any) => { + this.logger(msg); + this.logMessages.push(JSON.stringify(msg, null, 2)); + + // update the log messages provided to Composer via the status API. + const status = this.getLoadingStatus(botId, profileName, jobId); + status.result.log = this.logMessages.join('\n'); + + this.updateLoadingStatus(botId, profileName, jobId, status); + }, + accessToken: accessToken, + projPath: this.getProjectFolder(resourcekey, this.mode), + runtime: runtime, + }); + + // Perform the deploy + await azDeployer.deploy(project, settings, profileName, name, environment, language, hostname, luisResource); + + // update status and history + const status = this.getLoadingStatus(botId, profileName, jobId); + + if (status) { + status.status = 200; + status.result.message = 'Success'; + status.result.log = this.logMessages.join('\n'); + await this.updateHistory(botId, profileName, { status: status.status, ...status.result }); + this.removeLoadingStatus(botId, profileName, jobId); + await this.cleanup(resourcekey); + } + } catch (error) { + this.logger(error); + console.error(error); + if (error instanceof Error) { + this.logMessages.push(error.message); + } else if (typeof error === 'object') { + this.logMessages.push(JSON.stringify(error)); + } else { + this.logMessages.push(error); + } + // update status and history + const status = this.getLoadingStatus(botId, profileName, jobId); + if (status) { + status.status = 500; + status.result.message = this.logMessages[this.logMessages.length - 1]; + status.result.log = this.logMessages.join('\n'); + await this.updateHistory(botId, profileName, { status: status.status, ...status.result }); + this.removeLoadingStatus(botId, profileName, jobId); + await this.cleanup(resourcekey); + } + } + }; - try { - // test creds, if not valid, return 500 - if (!accessToken) { - throw new Error('Required field `accessToken` is missing from publishing profile.'); + /*******************************************************************************************************************************/ + /* These methods help to track the process of the deploy and provide info to Composer */ + /*******************************************************************************************************************************/ + + private addLoadingStatus = (botId: string, profileName: string, newStatus) => { + // save in publishingBots + if (!this.publishingBots[botId]) { + this.publishingBots[botId] = {}; + } + if (!this.publishingBots[botId][profileName]) { + this.publishingBots[botId][profileName] = []; } - if (!settings) { - throw new Error( - 'no successful created resource in Azure according to your config, please run provision script included in your bot project.' - ); + this.publishingBots[botId][profileName].push(newStatus); + }; + + private removeLoadingStatus = (botId: string, profileName: string, jobId: string) => { + if (this.publishingBots[botId] && this.publishingBots[botId][profileName]) { + const index = this.publishingBots[botId][profileName].findIndex((item) => item.result.id === jobId); + const status = this.publishingBots[botId][profileName][index]; + this.publishingBots[botId][profileName] = this.publishingBots[botId][profileName] + .slice(0, index) + .concat(this.publishingBots[botId][profileName].slice(index + 1)); + return status; } + return; + }; + + private getLoadingStatus = (botId: string, profileName: string, jobId = '') => { + if (this.publishingBots[botId] && this.publishingBots[botId][profileName].length > 0) { + // get current status + if (jobId) { + return this.publishingBots[botId][profileName].find((item) => item.result.id === jobId); + } + return this.publishingBots[botId][profileName][this.publishingBots[botId][profileName].length - 1]; + } + return undefined; + }; + + private updateLoadingStatus = (botId: string, profileName: string, jobId = '', newStatus) => { + if (this.publishingBots[botId] && this.publishingBots[botId][profileName].length > 0) { + // get current status + if (jobId) { + for (let x = 0; x < this.publishingBots[botId][profileName].length; x++) { + if (this.publishingBots[botId][profileName][x].result.id === jobId) { + this.publishingBots[botId][profileName][x] = newStatus; + } + } + } else { + this.publishingBots[botId][profileName][this.publishingBots[botId][profileName].length - 1] = newStatus; + } + } + }; + + // move the init folder and publsih together and not wait in publish method. because init folder take a long time + private asyncPublish = async (config: PublishConfig, project, resourcekey, jobId) => { + const { + // these are provided by Composer + fullSettings, // all the bot's settings - includes sensitive values not included in projet.settings + profileName, // the name of the publishing profile "My Azure Prod Slot" + + // these are specific to the azure publish profile shape + subscriptionID, + name, + environment, + hostname, + luisResource, + language, + settings, + accessToken, + } = config; + + // get the appropriate runtime template which contains methods to build and configure the runtime + const runtime = composer.getRuntimeByProject(project); + // set runtime code path as runtime template folder path + let runtimeCodePath = runtime.path; + + // If the project is using an "ejected" runtime, use that version of the code instead of the built-in template + // TODO: this templatePath should come from the runtime instead of this magic parameter + if ( + project.settings && + project.settings.runtime && + project.settings.runtime.customRuntime === true && + project.settings.runtime.path + ) { + runtimeCodePath = project.settings.runtime.path; + } + + // Prepare the temporary project + // this writes all the settings to the root settings/appsettings.json file + await this.init(project, runtimeCodePath, resourcekey, runtime); + + // Merge all the settings + // this combines the bot-wide settings, the environment specific settings, and 2 new fields needed for deployed bots + // these will be written to the appropriate settings file inside the appropriate runtime plugin. + const mergedSettings = mergeDeep(fullSettings, settings); + // Prepare parameters and then perform the actual deployment action const customizeConfiguration: CreateAndDeployResources = { + accessToken, subscriptionID, name, environment, @@ -281,34 +363,45 @@ class AzurePublisher { luisResource, language, }; - - // append provision resource into file - // TODO: here is where we configure the template for the runtime, and should be parameterized when we - // implement interchangeable runtimes - const resourcePath = path.resolve( - this.getProjectFolder(resourcekey, DEFAULT_RUNTIME), - 'appsettings.deployment.json' - ); - const appSettings = await readJson(resourcePath); - await writeJson( - resourcePath, - { ...appSettings, ...settings }, - { - spaces: 4, - } + await this.performDeploymentAction( + project, + mergedSettings, + runtime, + project.id, + profileName, + jobId, + resourcekey, + customizeConfiguration ); + }; - this.azDeployer = new BotProjectDeploy({ - subId: subscriptionID, - logger: (msg: any) => { - console.log(msg); - this.logMessages.push(JSON.stringify(msg, null, 2)); - }, - accessToken: accessToken, - projPath: this.getProjectFolder(resourcekey, 'azurewebapp'), - }); + /************************************************************************************************** + * plugin methods + *************************************************************************************************/ + publish = async (config: PublishConfig, project: IBotProject, metadata, user) => { + const { + // these are provided by Composer + profileName, // the name of the publishing profile "My Azure Prod Slot" + + // these are specific to the azure publish profile shape + name, + environment, + settings, + accessToken, + } = config; + // get the bot id from the project + const botId = project.id; + + // generate an id to track this deploy + const jobId = uuid(); + + // resource key to map to one provision resource + const resourcekey = md5([project.name, name, environment].join()); + + // Initialize the output logs... this.logMessages = ['Publish starting...']; + // Add first "in process" log message const response = { status: 202, result: { @@ -321,64 +414,72 @@ class AzurePublisher { }; this.addLoadingStatus(botId, profileName, response); - this.createAndDeploy(botId, profileName, jobId, resourcekey, customizeConfiguration); + try { + // test creds, if not valid, return 500 + if (!accessToken) { + throw new Error('Required field `accessToken` is missing from publishing profile.'); + } + if (!settings) { + throw new Error('Required field `settings` is missing from publishing profile.'); + } - return response; - } catch (err) { - console.log(err); - if (err instanceof Error) { - this.logMessages.push(err.message); - } else if (typeof err === 'object') { - this.logMessages.push(JSON.stringify(err)); - } else { - this.logMessages.push(err); + this.asyncPublish(config, project, resourcekey, jobId); + } catch (err) { + console.log(err); + if (err instanceof Error) { + this.logMessages.push(err.message); + } else if (typeof err === 'object') { + this.logMessages.push(JSON.stringify(err)); + } else { + this.logMessages.push(err); + } + + response.status = 500; + response.result.message = this.logMessages[this.logMessages.length - 1]; + + await this.updateHistory(botId, profileName, { status: response.status, ...response.result }); + this.removeLoadingStatus(botId, profileName, jobId); + this.cleanup(resourcekey); } - const response = { - status: 500, - result: { - id: jobId, - time: new Date(), - message: this.logMessages[this.logMessages.length - 1], - log: this.logMessages.join('\n'), - comment: metadata.comment, - }, - }; - this.updateHistory(botId, profileName, { status: response.status, ...response.result }); - this.cleanup(resourcekey); + return response; - } - }; - - getStatus = async (config: PublishConfig, project: IBotProject, user) => { - const profileName = config.profileName; - const botId = project.id; - // return latest status - const status = this.getLoadingStatus(botId, profileName); - if (status) { - return status; - } else { - const current = await this.getHistory(botId, profileName); - if (current.length > 0) { - return { status: current[0].status, result: { ...current[0] } }; + }; + + getStatus = async (config: PublishConfig, project: IBotProject, user) => { + const profileName = config.profileName; + const botId = project.id; + // return latest status + const status = this.getLoadingStatus(botId, profileName); + if (status) { + return status; + } else { + const current = await this.getHistory(botId, profileName); + if (current.length > 0) { + return { status: current[0].status, result: { ...current[0] } }; + } + return { + status: 404, + result: { + message: 'bot not published', + }, + }; } - return { - status: 404, - result: { - message: 'bot not published', - }, - }; - } - }; + }; - history = async (config: PublishConfig, project: IBotProject, user) => { - const profileName = config.profileName; - const botId = project.id; - return await this.getHistory(botId, profileName); - }; -} + history = async (config: PublishConfig, project: IBotProject, user) => { + const profileName = config.profileName; + const botId = project.id; + return await this.getHistory(botId, profileName); + }; + } -const azurePublish = new AzurePublisher(); + const azurePublish = new AzurePublisher(); + const azureFunctionsPublish = new AzurePublisher( + 'azurefunctions', + 'azureFunctionsPublish', + 'Publish bot to Azure Functions (Preview)' + ); -export default async (composer: any): Promise => { - await composer.addPublishMethod(azurePublish, schema, instructions); + await composer.addPublishMethod(azurePublish); + await composer.addPublishMethod(azureFunctionsPublish); }; diff --git a/Composer/plugins/azurePublish/src/luis.ts b/Composer/plugins/azurePublish/src/luis.ts new file mode 100644 index 0000000000..4c85aa3573 --- /dev/null +++ b/Composer/plugins/azurePublish/src/luis.ts @@ -0,0 +1,227 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import * as path from 'path'; +import { promisify } from 'util'; + +import * as fs from 'fs-extra'; +import * as rp from 'request-promise'; +import { ILuisConfig } from '@bfc/shared'; + +import { BotProjectDeployLoggerType } from './botProjectLoggerType'; + +const luBuild = require('@microsoft/bf-lu/lib/parser/lubuild/builder.js'); +const readdir: any = promisify(fs.readdir); + +export interface LuisPublishConfig { + // Logger + logger: (string) => any; + [key: string]: any; +} + +export class LuisPublish { + private logger: (string) => any; + + constructor(config: LuisPublishConfig) { + this.logger = config.logger; + } + + /*******************************************************************************************************************************/ + /* This section has to do with publishing LU files to LUIS + /*******************************************************************************************************************************/ + + /** + * return an array of all the files in a given directory + * @param dir + */ + private async getFiles(dir: string): Promise { + const dirents = await readdir(dir, { withFileTypes: true }); + const files = await Promise.all( + dirents.map((dirent) => { + const res = path.resolve(dir, dirent.name); + return dirent.isDirectory() ? this.getFiles(res) : res; + }) + ); + return Array.prototype.concat(...files); + } + + private notEmptyLuisModel(file: string) { + return fs.readFileSync(file).length > 0; + } + + /** + * Helper function to get the appropriate account out of a list of accounts + * @param accounts + * @param filter + */ + private getAccount(accounts: any, filter: string) { + for (const account of accounts) { + if (account.AccountName === filter) { + return account; + } + } + } + + // Run through the lubuild process + // This happens in the build folder, NOT in the original source folder + public async publishLuis( + workingFolder: string, + name: string, + environment: string, + accessToken: string, + language: string, + luisSettings: ILuisConfig, + luisResource?: string + ) { + const { authoringKey: luisAuthoringKey, authoringRegion: luisAuthoringRegion } = luisSettings; + let { endpoint: luisEndpoint, authoringEndpoint: luisAuthoringEndpoint } = luisSettings; + + if (luisAuthoringKey && luisAuthoringRegion) { + // Get a list of all the .lu files that are not empty + const botFiles = await this.getFiles(workingFolder); + const modelFiles = botFiles.filter((name) => { + return name.endsWith('.lu') && this.notEmptyLuisModel(name); + }); + + // Identify the generated folder + const generatedFolder = path.join(workingFolder, 'ComposerDialogs/generated'); + + // Identify the deployment settings file + // const deploymentSettingsPath = path.join(workingFolder, 'appsettings.deployment.json'); + + // Ensure the generated folder exists + if (!(await fs.pathExists(generatedFolder))) { + await fs.mkdir(generatedFolder); + } + + // Instantiate the LuBuild object from the LU parsing library + // This object is responsible for parsing the LU files and sending them to LUIS + const builder = new luBuild.Builder((msg) => + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: msg, + }) + ); + + // Pass in the list of the non-empty LU files we got above... + const loadResult = await builder.loadContents( + modelFiles, + language || 'en-us', + environment || '', + luisAuthoringRegion || '' + ); + + // set the default endpoint + if (!luisEndpoint) { + luisEndpoint = `https://${luisAuthoringRegion}.api.cognitive.microsoft.com`; + } + + // if not specified, set the authoring endpoint + if (!luisAuthoringEndpoint) { + luisAuthoringEndpoint = luisEndpoint; + } + + // Perform the Lubuild process + // This will create new luis apps for each of the luis models represented in the LU files + const buildResult = await builder.build( + loadResult.luContents, + loadResult.recognizers, + luisAuthoringKey, + luisAuthoringEndpoint, + name, + environment, + language, + true, + false, + loadResult.multiRecognizers, + loadResult.settings + ); + + // Write the generated files to the generated folder + await builder.writeDialogAssets(buildResult, true, generatedFolder); + + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: `lubuild succeed`, + }); + + // Find any files that contain the name 'luis.settings' in them + // These are generated by the LuBuild process and placed in the generated folder + // These contain dialog-to-luis app id mapping + const luisConfigFiles = (await this.getFiles(workingFolder)).filter((filename) => + filename.includes('luis.settings') + ); + const luisAppIds: any = {}; + + // Read in all the luis app id mappings + for (const luisConfigFile of luisConfigFiles) { + const luisSettings = await fs.readJson(luisConfigFile); + Object.assign(luisAppIds, luisSettings.luis); + } + + // In order for the bot to use the LUIS models, we need to assign a LUIS key to the endpoint of each app + // First step is to get a list of all the accounts available based on the given luisAuthoringKey. + let accountList; + try { + // Make a call to the azureaccounts api + // DOCS HERE: https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5be313cec181ae720aa2b26c + // This returns a list of azure account information objects with AzureSubscriptionID, ResourceGroup, AccountName for each. + const getAccountUri = `${luisEndpoint}/luis/api/v2.0/azureaccounts`; + const options = { + headers: { Authorization: `Bearer ${accessToken}`, 'Ocp-Apim-Subscription-Key': luisAuthoringKey }, + } as rp.RequestPromiseOptions; + const response = await rp.get(getAccountUri, options); + + // this should include an array of account info objects + accountList = JSON.parse(response); + } catch (err) { + // handle the token invalid + const error = JSON.parse(err.error); + if (error?.error?.message && error?.error?.message.indexOf('access token expiry') > 0) { + throw new Error( + `Type: ${error?.error?.code}, Message: ${error?.error?.message}, run az account get-access-token, then replace the accessToken in your configuration` + ); + } else { + throw err; + } + } + // Extract the accoutn object that matches the expected resource name. + // This is the name that would appear in the azure portal associated with the luis endpoint key. + const account = this.getAccount(accountList, luisResource ? luisResource : `${name}-${environment}-luis`); + + // Assign the appropriate account to each of the applicable LUIS apps for this bot. + // DOCS HERE: https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5be32228e8473de116325515 + for (const dialogKey in luisAppIds) { + const luisAppId = luisAppIds[dialogKey]; + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: `Assigning to luis app id: ${luisAppId}`, + }); + + const luisAssignEndpoint = `${luisEndpoint}/luis/api/v2.0/apps/${luisAppId}/azureaccounts`; + const options = { + body: account, + json: true, + headers: { Authorization: `Bearer ${accessToken}`, 'Ocp-Apim-Subscription-Key': luisAuthoringKey }, + } as rp.RequestPromiseOptions; + const response = await rp.post(luisAssignEndpoint, options); + + // TODO: Add some error handling on this API call. As it is, errors will just throw by default and be caught by the catch all try/catch in the deploy method + + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: response, + }); + } + + // The process has now completed. + this.logger({ + status: BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Luis Publish Success! ...', + }); + + // return the new settings that need to be added to the main settings file. + return luisAppIds; + } + } +} diff --git a/Composer/plugins/azurePublish/src/mergeDeep.ts b/Composer/plugins/azurePublish/src/mergeDeep.ts new file mode 100644 index 0000000000..46afc796e3 --- /dev/null +++ b/Composer/plugins/azurePublish/src/mergeDeep.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/** + * Originally found on Stack Overflow: + * https://stackoverflow.com/questions/27936772/how-to-deep-merge-instead-of-shallow-merge * + */ + +/** + * Simple object check. + * @param item + * @returns {boolean} + */ +export function isObject(item) { + return item && typeof item === 'object' && !Array.isArray(item); +} + +export function mergeDeep(target, ...sources) { + if (!sources.length) return target; + const source = sources.shift(); + + if (isObject(target) && isObject(source)) { + for (const key in source) { + if (isObject(source[key])) { + if (!target[key]) Object.assign(target, { [key]: {} }); + mergeDeep(target[key], source[key]); + } else { + Object.assign(target, { [key]: source[key] }); + } + } + } + + return mergeDeep(target, ...sources); +} diff --git a/Composer/plugins/lib/bot-deploy/src/botProjectDeploy.ts b/Composer/plugins/azurePublish/src/provision.ts similarity index 59% rename from Composer/plugins/lib/bot-deploy/src/botProjectDeploy.ts rename to Composer/plugins/azurePublish/src/provision.ts index 9d7b297f91..72ce6a9a24 100644 --- a/Composer/plugins/lib/bot-deploy/src/botProjectDeploy.ts +++ b/Composer/plugins/azurePublish/src/provision.ts @@ -2,7 +2,6 @@ // Licensed under the MIT License. import * as path from 'path'; -import * as util from 'util'; import { ResourceManagementClient } from '@azure/arm-resources'; import { ApplicationInsightsManagementClient } from '@azure/arm-appinsights'; @@ -21,28 +20,13 @@ import * as rp from 'request-promise'; import { BotProjectDeployConfig } from './botProjectDeployConfig'; import { BotProjectDeployLoggerType } from './botProjectLoggerType'; -import archiver = require('archiver'); -const exec = util.promisify(require('child_process').exec); -const { promisify } = require('util'); - -const luBuild = require('@microsoft/bf-lu/lib/parser/lubuild/builder.js'); -const readdir = promisify(fs.readdir); - -export class BotProjectDeploy { +export class BotProjectProvision { private subId: string; private accessToken: string; private creds: any; // credential from interactive login private projPath: string; - private deploymentSettingsPath: string; - private deployFilePath: string; - private zipPath: string; - private publishFolder: string; - private settingsPath: string; private templatePath: string; - private dotnetProjectPath: string; - private generatedFolder: string; - private remoteBotPath: string; private logger: (string) => any; // Will be assigned by create or deploy @@ -55,36 +39,41 @@ export class BotProjectDeploy { this.creds = config.creds; this.projPath = config.projPath; - // set path to .deployment file which points at the BotProject.csproj - this.deployFilePath = config.deployFilePath ?? path.join(this.projPath, '.deployment'); - - // path to the zipped assets - this.zipPath = config.zipPath ?? path.join(this.projPath, 'code.zip'); - - // path to the built, ready to deploy code assets - this.publishFolder = config.publishFolder ?? path.join(this.projPath, 'bin', 'Release', 'netcoreapp3.1'); - - // path to the source appsettings.deployment.json file - this.settingsPath = config.settingsPath ?? path.join(this.projPath, 'appsettings.deployment.json'); - - // path to the deployed settings file that contains additional luis information - this.deploymentSettingsPath = - config.deploymentSettingsPath ?? path.join(this.publishFolder, 'appsettings.deployment.json'); - // path to the ARM template // this is currently expected to live in the code project this.templatePath = config.templatePath ?? path.join(this.projPath, 'DeploymentTemplates', 'template-with-preexisting-rg.json'); + } - // path to the dotnet project file - this.dotnetProjectPath = - config.dotnetProjectPath ?? path.join(this.projPath, 'Microsoft.BotFramework.Composer.WebApp.csproj'); + /*******************************************************************************************************************************/ + /* This section has to do with creating new Azure resources + /*******************************************************************************************************************************/ - // path to the built, ready to deploy declarative assets - this.remoteBotPath = config.remoteBotPath ?? path.join(this.publishFolder, 'ComposerDialogs'); + /** + * Write updated settings back to the settings file + */ + private async updateDeploymentJsonFile( + client: ResourceManagementClient, + resourceGroupName: string, + deployName: string, + appId: string, + appPwd: string + ): Promise { + const outputs = await client.deployments.get(resourceGroupName, deployName); + if (outputs?.properties?.outputs) { + const outputResult = outputs.properties.outputs; + const applicationResult = { + MicrosoftAppId: appId, + MicrosoftAppPassword: appPwd, + }; + const outputObj = this.unpackObject(outputResult); - // path to the ready to deploy generated folder - this.generatedFolder = config.generatedFolder ?? path.join(this.remoteBotPath, 'generated'); + const result = {}; + Object.assign(result, outputObj, applicationResult); + return result; + } else { + return null; + } } private getErrorMesssage(err) { @@ -114,34 +103,6 @@ export class BotProjectDeploy { }; } - /** - * For more information about this api, please refer to this doc: https://docs.microsoft.com/en-us/rest/api/resources/Tenants/List - */ - private async getTenantId() { - if (!this.accessToken) { - throw new Error( - 'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token' - ); - } - if (!this.subId) { - throw new Error(`Error: Missing subscription Id. Please provide a valid Azure subscription id.`); - } - try { - const tenantUrl = `https://management.azure.com/subscriptions/${this.subId}?api-version=2020-01-01`; - const options = { - headers: { Authorization: `Bearer ${this.accessToken}` }, - } as rp.RequestPromiseOptions; - const response = await rp.get(tenantUrl, options); - const jsonRes = JSON.parse(response); - if (jsonRes.tenantId === undefined) { - throw new Error(`No tenants found in the account.`); - } - return jsonRes.tenantId; - } catch (err) { - throw new Error(`Get Tenant Id Failed, details: ${this.getErrorMesssage(err)}`); - } - } - private unpackObject(output: any) { const unpacked: any = {}; for (const key in output) { @@ -284,368 +245,30 @@ export class BotProjectDeploy { } /** - * Write updated settings back to the settings file - */ - private async updateDeploymentJsonFile( - client: ResourceManagementClient, - resourceGroupName: string, - deployName: string, - appId: string, - appPwd: string - ): Promise { - const outputs = await client.deployments.get(resourceGroupName, deployName); - if (outputs?.properties?.outputs) { - const outputResult = outputs.properties.outputs; - const applicationResult = { - MicrosoftAppId: appId, - MicrosoftAppPassword: appPwd, - }; - const outputObj = this.unpackObject(outputResult); - - const result = {}; - Object.assign(result, outputObj, applicationResult); - return result; - } else { - return null; - } - } - - private async getFiles(dir: string): Promise { - const dirents = await readdir(dir, { withFileTypes: true }); - const files = await Promise.all( - dirents.map((dirent) => { - const res = path.resolve(dir, dirent.name); - return dirent.isDirectory() ? this.getFiles(res) : res; - }) - ); - return Array.prototype.concat(...files); - } - - private async botPrepareDeploy(pathToDeploymentFile: string) { - return new Promise((resolve, reject) => { - const data = `[config]\nproject = Microsoft.BotFramework.Composer.WebApp.csproj`; - fs.writeFile(pathToDeploymentFile, data, (err) => { - if (err) { - reject(err); - } - resolve(); - }); - }); - } - - private async dotnetPublish(publishFolder: string, projFolder: string, botPath?: string) { - // perform the dotnet publish command - // this builds the app and prepares it to be deployed - // results in a built copy in publishFolder/ - await exec(`dotnet publish "${this.dotnetProjectPath}" -c release -o "${publishFolder}" -v q`); - const remoteBotPath = path.join(publishFolder, 'ComposerDialogs'); - const localBotPath = path.join(projFolder, 'ComposerDialogs'); - // Then, copy the declarative assets into the build folder. - if (botPath) { - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: `Publishing dialogs from external bot project: ${botPath}`, - }); - await fs.copy(botPath, remoteBotPath, { - overwrite: true, - recursive: true, - }); - } else { - await fs.copy(localBotPath, remoteBotPath, { - overwrite: true, - recursive: true, - }); - } - } - - private async zipDirectory(source: string, out: string) { - const archive = archiver('zip', { zlib: { level: 9 } }); - const stream = fs.createWriteStream(out); - - return new Promise((resolve, reject) => { - archive - .directory(source, false) - .on('error', (err) => reject(err)) - .pipe(stream); - - stream.on('close', () => resolve()); - archive.finalize(); - }); - } - - private notEmptyLuisModel(file: string) { - return fs.readFileSync(file).length > 0; - } - - // Run through the lubuild process - // This happens in the build folder, NOT in the original source folder - private async publishLuis( - name: string, - environment: string, - language: string, - luisEndpoint: string, - luisAuthoringEndpoint: string, - luisEndpointKey: string, - luisAuthoringKey?: string, - luisAuthoringRegion?: string, - luisResource?: string - ) { - if (luisAuthoringKey && luisAuthoringRegion) { - // publishing luis - const botFiles = await this.getFiles(this.remoteBotPath); - const modelFiles = botFiles.filter((name) => { - return name.endsWith('.lu') && this.notEmptyLuisModel(name); - }); - - if (!(await fs.pathExists(this.generatedFolder))) { - await fs.mkdir(this.generatedFolder); - } - const builder = new luBuild.Builder((msg) => - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: msg, - }) - ); - - const loadResult = await builder.loadContents( - modelFiles, - language || '', - environment || '', - luisAuthoringRegion || '' - ); - - if (!luisEndpoint) { - luisEndpoint = `https://${luisAuthoringRegion}.api.cognitive.microsoft.com`; - } - - if (!luisAuthoringEndpoint) { - luisAuthoringEndpoint = luisEndpoint; - } - - const buildResult = await builder.build( - loadResult.luContents, - loadResult.recognizers, - luisAuthoringKey, - luisAuthoringEndpoint, - name, - environment, - language, - true, - false, - loadResult.multiRecognizers, - loadResult.settings - ); - await builder.writeDialogAssets(buildResult, true, this.generatedFolder); - - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: `lubuild succeed`, - }); - - const luisConfigFiles = (await this.getFiles(this.remoteBotPath)).filter((filename) => - filename.includes('luis.settings') - ); - const luisAppIds: any = {}; - - for (const luisConfigFile of luisConfigFiles) { - const luisSettings = await fs.readJson(luisConfigFile); - Object.assign(luisAppIds, luisSettings.luis); - } - - const luisConfig: any = { - endpoint: luisEndpoint, - endpointKey: luisEndpointKey, - authoringRegion: luisAuthoringRegion, - authoringKey: luisAuthoringRegion, - }; - - Object.assign(luisConfig, luisAppIds); - - // Update deploymentSettings with the luis config - const settings: any = await fs.readJson(this.deploymentSettingsPath); - settings.luis = luisConfig; - - await fs.writeJson(this.deploymentSettingsPath, settings, { - spaces: 4, - }); - - let jsonRes; - try { - // Assign a LUIS key to the endpoint of each app - const getAccountUri = `${luisEndpoint}/luis/api/v2.0/azureaccounts`; - const options = { - headers: { Authorization: `Bearer ${this.accessToken}`, 'Ocp-Apim-Subscription-Key': luisAuthoringKey }, - } as rp.RequestPromiseOptions; - const response = await rp.get(getAccountUri, options); - jsonRes = JSON.parse(response); - } catch (err) { - // handle the token invalid - const error = JSON.parse(err.error); - if (error?.error?.message && error?.error?.message.indexOf('access token expiry') > 0) { - throw new Error( - `Type: ${error?.error?.code}, Message: ${error?.error?.message}, run az account get-access-token, then replace the accessToken in your configuration` - ); - } else { - throw err; - } - } - const account = this.getAccount(jsonRes, luisResource ? luisResource : `${name}-${environment}-luis`); - - for (const k in luisAppIds) { - const luisAppId = luisAppIds[k]; - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: `Assigning to luis app id: ${luisAppId}`, - }); - - const luisAssignEndpoint = `${luisEndpoint}/luis/api/v2.0/apps/${luisAppId}/azureaccounts`; - const options = { - body: account, - json: true, - headers: { Authorization: `Bearer ${this.accessToken}`, 'Ocp-Apim-Subscription-Key': luisAuthoringKey }, - } as rp.RequestPromiseOptions; - const response = await rp.post(luisAssignEndpoint, options); - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: response, - }); - } - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: 'Luis Publish Success! ...', - }); - } - } - /** - * Deploy a bot to a location + * For more information about this api, please refer to this doc: https://docs.microsoft.com/en-us/rest/api/resources/Tenants/List */ - public async deploy( - name: string, - environment: string, - luisAuthoringKey?: string, - luisAuthoringRegion?: string, - botPath?: string, - language?: string, - hostname?: string, - luisResource?: string - ) { - try { - // Check for existing deployment files - if (!fs.pathExistsSync(this.deployFilePath)) { - await this.botPrepareDeploy(this.deployFilePath); - } - - if (await fs.pathExists(this.zipPath)) { - await fs.remove(this.zipPath); - } - - // dotnet publish - await this.dotnetPublish(this.publishFolder, this.projPath, botPath); - - // LUIS build - const settings = await fs.readJSON(this.settingsPath); - const luisSettings = settings.luis; - - let luisEndpointKey = ''; - let luisEndpoint = ''; - let luisAuthoringEndpoint = ''; - - if (luisSettings) { - // if luisAuthoringKey is not set, use the one from the luis settings - luisAuthoringKey = luisAuthoringKey || luisSettings.authoringKey; - luisAuthoringRegion = luisAuthoringRegion || luisSettings.region; - luisEndpointKey = luisSettings.endpointKey; - luisEndpoint = luisSettings.endpoint; - luisAuthoringEndpoint = luisSettings.authoringEndpoint; - } - - if (!language) { - language = 'en-us'; - } - - await this.publishLuis( - name, - environment, - language, - luisEndpoint, - luisAuthoringEndpoint, - luisEndpointKey, - luisAuthoringKey, - luisAuthoringRegion, - luisResource + private async getTenantId() { + if (!this.accessToken) { + throw new Error( + 'Error: Missing access token. Please provide a non-expired Azure access token. Tokens can be obtained by running az account get-access-token' ); - - // Build a zip file of the project - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: 'Packing up the bot service ...', - }); - await this.zipDirectory(this.publishFolder, this.zipPath); - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: 'Packing Service Success!', - }); - - // Deploy the zip file to the web app - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: 'Publishing to Azure ...', - }); - - await this.deployZip(this.accessToken, this.zipPath, name, environment, hostname); - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_SUCCESS, - message: 'Publish To Azure Success!', - }); - } catch (error) { - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_ERROR, - message: JSON.stringify(error, Object.getOwnPropertyNames(error)), - }); - throw error; } - } - - private getAccount(accounts: any, filter: string) { - for (const account of accounts) { - if (account.AccountName === filter) { - return account; - } + if (!this.subId) { + throw new Error(`Error: Missing subscription Id. Please provide a valid Azure subscription id.`); } - } - - // Upload the zip file to Azure - private async deployZip(token: string, zipPath: string, name: string, env: string, hostname?: string) { - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: 'Retrieve publishing details ...', - }); - - const publishEndpoint = `https://${hostname ? hostname : name + '-' + env}.scm.azurewebsites.net/zipdeploy`; - const fileContent = await fs.readFile(zipPath); - const options = { - body: fileContent, - encoding: null, - headers: { - Authorization: `Bearer ${token}`, - 'Content-Type': 'application/zip', - 'Content-Length': fileContent.length, - }, - } as rp.RequestPromiseOptions; try { - const response = await rp.post(publishEndpoint, options); - this.logger({ - status: BotProjectDeployLoggerType.DEPLOY_INFO, - message: response, - }); - } catch (err) { - if (err.statusCode === 403) { - throw new Error( - `Token expired, please run az account get-access-token, then replace the accessToken in your configuration` - ); - } else { - throw err; + const tenantUrl = `https://management.azure.com/subscriptions/${this.subId}?api-version=2020-01-01`; + const options = { + headers: { Authorization: `Bearer ${this.accessToken}` }, + } as rp.RequestPromiseOptions; + const response = await rp.get(tenantUrl, options); + const jsonRes = JSON.parse(response); + if (jsonRes.tenantId === undefined) { + throw new Error(`No tenants found in the account.`); } + return jsonRes.tenantId; + } catch (err) { + throw new Error(`Get Tenant Id Failed, details: ${this.getErrorMesssage(err)}`); } } @@ -678,10 +301,7 @@ export class BotProjectDeploy { baseUri: 'https://graph.windows.net', }); - let settings: any = {}; - if (fs.existsSync(this.settingsPath)) { - settings = await fs.readJson(this.settingsPath); - } + const settings: any = {}; // Validate settings let appId = settings.MicrosoftAppId; @@ -940,20 +560,4 @@ export class BotProjectDeploy { }); return updateResult; } - - /** - * createAndDeploy - * provision the Azure resources AND deploy a bot to those resources - */ - public async createAndDeploy( - name: string, - location: string, - environment: string, - appPassword: string, - luisAuthoringKey?: string, - luisAuthoringRegion?: string - ) { - await this.create(name, location, environment, appPassword); - await this.deploy(name, environment, luisAuthoringKey, luisAuthoringRegion); - } } diff --git a/Composer/plugins/azurePublish/src/schema.ts b/Composer/plugins/azurePublish/src/schema.ts index c1f7421e62..fbcbec0207 100644 --- a/Composer/plugins/azurePublish/src/schema.ts +++ b/Composer/plugins/azurePublish/src/schema.ts @@ -125,9 +125,9 @@ const schema: JSONSchema7 = { }, luis: { authoringKey: '', - authoringEndpoint: '', + authoringEndpoint: '', endpointKey: '', - endpoint: '', + endpoint: '', region: 'westus', }, MicrosoftAppId: '', diff --git a/Composer/plugins/yarn.lock b/Composer/plugins/azurePublish/yarn.lock similarity index 92% rename from Composer/plugins/yarn.lock rename to Composer/plugins/azurePublish/yarn.lock index 4739afba37..c258b0d25d 100644 --- a/Composer/plugins/yarn.lock +++ b/Composer/plugins/azurePublish/yarn.lock @@ -2,43 +2,43 @@ # yarn lockfile v1 -"@azure/arm-appinsights@^2.1.0": +"@azure/arm-appinsights@2.1.0": version "2.1.0" - resolved "https://registry.yarnpkg.com/@azure/arm-appinsights/-/arm-appinsights-2.1.0.tgz#a14238e5fa1e0ae949d6f65d49020459116f16fd" - integrity sha512-wfJgzoz/ZdLpT9TsKtpjWWsKmqQ7BkseEmKrm6gPcrQeINjzpgqex29suhS+Jmq1f4i2ZEofQKA1YHhBknrcsA== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-appinsights/-/@azure/arm-appinsights-2.1.0.tgz#a14238e5fa1e0ae949d6f65d49020459116f16fd" + integrity sha1-oUI45foeCulJ1vZdSQIEWRFvFv0= dependencies: "@azure/ms-rest-azure-js" "^1.1.0" "@azure/ms-rest-js" "^1.1.0" tslib "^1.9.3" -"@azure/arm-appservice-profile-2019-03-01-hybrid@^1.0.0": +"@azure/arm-appservice-profile-2019-03-01-hybrid@1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@azure/arm-appservice-profile-2019-03-01-hybrid/-/arm-appservice-profile-2019-03-01-hybrid-1.0.0.tgz#36b41dd5ce2d7d07ac8828efb4bc0badf9820c3e" - integrity sha512-5hW65PAO3Uhx5V5cIyjvOU+akErhJFm3AtBCA/fAMb/Bj73c5c5HFYJus+CzNoJQyKEE0RubDh7Q3YDjjmXG9g== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-appservice-profile-2019-03-01-hybrid/-/@azure/arm-appservice-profile-2019-03-01-hybrid-1.0.0.tgz#36b41dd5ce2d7d07ac8828efb4bc0badf9820c3e" + integrity sha1-NrQd1c4tfQesiCjvtLwLrfmCDD4= dependencies: "@azure/ms-rest-azure-js" "^1.3.2" "@azure/ms-rest-js" "^1.8.1" tslib "^1.9.3" -"@azure/arm-botservice@^1.0.0": +"@azure/arm-botservice@1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@azure/arm-botservice/-/arm-botservice-1.0.0.tgz#439140b234831895dd3c9fdec524fef5fc94c5e3" - integrity sha512-0+Er+05npiOerhG6FAyFY17bglwHQA5+AmeLIlD+/skAcPI3pvcRfepFTI2XW7CoBWeakY8Ki5w89PPkLFNqjQ== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-botservice/-/@azure/arm-botservice-1.0.0.tgz#439140b234831895dd3c9fdec524fef5fc94c5e3" + integrity sha1-Q5FAsjSDGJXdPJ/exST+9fyUxeM= dependencies: "@azure/ms-rest-azure-js" "^1.3.2" "@azure/ms-rest-js" "^1.8.1" tslib "^1.9.3" -"@azure/arm-deploymentmanager@^3.0.0": +"@azure/arm-deploymentmanager@3.0.0": version "3.0.0" - resolved "https://registry.yarnpkg.com/@azure/arm-deploymentmanager/-/arm-deploymentmanager-3.0.0.tgz#793ae174d043d2118d520eaec67f0986c319f7a3" - integrity sha512-9gv9hUCfAg52Dqxw7W2+B1ytBNitIBEoxd8C1OJnlBH84j5L2S8yLfZsqsyAKbeQE8zkbvVFnrdgO1CS8HUj7g== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-deploymentmanager/-/@azure/arm-deploymentmanager-3.0.0.tgz#793ae174d043d2118d520eaec67f0986c319f7a3" + integrity sha1-eTrhdNBD0hGNUg6uxn8JhsMZ96M= dependencies: "@azure/ms-rest-azure-js" "^2.0.1" "@azure/ms-rest-js" "^2.0.4" tslib "^1.10.0" -"@azure/arm-resources@2.1.0", "@azure/arm-resources@^2.1.0": +"@azure/arm-resources@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@azure/arm-resources/-/arm-resources-2.1.0.tgz#bb7a3faca0c717656bef93c6f81ff6a9d1d8fa8b" integrity sha512-WpBQt3QwfulWAgss7r6apfKswc6SS8Z005AhQalx618757dX+0kTiizL5XipDZFWq/nlCN2fFv9ba1m4v5x2tg== @@ -47,10 +47,10 @@ "@azure/ms-rest-js" "^2.0.4" tslib "^1.10.0" -"@azure/arm-subscriptions@^2.0.0": +"@azure/arm-subscriptions@2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@azure/arm-subscriptions/-/arm-subscriptions-2.0.0.tgz#4202740b7f65a9d0f16f7903579a615f5de45a92" - integrity sha512-+ys2glK5YgwZ9KhwWblfAQIPABtiB5OdKEpPOpcvr7B5ygYTwZuSUNObX9MRu/MyiRo1zDlUvlxHltBphq/bLQ== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-subscriptions/-/@azure/arm-subscriptions-2.0.0.tgz#4202740b7f65a9d0f16f7903579a615f5de45a92" + integrity sha1-QgJ0C39lqdDxb3kDV5phX13kWpI= dependencies: "@azure/ms-rest-azure-js" "^2.0.1" "@azure/ms-rest-js" "^2.0.4" @@ -64,14 +64,6 @@ "@azure/ms-rest-js" "^2.0.3" tslib "^1.10.0" -"@azure/cognitiveservices-luis-authoring@^4.0.0-preview.1": - version "4.0.0-preview.3" - resolved "https://registry.yarnpkg.com/@azure/cognitiveservices-luis-authoring/-/cognitiveservices-luis-authoring-4.0.0-preview.3.tgz#68cef01a9efca77c4c5cd4be67b9e0888433af60" - integrity sha512-ZQl5ThPwLEHGpdk9p6YcSLODdW/008ngiJsXt5yBP5GDEryqCX5kIgoDDE/ChJNiCU+aZ/jAsRBtNsnqdKekBw== - dependencies: - "@azure/ms-rest-js" "^2.0.3" - tslib "^1.10.0" - "@azure/cognitiveservices-luis-runtime@5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@azure/cognitiveservices-luis-runtime/-/cognitiveservices-luis-runtime-5.0.0.tgz#5a1cbff1f78b25b7ab33d9f675f79eff217188c9" @@ -80,10 +72,10 @@ "@azure/ms-rest-js" "^2.0.3" tslib "^1.10.0" -"@azure/graph@^5.0.1": +"@azure/graph@5.0.1": version "5.0.1" - resolved "https://registry.yarnpkg.com/@azure/graph/-/graph-5.0.1.tgz#93b89872ad63d40956ddb664d9bcca46cf958179" - integrity sha512-MMge4Uzl0hK/72h4cGESjX3D5jSwV9Ylwp4HiXp0LdF//vFhYLzsnVRfD1cfkMl5nGlbaqOR3mej4QWAeppjig== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/graph/-/@azure/graph-5.0.1.tgz#93b89872ad63d40956ddb664d9bcca46cf958179" + integrity sha1-k7iYcq1j1AlW3bZk2bzKRs+VgXk= dependencies: "@azure/ms-rest-azure-js" "^2.0.0" "@azure/ms-rest-js" "^2.0.3" @@ -115,10 +107,10 @@ "@azure/ms-rest-js" "^1.8.10" tslib "^1.9.3" -"@azure/ms-rest-browserauth@^0.1.4": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-browserauth/-/ms-rest-browserauth-0.1.5.tgz#eb73dc9f6ae8c3f4df187e3e3aaf23f2ee940018" - integrity sha512-vOuQyNGItl8jpr4SUKlZoyFzrJokheKeBHEJTecwDtppri1xDQOTPfYuEbkATxaYd9C36Awo1PUV6XO1Z+wQ/Q== +"@azure/ms-rest-browserauth@0.1.4": + version "0.1.4" + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-browserauth/-/@azure/ms-rest-browserauth-0.1.4.tgz#a2b9434c7de08fd3e742b4bfd75427deef1dbab1" + integrity sha1-orlDTH3gj9PnQrS/11Qn3u8durE= dependencies: "@azure/ms-rest-azure-env" "^1.1.0" "@azure/ms-rest-js" "^1.8.1" @@ -164,23 +156,6 @@ "@azure/ms-rest-js" "^2.0.4" adal-node "^0.1.28" -"@azure/ms-rest-nodeauth@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.0.5.tgz#f277ec6e323178fd13c05ca82321ba99c767d4bc" - integrity sha512-GoP9tn4rFNHJqE00+ARtHmPKufC3h4j7xEuyveOueUrguLT/Q0c5aEPgS9bmXWiHGoreRn2hVGGwd3m8oDdV3g== - dependencies: - "@azure/ms-rest-azure-env" "^2.0.0" - "@azure/ms-rest-js" "^2.0.4" - adal-node "^0.1.28" - -"@bfc/plugin-loader@../packages/extensions/plugin-loader", "@bfc/plugin-loader@file:../packages/extensions/plugin-loader": - version "1.0.0" - dependencies: - debug "^4.1.1" - globby "^11.0.0" - passport "^0.4.1" - path-to-regexp "^6.1.0" - "@microsoft/bf-cli-command@4.10.0-dev.20200721.8bb21ac": version "4.10.0-dev.20200721.8bb21ac" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-cli-command/-/@microsoft/bf-cli-command-4.10.0-dev.20200721.8bb21ac.tgz#9c81b37bc10072ca6beec7d7f68aa309f8a552ec" @@ -403,7 +378,7 @@ resolved "https://registry.yarnpkg.com/@oclif/screen/-/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493" integrity sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw== -"@types/archiver@3.1.0", "@types/archiver@^3.1.0": +"@types/archiver@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/archiver/-/archiver-3.1.0.tgz#0d5bd922ba5cf06e137cd6793db7942439b1805e" integrity sha512-nTvHwgWONL+iXG+9CX+gnQ/tTOV+qucAjwpXqeUn4OCRMxP42T29FFP/7XaOo0EqqO3TlENhObeZEe7RUJAriw== @@ -432,13 +407,6 @@ dependencies: "@types/node" "*" -"@types/fs-extra@^8.1.0": - version "8.1.1" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.1.tgz#1e49f22d09aa46e19b51c0b013cb63d0d923a068" - integrity sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w== - dependencies: - "@types/node" "*" - "@types/glob@*", "@types/glob@^7.1.1": version "7.1.2" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987" @@ -478,15 +446,7 @@ "@types/bluebird" "*" "@types/request" "*" -"@types/request-promise@^4.1.45": - version "4.1.46" - resolved "https://registry.yarnpkg.com/@types/request-promise/-/request-promise-4.1.46.tgz#37df6efae984316dfbfbbe8fcda37f3ba52822f2" - integrity sha512-3Thpj2Va5m0ji3spaCk8YKrjkZyZc6RqUVOphA0n/Xet66AW/AiOAs5vfXhQIL5NmkaO7Jnun7Nl9NEjJ2zBaw== - dependencies: - "@types/bluebird" "*" - "@types/request" "*" - -"@types/request@*", "@types/request@^2.48.4": +"@types/request@*": version "2.48.5" resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== @@ -572,11 +532,6 @@ adal-node@^0.1.28: xmldom ">= 0.1.x" xpath.js "~1.1.0" -adm-zip@0.4.14: - version "0.4.14" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.14.tgz#2cf312bcc9f8875df835b0f6040bd89be0a727a9" - integrity sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g== - ajv@^6.5.5: version "6.12.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" @@ -658,7 +613,7 @@ archiver-utils@^2.1.0: normalize-path "^3.0.0" readable-stream "^2.0.0" -archiver@3.1.1, archiver@^3.1.1: +archiver@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0" integrity sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg== @@ -708,7 +663,7 @@ async@>=0.6.0: resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== -async@^2.6.2, async@^2.6.3: +async@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== @@ -1039,13 +994,6 @@ debug@=3.1.0: dependencies: ms "2.0.0" -debug@^3.1.1: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -1278,7 +1226,7 @@ form-data@^2.3.2, form-data@^2.5.0: form-data@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" + resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== dependencies: asynckit "^0.4.0" @@ -1299,6 +1247,15 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-extra@8.1.0, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^7.0.0, fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -1308,15 +1265,6 @@ fs-extra@^7.0.0, fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -1375,18 +1323,6 @@ glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -globby@11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.0.tgz#56fd0e9f0d4f8fb0c456f1ab0dee96e1380bc154" - integrity sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - globby@^10.0.1: version "10.0.2" resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" @@ -1401,7 +1337,7 @@ globby@^10.0.1: merge2 "^1.2.3" slash "^3.0.0" -globby@^11.0.0, globby@^11.0.1: +globby@^11.0.1: version "11.0.1" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== @@ -1500,11 +1436,6 @@ inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - intercept-stdout@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/intercept-stdout/-/intercept-stdout-0.1.2.tgz#126abf1fae6c509a428a98c61a631559042ae9fd" @@ -1783,6 +1714,11 @@ lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== +lodash@^4.17.20: + version "4.17.20" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -1845,18 +1781,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@1.2.5, minimist@^1.2.5: +minimist@1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1949,19 +1878,6 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== -passport-strategy@1.x.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= - -passport@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" - integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== - dependencies: - passport-strategy "1.x.x" - pause "0.0.1" - password-prompt@^1.0.7, password-prompt@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/password-prompt/-/password-prompt-1.1.2.tgz#85b2f93896c5bd9e9f2d6ff0627fa5af3dc00923" @@ -1980,29 +1896,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-to-regexp@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.1.0.tgz#0b18f88b7a0ce0bfae6a25990c909ab86f512427" - integrity sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw== - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -path@0.12.7, path@^0.12.7: - version "0.12.7" - resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" - integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= - dependencies: - process "^0.11.1" - util "^0.10.3" - -pause@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -2013,25 +1911,11 @@ picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -portfinder@1.0.26, portfinder@^1.0.26: - version "1.0.26" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" - integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.1" - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@^0.11.1: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= - psl@^1.1.28: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -2099,17 +1983,17 @@ request-promise-core@1.1.3: dependencies: lodash "^4.17.15" -request-promise@^4.2.5: +request-promise@4.2.5: version "4.2.5" - resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.5.tgz#186222c59ae512f3497dfe4d75a9c8461bd0053c" - integrity sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg== + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/request-promise/-/request-promise-4.2.5.tgz#186222c59ae512f3497dfe4d75a9c8461bd0053c" + integrity sha1-GGIixZrlEvNJff5NdanIRhvQBTw= dependencies: bluebird "^3.5.0" request-promise-core "1.1.3" stealthy-require "^1.1.1" tough-cookie "^2.3.3" -"request@>= 2.52.0", request@^2.88.0, request@^2.88.2: +request@2.88.2, "request@>= 2.52.0", request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -2140,13 +2024,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@3.0.2, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - run-parallel@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" @@ -2428,19 +2305,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@^0.10.3: - version "0.10.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" - integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== - dependencies: - inherits "2.0.3" - -uuid@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.1.tgz#95ed6ff3d8c881cbf85f0f05cc3915ef994818ef" - integrity sha512-yqjRXZzSJm9Dbl84H2VDHpM3zMjzSJQ+hn6C4zqd5ilW+7P4ZmLEEqwho9LjP+tGuZlF4xrHQXT0h9QZUS/pWA== - -uuid@7.0.3, uuid@^7.0.1: +uuid@7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== diff --git a/Composer/plugins/lib/bot-deploy/.gitignore b/Composer/plugins/lib/bot-deploy/.gitignore deleted file mode 100644 index 1ccc52a7fb..0000000000 --- a/Composer/plugins/lib/bot-deploy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/node_modules -/lib \ No newline at end of file diff --git a/Composer/plugins/lib/bot-deploy/README.md b/Composer/plugins/lib/bot-deploy/README.md deleted file mode 100644 index bac3d47eee..0000000000 --- a/Composer/plugins/lib/bot-deploy/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Node Deployment - -## Instructions -> 1. npm install - -> 2. You should provide following params: - - // Subscription Id of Auzre Account - subId: string - - // The credentials from user login - creds: any - - // The project path to deploy - projPath: string - - // Logger - logger: (string) => any - - // Deployment settings file path - deploymentSettingsPath?: string - - // Deploy file path, default is .deployment file - deployFilePath?: string - - // Zip file path, default is 'code.zip' - zipPath?: string - - // Pulblishing folder for 'dotnet publish' command, default is 'bin/Release/netcoreapp3.1' - publishFolder?: string - - // The deployment settings file path, default is 'appsettings.deployment.json' - settingsPath?: string - - // The ARM template file path, default is 'DeploymentTemplates/template-with-preexisting-rg.json' - templatePath?: string - - // Dotnet project path, default is 'Microsoft.BotFramework.Composer.WebApp.csproj' - dotnetProjectPath?: string - - // Lubuild generated folder path, default is 'generated' - generatedFolder?: string - - // Remote bot json dialog path, default is 'ComposerDialogs' - remoteBotPath?: string -> 3. run 'create' method to create azure resources, including Bot Channels Registration, Azure Cosmos DB account, Application Insights, App Service plan, App Service, Luis, Storage account -> 4. run 'deploy' method to train the related luis models and deploy the runtime to Azure. -## Details -1. If you don't provide appId, the script will create an app registration based on your password. -2. If you don't provide luis authoring key, the script will create a luis authoring service and related luis service on Azure diff --git a/Composer/plugins/lib/bot-deploy/package.json b/Composer/plugins/lib/bot-deploy/package.json deleted file mode 100644 index 1e6e7759cb..0000000000 --- a/Composer/plugins/lib/bot-deploy/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@bfc/botframeworkdeploy", - "version": "1.0.0", - "description": "typescript version of bot deployment", - "main": "lib/index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "tsc" - }, - "author": "", - "license": "MIT", - "dependencies": { - "@azure/arm-appinsights": "^2.1.0", - "@azure/arm-appservice-profile-2019-03-01-hybrid": "^1.0.0", - "@azure/arm-botservice": "^1.0.0", - "@azure/arm-deploymentmanager": "^3.0.0", - "@azure/arm-resources": "^2.1.0", - "@azure/arm-subscriptions": "^2.0.0", - "@azure/cognitiveservices-luis-authoring": "^4.0.0-preview.1", - "@azure/graph": "^5.0.1", - "@azure/ms-rest-browserauth": "^0.1.4", - "@azure/ms-rest-nodeauth": "^3.0.3", - "@microsoft/bf-lu": "^4.10.0-dev.20200728.930f45e", - "@microsoft/bf-luis-cli": "^4.10.0-dev.20200721.8bb21ac", - "@types/archiver": "^3.1.0", - "@types/fs-extra": "^8.1.0", - "@types/request": "^2.48.4", - "@types/request-promise": "^4.1.45", - "archiver": "^3.1.1", - "fs-extra": "^8.1.0", - "request": "^2.88.2", - "request-promise": "^4.2.5" - } -} diff --git a/Composer/plugins/lib/bot-deploy/src/index.ts b/Composer/plugins/lib/bot-deploy/src/index.ts deleted file mode 100644 index 3b5600496f..0000000000 --- a/Composer/plugins/lib/bot-deploy/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -export * from './botProjectDeploy'; -export * from './botProjectDeployConfig'; -export * from './botProjectLoggerType'; diff --git a/Composer/plugins/lib/bot-deploy/tsconfig.json b/Composer/plugins/lib/bot-deploy/tsconfig.json deleted file mode 100644 index 7da2b5f30b..0000000000 --- a/Composer/plugins/lib/bot-deploy/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "lib" - }, - "include": [ - "./src/**/*", - ], - "exclude": [ - "node_modules" - ], -} diff --git a/Composer/plugins/lib/package.json b/Composer/plugins/lib/package.json deleted file mode 100644 index dc4d49eaab..0000000000 --- a/Composer/plugins/lib/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "@bfc/plugins-libs", - "version": "1.0.0", - "engines": { - "node": ">=12" - }, - "scripts": { - "build:bot-deploy": "cd bot-deploy && yarn build", - "build:all": "yarn build:bot-deploy" - }, - "author": "", - "license": "ISC" - } \ No newline at end of file diff --git a/Composer/plugins/localPublish/.eslintrc.js b/Composer/plugins/localPublish/.eslintrc.js index bcfa12e31d..101c1fc90b 100644 --- a/Composer/plugins/localPublish/.eslintrc.js +++ b/Composer/plugins/localPublish/.eslintrc.js @@ -1,10 +1,7 @@ module.exports = { - extends: ['../../.eslintrc.js'], - parserOptions: { - project: './tsconfig.json', - tsconfigRootDir: __dirname, - }, - rules: { - 'security/detect-non-literal-fs-filename': 'off', - }, + extends: ['../../.eslintrc.js'], + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: __dirname, + }, }; diff --git a/Composer/plugins/localPublish/.gitignore b/Composer/plugins/localPublish/.gitignore index c6b01f850d..276d53589c 100644 --- a/Composer/plugins/localPublish/.gitignore +++ b/Composer/plugins/localPublish/.gitignore @@ -1,3 +1,4 @@ hostedBots node_modules -lib \ No newline at end of file +lib + diff --git a/Composer/plugins/localPublish/package.json b/Composer/plugins/localPublish/package.json index 76b857e720..aa5bbf3332 100644 --- a/Composer/plugins/localPublish/package.json +++ b/Composer/plugins/localPublish/package.json @@ -11,13 +11,12 @@ "author": "", "license": "ISC", "dependencies": { - "@bfc/plugin-loader": "file:../../packages/extensions/plugin-loader", - "adm-zip": "0.4.14", - "archiver": "3.1.1", - "globby": "11.0.0", - "path": "0.12.7", - "portfinder": "1.0.26", - "rimraf": "3.0.2", - "uuid": "7.0.1" + "adm-zip": "^0.4.14", + "archiver": "^3.1.1", + "globby": "^11.0.0", + "path": "^0.12.7", + "portfinder": "^1.0.26", + "rimraf": "^3.0.2", + "uuid": "^7.0.1" } } diff --git a/Composer/plugins/localPublish/src/index.ts b/Composer/plugins/localPublish/src/index.ts index 800cd4f6d2..dd7b98abcd 100644 --- a/Composer/plugins/localPublish/src/index.ts +++ b/Composer/plugins/localPublish/src/index.ts @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { ChildProcess, spawn, execSync } from 'child_process'; +import { ChildProcess, spawn } from 'child_process'; import path from 'path'; import fs from 'fs'; import { promisify } from 'util'; @@ -11,10 +11,6 @@ import archiver from 'archiver'; import { v4 as uuid } from 'uuid'; import AdmZip from 'adm-zip'; import portfinder from 'portfinder'; -import { ComposerPluginRegistration, PublishResponse, PublishPlugin } from '@bfc/plugin-loader'; - -import { copyDir } from './copyDir'; -import { IFileStorage } from './interface'; const stat = promisify(fs.stat); const readDir = promisify(fs.readdir); @@ -22,72 +18,112 @@ const removeFile = promisify(fs.unlink); const mkDir = promisify(fs.mkdir); const removeDirAndFiles = promisify(rimraf); const copyFile = promisify(fs.copyFile); +const readFile = promisify(fs.readFile); interface RunningBot { - process: ChildProcess; - port: number; + process?: ChildProcess; + port?: number; + status: number; + result: { + message: string; + }; } interface PublishConfig { botId: string; version: string; fullSettings: any; - templatePath: string; } const isWin = process.platform === 'win32'; -class LocalPublisher implements PublishPlugin { +class LocalPublisher { static runningBots: { [key: string]: RunningBot } = {}; private readonly baseDir = path.resolve(__dirname, '../'); - private templatePath; - private composer: ComposerPluginRegistration; + private composer: any; - constructor(composer: ComposerPluginRegistration) { + constructor(composer: any) { this.composer = composer; } + private setBotStatus = (botId: string, status: RunningBot) => { + this.composer.log(`SETTING STATUS OF ${botId} to port ${status.port} and status ${status.status}`); + // preserve the pid and port if one is available + if (!status.process && LocalPublisher.runningBots[botId] && LocalPublisher.runningBots[botId].process) { + status.process = LocalPublisher.runningBots[botId].process; + } + if (!status.port && LocalPublisher.runningBots[botId] && LocalPublisher.runningBots[botId].port) { + status.port = LocalPublisher.runningBots[botId].port; + } + + LocalPublisher.runningBots[botId] = status; + }; + + private publishAsync = async (botId: string, version: string, fullSettings: any, project: any, user) => { + try { + // 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); + if (!project.settings.runtime || project.settings.runtime.customRuntime !== true) { + this.composer.log('Using managed runtime'); + + await this.initBot(project); + await this.saveContent(botId, version, project.dataDir, user); + await runtime.setSkillManifest( + this.getBotRuntimeDir(botId), + project.fileStorage, + this.getManifestSrcDir(project.dataDir), + project.fileStorage + ); + } else if (project.settings.runtime.path && project.settings.runtime.command) { + await runtime.setSkillManifest( + project.settings.runtime.path, + project.fileStorage, + this.getManifestSrcDir(project.dataDir), + project.fileStorage + ); + } else { + throw { + status: 500, + result: { + message: 'Custom runtime settings are incomplete. Please specify path and command.', + }, + }; + } + await this.setBot(botId, version, fullSettings, project); + } catch (error) { + this.stopBot(botId); + this.setBotStatus(botId, { + status: 500, + result: { + message: error.message, + }, + }); + } + }; + // config include botId and version, project is content(ComposerDialogs) - publish = async (config: PublishConfig, project, metadata, user): Promise => { - const { templatePath, fullSettings } = config; - this.templatePath = templatePath; + publish = async (config: PublishConfig, project, metadata, user): Promise => { + const { fullSettings } = config; const botId = project.id; const version = 'default'; this.composer.log('Starting publish'); - // if enableCustomRuntime is not true, initialize the runtime code in a tmp folder - // and export the content into that folder as well. - if (!project.settings.runtime || project.settings.runtime.customRuntime !== true) { - this.composer.log('Using managed runtime'); - await this.initBot(botId); - await this.saveContent(botId, version, project.dataDir, user); - await this.saveSkillManifests(this.getBotRuntimeDir(botId), project.dataDir); - } else if (project.settings.runtime.path && project.settings.runtime.command) { - // update manifst into runtime wwwroot - await this.saveSkillManifests(project.settings.runtime.path, project.dataDir); - } else { - return { - status: 400, - result: { - message: 'Custom runtime settings are incomplete. Please specify path and command.', - }, - }; - } + // set the running bot status + this.setBotStatus(botId, { status: 202, result: { message: 'Reloading...' } }); try { // start or restart the bot process - const url = await this.setBot(botId, version, fullSettings, project.dataDir); - + // do NOT await this, as it can take a long time + this.publishAsync(botId, version, fullSettings, project, user); return { - status: 200, + status: 202, result: { id: uuid(), - endpointURL: url, message: 'Local publish success.', }, }; } catch (error) { - console.error('Error in local publish', error); return { status: 500, result: { @@ -99,15 +135,27 @@ class LocalPublisher implements PublishPlugin { getStatus = async (config: PublishConfig, project, user) => { const botId = project.id; if (LocalPublisher.runningBots[botId]) { - const port = LocalPublisher.runningBots[botId].port; - const url = `http://localhost:${port}`; - return { - status: 200, - result: { - message: 'Running', - endpointURL: url, - }, - }; + if (LocalPublisher.runningBots[botId].status === 200) { + const port = LocalPublisher.runningBots[botId].port; + const url = `http://localhost:${port}`; + return { + status: 200, + result: { + message: 'Running', + endpointURL: url, + }, + }; + } else { + const status = { + status: LocalPublisher.runningBots[botId].status, + result: LocalPublisher.runningBots[botId].result, + }; + if (LocalPublisher.runningBots[botId].status === 500) { + // after we return the 500 status once, delete it out of the running bots list. + delete LocalPublisher.runningBots[botId]; + } + return status; + } } else { return { status: 200, @@ -143,8 +191,6 @@ class LocalPublisher implements PublishPlugin { private getManifestSrcDir = (srcDir: string) => path.resolve(srcDir, 'manifests'); - private getManifestDstDir = (baseDir: string) => path.resolve(baseDir, 'azurewebapp', 'wwwroot', 'manifests'); - private getDownloadPath = (botId: string, version: string) => path.resolve(this.getHistoryDir(botId), `${version}.zip`); @@ -166,32 +212,50 @@ class LocalPublisher implements PublishPlugin { } }; - private initBot = async (botId: string) => { + private initBot = async (project) => { this.composer.log('Initializing bot'); + const botId = project.id; const isExist = await this.botExist(botId); - if (!isExist) { - const botDir = this.getBotDir(botId); - const runtimeDir = this.getBotRuntimeDir(botId); - // create bot dir - await mkDir(botDir, { recursive: true }); - await mkDir(runtimeDir, { recursive: true }); - - // create ComposerDialogs and history folder - mkDir(this.getBotAssetsDir(botId), { recursive: true }); - mkDir(this.getHistoryDir(botId), { recursive: true }); - - // copy runtime template in folder - await this.copyDir(this.templatePath, runtimeDir); - - try { - // TODO ccastro: discuss with benbrown. Consider init command as template metadata. Remove azurewebapp from here. - execSync('dotnet user-secrets init --project azurewebapp', { cwd: runtimeDir, stdio: 'pipe' }); - execSync('dotnet build', { cwd: runtimeDir, stdio: 'pipe' }); - } catch (error) { - // delete the folder to make sure build again. - await removeDirAndFiles(botDir); - throw new Error(error.toString()); + // get runtime template + const runtime = this.composer.getRuntimeByProject(project); + try { + if (!isExist) { + const botDir = this.getBotDir(botId); + const runtimeDir = this.getBotRuntimeDir(botId); + // create bot dir + await mkDir(botDir, { recursive: true }); + await mkDir(runtimeDir, { recursive: true }); + + // create ComposerDialogs and history folder + mkDir(this.getBotAssetsDir(botId), { recursive: true }); + mkDir(this.getHistoryDir(botId), { recursive: true }); + + // copy runtime template in folder + this.composer.log('COPY FROM ', runtime.path, ' to ', runtimeDir); + await this.copyDir(runtime.path, runtimeDir); + await runtime.build(runtimeDir, project); + } else { + // stop bot + this.stopBot(botId); + // get previous settings + // when changing type of runtime + const settings = JSON.parse( + await readFile(path.resolve(this.getBotDir(botId), 'settings/appsettings.json'), { + encoding: 'utf-8', + }) + ); + if (!settings.runtime?.key || settings.runtime?.key !== project.settings.runtime?.key) { + // in order to change runtime type + await removeDirAndFiles(this.getBotRuntimeDir(botId)); + // copy runtime template in folder + await this.copyDir(runtime.path, this.getBotRuntimeDir(botId)); + await runtime.build(this.getBotRuntimeDir(botId), project); + } } + } catch (error) { + // delete the folder to make sure build again. + await removeDirAndFiles(this.getBotDir(botId)); + throw new Error(error.toString()); } }; @@ -201,56 +265,47 @@ class LocalPublisher implements PublishPlugin { await this.zipBot(dstPath, srcDir); }; - private saveSkillManifests = async (dstPath: string, srcDir: string) => { - const manifestSrcDir = this.getManifestSrcDir(srcDir); - const manifestDstDir = this.getManifestDstDir(dstPath); - - if (await this.dirExist(manifestDstDir)) { - await removeDirAndFiles(manifestDstDir); - } - - if (await this.dirExist(manifestSrcDir)) { - this.copyDir(manifestSrcDir, manifestDstDir); - } - }; - // start bot in current version - private setBot = async (botId: string, version: string, settings: any, project: any = undefined) => { + private setBot = async (botId: string, version: string, settings: any, project: any) => { // get port, and stop previous bot if exist - let port; - if (LocalPublisher.runningBots[botId]) { - this.composer.log('Bot already running. Stopping bot...'); - port = LocalPublisher.runningBots[botId].port; - this.stopBot(botId); - } else { - port = await portfinder.getPortPromise({ port: 3979, stopPort: 5000 }); - } + 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; + this.stopBot(botId); + } + if (!port) { + port = await portfinder.getPortPromise({ port: 3979, stopPort: 5000 }); + } - // if not using custom runtime, update assets in tmp older - if (!settings.runtime || settings.runtime.customRuntime !== true) { - this.composer.log('Updating bot assets'); - await this.restoreBot(botId, version); - } + // if not using custom runtime, update assets in tmp older + if (!settings.runtime || settings.runtime.customRuntime !== true) { + this.composer.log('Updating bot assets'); + await this.restoreBot(botId, version); + } - // start the bot process - try { - await this.startBot(botId, port, settings); - return `http://localhost:${port}`; + // start the bot process + await this.startBot(botId, port, settings, project); } catch (error) { + console.error('Error in startbot: ', error); this.stopBot(botId); - throw error; + this.setBotStatus(botId, { + status: 500, + result: { + message: error, + }, + }); } }; - private startBot = async (botId: string, port: number, settings: any): Promise => { - const botDir = - settings.runtime && settings.runtime.customRuntime === true - ? settings.runtime.path - : this.getBotRuntimeDir(botId); + private startBot = async (botId: string, port: number, settings: any, project: any): Promise => { + const botDir = settings.runtime?.customRuntime === true ? settings.runtime.path : this.getBotRuntimeDir(botId); const commandAndArgs = - settings.runtime && settings.runtime.customRuntime === true + settings.runtime?.customRuntime === true ? settings.runtime.command.split(/\s+/) - : ['dotnet', 'run', '--project', 'azurewebapp']; //TODO: ccastro should pick up the bot start command here. After, remove azurewebapp arg + : this.composer.getRuntimeByProject(project).startCommand.split(/\s+/); return new Promise((resolve, reject) => { // ensure the specified runtime path exists @@ -258,28 +313,33 @@ class LocalPublisher implements PublishPlugin { reject(`Runtime path ${botDir} does not exist.`); return; } - // take the 0th item off the array, leaving just the args this.composer.log('Starting bot on port %d. (%s)', port, commandAndArgs.join(' ')); const startCommand = commandAndArgs.shift(); - let process; + let spawnProcess; try { - process = spawn( + spawnProcess = spawn( startCommand, - [...commandAndArgs, `--urls`, `http://0.0.0.0:${port}`, ...this.getConfig(settings)], + [...commandAndArgs, '--port', port, `--urls`, `http://0.0.0.0:${port}`, ...this.getConfig(settings)], { cwd: botDir, stdio: ['ignore', 'pipe', 'pipe'], detached: !isWin, // detach in non-windows } ); - this.composer.log('Started process %d', process.pid); + this.composer.log('Started process %d', spawnProcess.pid); } catch (err) { return reject(err); } - LocalPublisher.runningBots[botId] = { process: process, port: port }; - const processLog = this.composer.log.extend(process.pid); - this.addListeners(process, processLog, resolve, reject); + this.setBotStatus(botId, { + process: spawnProcess, + port: port, + status: 200, + result: { message: 'Runtime started' }, + }); + const processLog = this.composer.log.extend(spawnProcess.pid); + this.addListeners(spawnProcess, botId, processLog); + resolve(); }); }; @@ -296,18 +356,25 @@ class LocalPublisher implements PublishPlugin { return configList; }; + private removeListener = (child: ChildProcess) => { + child.stdout.removeAllListeners('data'); + child.stderr.removeAllListeners('data'); + + child.removeAllListeners('message'); + child.removeAllListeners('error'); + child.removeAllListeners('exit'); + }; + private addListeners = ( child: ChildProcess, + botId: string, // eslint-disable-next-line @typescript-eslint/no-explicit-any - logger: (...args: any[]) => void, - resolve: Function, - reject: Function + logger: (...args: any[]) => void ) => { let erroutput = ''; child.stdout && child.stdout.on('data', (data: any) => { logger('%s', data); - resolve(child.pid); }); child.stderr && @@ -317,13 +384,14 @@ class LocalPublisher implements PublishPlugin { child.on('exit', (code) => { if (code !== 0) { - reject(erroutput); + logger('error on exit: %s, exit code %d', erroutput, code); + this.setBotStatus(botId, { status: 500, result: { message: erroutput } }); } }); child.on('error', (err) => { logger('error: %s', err.message); - reject(`Could not launch bot runtime process: ${err.message}`); + this.setBotStatus(botId, { status: 500, result: { message: err.message } }); }); child.on('message', (msg) => { @@ -367,13 +435,15 @@ class LocalPublisher implements PublishPlugin { zip.extractAllTo(dstPath, true); }; - private stopBot = (botId: string) => { + // make it public, so that able to stop runtime before switch ejected runtime. + public stopBot = (botId: string) => { const proc = LocalPublisher.runningBots[botId]?.process; if (proc) { this.composer.log('Killing process %d', -proc.pid); // Kill the bot process AND all child processes try { + this.removeListener(proc); process.kill(isWin ? proc.pid : -proc.pid); } catch (err) { // ESRCH means pid not found @@ -421,40 +491,10 @@ class LocalPublisher implements PublishPlugin { }; } -export default async (composer: ComposerPluginRegistration): Promise => { +export default async (composer: any): Promise => { const publisher = new LocalPublisher(composer); // register this publishing method with Composer await composer.addPublishMethod(publisher); - - // register the bundled c# runtime used by the local publisher with the eject feature - composer.addRuntimeTemplate({ - key: 'azurewebapp', - name: 'C#', - startCommand: 'dotnet run --project azurewebapp', - eject: async (project, localDisk: IFileStorage) => { - const sourcePath = path.resolve(__dirname, '../../../../runtime/dotnet'); - const destPath = path.join(project.dir, 'runtime'); - if (!(await project.fileStorage.exists(destPath))) { - // used to read bot project template from source (bundled in plugin) - await copyDir(sourcePath, localDisk, destPath, project.fileStorage); - const schemaDstPath = path.join(project.dir, 'schemas'); - const schemaSrcPath = path.join(sourcePath, 'azurewebapp/schemas'); - const customSchemaExists = fs.existsSync(schemaDstPath); - const pathsToExclude: Set = new Set(); - if (customSchemaExists) { - const sdkExcludePath = await localDisk.glob('sdk.schema', schemaSrcPath); - if (sdkExcludePath.length > 0) { - pathsToExclude.add(path.join(schemaSrcPath, sdkExcludePath[0])); - } - } - await copyDir(schemaSrcPath, localDisk, schemaDstPath, project.fileStorage, pathsToExclude); - const schemaFolderInRuntime = path.join(destPath, 'azurewebapp/schemas'); - await removeDirAndFiles(schemaFolderInRuntime); - return destPath; - } - throw new Error(`Runtime already exists at ${destPath}`); - }, - }); }; // stop all the runningBot when process exit diff --git a/Composer/plugins/localPublish/yarn.lock b/Composer/plugins/localPublish/yarn.lock new file mode 100644 index 0000000000..d191cd90f0 --- /dev/null +++ b/Composer/plugins/localPublish/yarn.lock @@ -0,0 +1,540 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +adm-zip@^0.4.14: + version "0.4.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" + integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== + +archiver-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" + integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== + dependencies: + glob "^7.1.4" + graceful-fs "^4.2.0" + lazystream "^1.0.0" + lodash.defaults "^4.2.0" + lodash.difference "^4.5.0" + lodash.flatten "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.union "^4.6.0" + normalize-path "^3.0.0" + readable-stream "^2.0.0" + +archiver@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0" + integrity sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg== + dependencies: + archiver-utils "^2.1.0" + async "^2.6.3" + buffer-crc32 "^0.2.1" + glob "^7.1.4" + readable-stream "^3.4.0" + tar-stream "^2.1.0" + zip-stream "^2.1.2" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +async@^2.6.2, async@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +bl@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" + integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer@^5.1.0, buffer@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +compress-commons@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-2.1.1.tgz#9410d9a534cf8435e3fbbb7c6ce48de2dc2f0610" + integrity sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q== + dependencies: + buffer-crc32 "^0.2.13" + crc32-stream "^3.0.1" + normalize-path "^3.0.0" + readable-stream "^2.3.6" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +crc32-stream@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-3.0.1.tgz#cae6eeed003b0e44d739d279de5ae63b171b4e85" + integrity sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w== + dependencies: + crc "^3.4.4" + readable-stream "^3.4.0" + +crc@^3.4.4: + version "3.8.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== + dependencies: + buffer "^5.1.0" + +debug@^3.1.1: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fastq@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" + integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q== + dependencies: + reusify "^1.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob-parent@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" + integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + dependencies: + readable-stream "^2.0.5" + +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.difference@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= + +lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.union@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= + +lodash@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= + dependencies: + process "^0.11.1" + util "^0.10.3" + +picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +portfinder@^1.0.26: + version "1.0.26" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" + integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.1: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +tar-stream@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" + integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +uuid@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +zip-stream@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-2.1.3.tgz#26cc4bdb93641a8590dd07112e1f77af1758865b" + integrity sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q== + dependencies: + archiver-utils "^2.1.0" + compress-commons "^2.1.1" + readable-stream "^3.4.0" diff --git a/Composer/plugins/mockRemotePublish/src/index.ts b/Composer/plugins/mockRemotePublish/src/index.ts index 16c0972dec..a5137fc0f3 100644 --- a/Composer/plugins/mockRemotePublish/src/index.ts +++ b/Composer/plugins/mockRemotePublish/src/index.ts @@ -8,7 +8,7 @@ */ import { v4 as uuid } from 'uuid'; -import { ComposerPluginRegistration, PublishResponse, PublishPlugin } from '@bfc/plugin-loader'; +import { ComposerPluginRegistration, PublishResponse, PublishPlugin, JSONSchema7 } from '@bfc/plugin-loader'; import schema from './schema'; @@ -24,15 +24,16 @@ interface PublishConfig { class LocalPublisher implements PublishPlugin { private data: { [botId: string]: LocalPublishData }; private composer: ComposerPluginRegistration; - + public schema: JSONSchema7; constructor(composer: ComposerPluginRegistration) { this.data = {}; this.composer = composer; + this.schema = schema; } private finishPublish = async (botId: string, profileName: string, jobId: string) => { setTimeout(() => { - this.data[botId][profileName].forEach(element => { + this.data[botId][profileName].forEach((element) => { if (element.result.id == jobId && element.status !== 500) { element.status = 200; element.result.message = 'Success'; @@ -97,7 +98,7 @@ class LocalPublisher implements PublishPlugin { const botId = project.id; const result = []; if (this.data[botId] && this.data[botId][profileName]) { - this.data[botId][profileName].map(item => { + this.data[botId][profileName].map((item) => { result.push({ ...item.result, status: item.status, @@ -113,7 +114,7 @@ class LocalPublisher implements PublishPlugin { const profileName = config.name; const botId = project.id; this.composer.log('eval list %O', this.data[botId][profileName]); - const matched = this.data[botId][profileName].filter(item => { + const matched = this.data[botId][profileName].filter((item) => { this.composer.log('comparing %s %s', item.result.id, rollbackToVersion); return item.result.id === rollbackToVersion; }); @@ -136,5 +137,5 @@ class LocalPublisher implements PublishPlugin { export default async (composer: ComposerPluginRegistration): Promise => { const publisher = new LocalPublisher(composer); // pass in the custom storage class that will override the default - await composer.addPublishMethod(publisher, schema); + await composer.addPublishMethod(publisher); }; diff --git a/Composer/plugins/package.json b/Composer/plugins/package.json deleted file mode 100644 index 5a04e45eaf..0000000000 --- a/Composer/plugins/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@bfc/plugins", - "license": "MIT", - "private": true, - "engines": { - "node": ">=12" - }, - "workspaces": [ - "azureFunctionsPublish", - "azurePublish", - "samples", - "localPublish", - "lib", - "lib/*" - ], - "scripts": { - "build:all": "yarn build:lib && yarn build:localpublish && yarn build:samples && yarn build:azurePublish && yarn build:azureFunctionsPublish", - "build:localpublish": "yarn workspace localpublish build", - "build:samples": "yarn workspace samples build", - "build:azurePublish": "yarn workspace azurePublish build", - "build:azureFunctionsPublish": "yarn workspace azureFunctionsPublish build", - "build:lib": "yarn workspace @bfc/plugins-libs build:all" - } - } \ No newline at end of file diff --git a/Composer/plugins/runtimes/.eslintrc.js b/Composer/plugins/runtimes/.eslintrc.js new file mode 100644 index 0000000000..8cbe448349 --- /dev/null +++ b/Composer/plugins/runtimes/.eslintrc.js @@ -0,0 +1,10 @@ +module.exports = { + extends: ['../../.eslintrc.js'], + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: __dirname, + }, + rules: { + 'security/detect-non-literal-fs-filename': 'off', + }, +}; diff --git a/Composer/plugins/runtimes/.gitignore b/Composer/plugins/runtimes/.gitignore new file mode 100644 index 0000000000..276d53589c --- /dev/null +++ b/Composer/plugins/runtimes/.gitignore @@ -0,0 +1,4 @@ +hostedBots +node_modules +lib + diff --git a/Composer/plugins/runtimes/package.json b/Composer/plugins/runtimes/package.json new file mode 100644 index 0000000000..22e1ae4dab --- /dev/null +++ b/Composer/plugins/runtimes/package.json @@ -0,0 +1,18 @@ +{ + "name": "plugin-runtimes", + "version": "1.0.0", + "description": "provide info about available runtimes", + "main": "lib/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc" + }, + "extendsComposer": true, + "author": "", + "license": "ISC", + "dependencies": { + "fs-extra": "^9.0.1", + "rimraf": "^3.0.2", + "path": "^0.12.7" + } +} diff --git a/Composer/plugins/localPublish/src/copyDir.ts b/Composer/plugins/runtimes/src/copyDir.ts similarity index 89% rename from Composer/plugins/localPublish/src/copyDir.ts rename to Composer/plugins/runtimes/src/copyDir.ts index a41ad5e44d..2e782f3164 100644 --- a/Composer/plugins/localPublish/src/copyDir.ts +++ b/Composer/plugins/runtimes/src/copyDir.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import Path from 'path'; + import { IFileStorage } from './interface'; export async function copyDir( @@ -21,11 +23,11 @@ export async function copyDir( const paths = await srcStorage.readDir(srcDir); for (const path of paths) { - const srcPath = `${srcDir}/${path}`; + const srcPath = Path.join(srcDir, path); if (pathsToExclude && pathsToExclude.has(srcPath)) { continue; } - const dstPath = `${dstDir}/${path}`; + const dstPath = Path.join(dstDir, path); if ((await srcStorage.stat(srcPath)).isFile) { // copy files diff --git a/Composer/plugins/runtimes/src/index.ts b/Composer/plugins/runtimes/src/index.ts new file mode 100644 index 0000000000..15f6a5f750 --- /dev/null +++ b/Composer/plugins/runtimes/src/index.ts @@ -0,0 +1,238 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +import path from 'path'; +import { promisify } from 'util'; +import { exec } from 'child_process'; + +import rimraf from 'rimraf'; +import * as fs from 'fs-extra'; + +import { copyDir } from './copyDir'; +import { IFileStorage } from './interface'; + +const execAsync = promisify(exec); +const removeDirAndFiles = promisify(rimraf); + +export default async (composer: any): Promise => { + // register the bundled c# runtime used by the local publisher with the eject feature + composer.addRuntimeTemplate({ + key: 'csharp-azurewebapp', + name: 'C#', + startCommand: 'dotnet run --project azurewebapp', + path: path.resolve(__dirname, '../../../../runtime/dotnet'), + build: async (runtimePath: string, _project: any) => { + 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 + const { stderr: initErr } = await execAsync('dotnet user-secrets init --project azurewebapp', { + cwd: runtimePath, + }); + if (initErr) { + throw new Error(initErr); + } + composer.log('Run dotnet build...'); + const { stderr: buildErr } = await execAsync('dotnet build', { cwd: runtimePath }); + if (buildErr) { + throw new Error(buildErr); + } + composer.log('FINISHED BUILDING!'); + }, + run: async (project: any, localDisk: IFileStorage) => { + composer.log('RUN THIS C# PROJECT!'); + }, + buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + composer.log('BUILD FOR DEPLOY TO AZURE!'); + + let csproj = ''; + // find publishing profile in list + const profile = project.settings.publishTargets.find((p) => p.name === profileName); + if (profile.type === 'azurePublish') { + csproj = 'Microsoft.BotFramework.Composer.WebApp.csproj'; + } else if (profile.type === 'azureFunctionsPublish') { + csproj = 'Microsoft.BotFramework.Composer.Functions.csproj'; + } + const publishFolder = path.join(runtimePath, 'bin', 'Release', 'netcoreapp3.1'); + const deployFilePath = path.join(runtimePath, '.deployment'); + const dotnetProjectPath = path.join(runtimePath, csproj); + + // Check for existing .deployment file, if missing, write it. + if (!(await fs.pathExists(deployFilePath))) { + const data = `[config]\nproject = ${csproj}`; + + await fs.writeFile(deployFilePath, data); + } + + // do the dotnet publish + try { + const { stdout, stderr } = await execAsync( + `dotnet publish "${dotnetProjectPath}" -c release -o "${publishFolder}" -v q`, + { + cwd: runtimePath, + } + ); + composer.log('OUTPUT FROM BUILD', stdout); + if (stderr) { + composer.log('ERR FROM BUILD: ', stderr); + } + } catch (err) { + composer.log('Error doing dotnet publish', err); + throw err; + return; + } + // Then, copy the declarative assets into the build artifacts folder. + const remoteBotPath = path.join(publishFolder, 'ComposerDialogs'); + const localBotPath = path.join(runtimePath, 'ComposerDialogs'); + await fs.copy(localBotPath, remoteBotPath, { + overwrite: true, + recursive: true, + }); + + // write settings to disk in the appropriate location + const settingsPath = path.join(publishFolder, 'ComposerDialogs', 'settings', 'appsettings.json'); + if (!(await fs.pathExists(path.dirname(settingsPath)))) { + await fs.mkdirp(path.dirname(settingsPath)); + } + await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2)); + + // return the location of the build artifiacts + return publishFolder; + }, + eject: async (project, localDisk: IFileStorage, isReplace: boolean) => { + const sourcePath = path.resolve(__dirname, '../../../../runtime/dotnet'); + const destPath = path.join(project.dir, 'runtime'); + if ((await project.fileStorage.exists(destPath)) && isReplace) { + // remove runtime folder + await removeDirAndFiles(destPath); + } + if (!(await project.fileStorage.exists(destPath))) { + // used to read bot project template from source (bundled in plugin) + await copyDir(sourcePath, localDisk, destPath, project.fileStorage); + const schemaDstPath = path.join(project.dir, 'schemas'); + const schemaSrcPath = path.join(sourcePath, 'azurewebapp/Schemas'); + const customSchemaExists = fs.existsSync(schemaDstPath); + const pathsToExclude: Set = new Set(); + if (customSchemaExists) { + const sdkExcludePath = await localDisk.glob('sdk.schema', schemaSrcPath); + if (sdkExcludePath.length > 0) { + pathsToExclude.add(path.join(schemaSrcPath, sdkExcludePath[0])); + } + } + await copyDir(schemaSrcPath, localDisk, schemaDstPath, project.fileStorage, pathsToExclude); + const schemaFolderInRuntime = path.join(destPath, 'azurewebapp/Schemas'); + await removeDirAndFiles(schemaFolderInRuntime); + return destPath; + } + throw new Error(`Runtime already exists at ${destPath}`); + }, + setSkillManifest: async ( + dstRuntimePath: string, + dstStorage: IFileStorage, + srcManifestDir: string, + srcStorage: IFileStorage, + mode = 'azurewebapp' // set default as azurewebapp + ) => { + // update manifst into runtime wwwroot + if (mode === 'azurewebapp') { + const manifestDstDir = path.resolve(dstRuntimePath, 'azurewebapp', 'wwwroot', 'manifests'); + + if (await fs.pathExists(manifestDstDir)) { + await removeDirAndFiles(manifestDstDir); + } + + if (await fs.pathExists(srcManifestDir)) { + await copyDir(srcManifestDir, srcStorage, manifestDstDir, dstStorage); + } + } + }, + }); + + composer.addRuntimeTemplate({ + key: 'node-azurewebapp', + name: 'JS (preview)', + startCommand: 'node ./lib/webapp.js', + path: path.resolve(__dirname, '../../../../runtime/node'), + build: async (runtimePath: string, _project: any) => { + // do stuff + composer.log('BUILD THIS JS PROJECT'); + // install dev dependencies in production, make sure typescript is installed + const { stderr: installErr } = await execAsync('npm install && npm install --only=dev', { + cwd: runtimePath, + }); + if (installErr) { + // in order to not throw warning, we just log all warning and error message + composer.log(installErr); + } + const { stderr: install2Err } = await execAsync('npm run build', { + cwd: runtimePath, + }); + if (install2Err) { + throw new Error(install2Err); + } + composer.log('BUILD COMPLETE'); + }, + run: async (project: any, localDisk: IFileStorage) => { + // do stuff + }, + buildDeploy: async (runtimePath: string, project: any, settings: any, profileName: string): Promise => { + // do stuff + composer.log('BUILD THIS JS PROJECT'); + const { stderr: installErr } = await execAsync('npm install', { + cwd: path.resolve(runtimePath, '../'), + }); + if (installErr) { + composer.log(installErr); + } + const { stderr: install2Err } = await execAsync('npm run build', { + cwd: path.resolve(runtimePath, '../'), + }); + if (install2Err) { + throw new Error(install2Err); + } + // write settings to disk in the appropriate location + const settingsPath = path.join(runtimePath, 'ComposerDialogs', 'settings', 'appsettings.json'); + if (!(await fs.pathExists(path.dirname(settingsPath)))) { + await fs.mkdirp(path.dirname(settingsPath)); + } + await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2)); + + composer.log('BUILD COMPLETE'); + return path.resolve(runtimePath, '../'); + }, + eject: async (project: any, localDisk: IFileStorage, isReplace: boolean) => { + const sourcePath = path.resolve(__dirname, '../../../../runtime/node'); + const destPath = path.join(project.dir, 'runtime'); + + if ((await project.fileStorage.exists(destPath)) && isReplace) { + // remove runtime folder + await removeDirAndFiles(destPath); + } + + if (!(await project.fileStorage.exists(destPath))) { + // used to read bot project template from source (bundled in plugin) + const excludeFolder = new Set().add(path.resolve(sourcePath, 'node_modules')); + await copyDir(sourcePath, localDisk, destPath, project.fileStorage, excludeFolder); + // install dev dependencies in production, make sure typescript is installed + const { stderr: initErr } = await execAsync('npm install && npm install --only=dev', { + cwd: destPath, + }); + if (initErr) { + composer.log(initErr); + } + const { stderr: initErr2 } = await execAsync('npm run build', { cwd: destPath }); + if (initErr2) { + throw new Error(initErr2); + } + return destPath; + } else { + throw new Error(`Runtime already exists at ${destPath}`); + } + }, + setSkillManifest: async ( + dstRuntimePath: string, + dstStorage: IFileStorage, + srcManifestDir: string, + srcStorage: IFileStorage, + mode = 'azurewebapp' + ) => {}, + }); +}; diff --git a/Composer/plugins/localPublish/src/interface.ts b/Composer/plugins/runtimes/src/interface.ts similarity index 100% rename from Composer/plugins/localPublish/src/interface.ts rename to Composer/plugins/runtimes/src/interface.ts diff --git a/Composer/plugins/azureFunctionsPublish/tsconfig.json b/Composer/plugins/runtimes/tsconfig.json similarity index 99% rename from Composer/plugins/azureFunctionsPublish/tsconfig.json rename to Composer/plugins/runtimes/tsconfig.json index 13305de8f2..2824efac1d 100644 --- a/Composer/plugins/azureFunctionsPublish/tsconfig.json +++ b/Composer/plugins/runtimes/tsconfig.json @@ -5,9 +5,9 @@ "declaration": true, "sourceMap": true, "esModuleInterop": true, - "skipLibCheck": true, "outDir": "./lib", "rootDir": "./src", + "skipLibCheck": true, "types": [ "node" ] @@ -18,4 +18,4 @@ "exclude": [ "node_modules" ] -} \ No newline at end of file +} diff --git a/Composer/plugins/runtimes/yarn.lock b/Composer/plugins/runtimes/yarn.lock new file mode 100644 index 0000000000..41e59ff0f7 --- /dev/null +++ b/Composer/plugins/runtimes/yarn.lock @@ -0,0 +1,141 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +fs-extra@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" + integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +jsonfile@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" + integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg== + dependencies: + universalify "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.npmjs.org/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= + dependencies: + process "^0.11.1" + util "^0.10.3" + +process@^0.11.1: + version "0.11.10" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.npmjs.org/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= diff --git a/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/repeatdialog/repeatdialog.dialog b/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/repeatdialog/repeatdialog.dialog index facccb7bfe..b9965de319 100644 --- a/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/repeatdialog/repeatdialog.dialog +++ b/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/repeatdialog/repeatdialog.dialog @@ -24,7 +24,7 @@ "alwaysPrompt": true, "allowInterruptions": "false", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/switchcondition/switchcondition.dialog b/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/switchcondition/switchcondition.dialog index c369288815..fb0cbdbc84 100644 --- a/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/switchcondition/switchcondition.dialog +++ b/Composer/plugins/samples/assets/projects/ActionsSample/dialogs/switchcondition/switchcondition.dialog @@ -31,9 +31,8 @@ "value": "Test3" } ], - "appendChoices": true, "defaultLocale": "en-us", - "style": "List", + "style": "list", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/choiceinput/choiceinput.dialog b/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/choiceinput/choiceinput.dialog index cca87a34fa..b13139795f 100644 --- a/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/choiceinput/choiceinput.dialog +++ b/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/choiceinput/choiceinput.dialog @@ -35,9 +35,8 @@ "value": "Test3" } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "List", + "style": "list", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/confirminput/confirminput.dialog b/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/confirminput/confirminput.dialog index 2c211c0ae9..0504adf6d9 100644 --- a/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/confirminput/confirminput.dialog +++ b/Composer/plugins/samples/assets/projects/AskingQuestionsSample/dialogs/confirminput/confirminput.dialog @@ -23,7 +23,7 @@ "alwaysPrompt": true, "allowInterruptions": "false", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/repeatdialog/repeatdialog.dialog b/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/repeatdialog/repeatdialog.dialog index 8ef7f75636..5018c49ee0 100644 --- a/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/repeatdialog/repeatdialog.dialog +++ b/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/repeatdialog/repeatdialog.dialog @@ -24,7 +24,7 @@ "alwaysPrompt": true, "allowInterruptions": "false", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/switchcondition/switchcondition.dialog b/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/switchcondition/switchcondition.dialog index cfcd8fffba..2fc987677c 100644 --- a/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/switchcondition/switchcondition.dialog +++ b/Composer/plugins/samples/assets/projects/ControllingConversationFlowSample/dialogs/switchcondition/switchcondition.dialog @@ -34,9 +34,8 @@ "value": "Tom" } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "List", + "style": "list", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/QnAMakerLUISSample/qnamakerluissample.dialog b/Composer/plugins/samples/assets/projects/QnAMakerLUISSample/qnamakerluissample.dialog index df1d05a856..41469218db 100644 --- a/Composer/plugins/samples/assets/projects/QnAMakerLUISSample/qnamakerluissample.dialog +++ b/Composer/plugins/samples/assets/projects/QnAMakerLUISSample/qnamakerluissample.dialog @@ -49,7 +49,7 @@ "$designer": { "id": "242409" }, - "condition": "#Help.Score >= 0.8", + "condition": "#Help.Score >= 0.6", "actions": [ { "$kind": "Microsoft.SendActivity", @@ -90,7 +90,7 @@ "$designer": { "id": "872754" }, - "condition": "#BuySurface.Score >= 0.8", + "condition": "#BuySurface.Score >= 0.6", "actions": [ { "$kind": "Microsoft.SendActivity", diff --git a/Composer/plugins/samples/assets/projects/RespondingWithCardsSample/respondingwithcardssample.dialog b/Composer/plugins/samples/assets/projects/RespondingWithCardsSample/respondingwithcardssample.dialog index e5c0a118b5..31b807760f 100644 --- a/Composer/plugins/samples/assets/projects/RespondingWithCardsSample/respondingwithcardssample.dialog +++ b/Composer/plugins/samples/assets/projects/RespondingWithCardsSample/respondingwithcardssample.dialog @@ -50,9 +50,8 @@ "value": "AllCards" } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "List", + "style": "list", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/RespondingWithTextSample/dialogs/ifelsecondition/ifelsecondition.dialog b/Composer/plugins/samples/assets/projects/RespondingWithTextSample/dialogs/ifelsecondition/ifelsecondition.dialog index 369d011a0b..4684cbe59a 100644 --- a/Composer/plugins/samples/assets/projects/RespondingWithTextSample/dialogs/ifelsecondition/ifelsecondition.dialog +++ b/Composer/plugins/samples/assets/projects/RespondingWithTextSample/dialogs/ifelsecondition/ifelsecondition.dialog @@ -37,9 +37,8 @@ "value": "evening" } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/RespondingWithTextSample/respondingwithtextsample.dialog b/Composer/plugins/samples/assets/projects/RespondingWithTextSample/respondingwithtextsample.dialog index 27b6f5b4a2..12dccba6fd 100644 --- a/Composer/plugins/samples/assets/projects/RespondingWithTextSample/respondingwithtextsample.dialog +++ b/Composer/plugins/samples/assets/projects/RespondingWithTextSample/respondingwithtextsample.dialog @@ -98,9 +98,8 @@ "value": "SwitchCondition" } ], - "appendChoices": true, "defaultLocale": "en-us", - "style": "List", + "style": "list", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/additem/additem.dialog b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/additem/additem.dialog index 4f4c68af5f..b62d46d10c 100644 --- a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/additem/additem.dialog +++ b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/additem/additem.dialog @@ -75,9 +75,8 @@ ] } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/deleteitem/deleteitem.dialog b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/deleteitem/deleteitem.dialog index 1e64aee039..a98a5b8ff2 100644 --- a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/deleteitem/deleteitem.dialog +++ b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/deleteitem/deleteitem.dialog @@ -63,9 +63,8 @@ ] } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", @@ -133,9 +132,8 @@ "allowInterruptions": "!@itemTitle && !@number", "outputFormat": "value", "choices": "=user.lists[dialog.listType]", - "appendChoices": "true", "defaultLocale": "en-us", - "style": "List", + "style": "list", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/viewitem/viewitem.dialog b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/viewitem/viewitem.dialog index 7142b340d1..197022b341 100644 --- a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/viewitem/viewitem.dialog +++ b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/dialogs/viewitem/viewitem.dialog @@ -53,9 +53,8 @@ ] } ], - "appendChoices": "true", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/todobotwithluissample.dialog b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/todobotwithluissample.dialog index 3ffcfb3738..27defc38a7 100644 --- a/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/todobotwithluissample.dialog +++ b/Composer/plugins/samples/assets/projects/ToDoBotWithLuisSample/todobotwithluissample.dialog @@ -76,7 +76,7 @@ "id": "263959" }, "intent": "Add", - "condition": "#Add.Score > 0.8", + "condition": "#Add.Score > 0.6", "actions": [ { "$kind": "Microsoft.BeginDialog", @@ -95,7 +95,7 @@ "id": "100671" }, "intent": "Delete", - "condition": "#Delete.Score > 0.8", + "condition": "#Delete.Score > 0.6", "actions": [ { "$kind": "Microsoft.BeginDialog", @@ -114,7 +114,7 @@ "id": "660567" }, "intent": "View", - "condition": "#View.Score > 0.8", + "condition": "#View.Score > 0.6", "actions": [ { "$kind": "Microsoft.BeginDialog", @@ -133,7 +133,7 @@ "id": "802923" }, "intent": "UserProfile", - "condition": "#UserProfile.Score > 0.8", + "condition": "#UserProfile.Score > 0.6", "actions": [ { "$kind": "Microsoft.BeginDialog", @@ -152,7 +152,7 @@ "id": "732966" }, "intent": "whatCanYouDo", - "condition": "#whatCanYouDo.Score > 0.8", + "condition": "#whatCanYouDo.Score > 0.6", "actions": [ { "$kind": "Microsoft.BeginDialog", @@ -171,7 +171,7 @@ "id": "683937" }, "intent": "cancel", - "condition": "#cancel.Score > 0.8", + "condition": "#cancel.Score > 0.6", "actions": [ { "$kind": "Microsoft.ConfirmInput", @@ -185,7 +185,7 @@ "value": "=@confirmation", "allowInterruptions": "!@confirmation", "defaultLocale": "en-us", - "style": "Auto", + "style": "auto", "choiceOptions": { "inlineSeparator": ", ", "inlineOr": " or ", diff --git a/Composer/plugins/samples/yarn.lock b/Composer/plugins/samples/yarn.lock new file mode 100644 index 0000000000..91d07afb9a --- /dev/null +++ b/Composer/plugins/samples/yarn.lock @@ -0,0 +1,157 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +debug@^3.1.1: + version "3.2.6" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +lodash@^4.17.14: + version "4.17.17" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.17.tgz#d9018b3acc57a95c9dcf4a45c6b63b877b6c2d45" + integrity sha512-/B2DjOphAoqi5BX4Gg2oh4UR0Gy/A7xYAMh3aSECEKzwS3eCDEpS0Cals1Ktvxwlal3bBJNc+5W9kNIcADdw5Q== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.1: + version "0.5.5" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.npmjs.org/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= + dependencies: + process "^0.11.1" + util "^0.10.3" + +portfinder@^1.0.26: + version "1.0.26" + resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" + integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +process@^0.11.1: + version "0.11.10" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.npmjs.org/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +uuid@^7.0.1: + version "7.0.3" + resolved "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= diff --git a/runtime/dotnet/azurefunctions/Microsoft.BotFramework.Composer.Functions.csproj b/runtime/dotnet/azurefunctions/Microsoft.BotFramework.Composer.Functions.csproj index a84650f59e..cea4e7d423 100644 --- a/runtime/dotnet/azurefunctions/Microsoft.BotFramework.Composer.Functions.csproj +++ b/runtime/dotnet/azurefunctions/Microsoft.BotFramework.Composer.Functions.csproj @@ -40,12 +40,6 @@ - - Always - - - Always - Always diff --git a/runtime/dotnet/azurefunctions/Startup.cs b/runtime/dotnet/azurefunctions/Startup.cs index 060033c9d1..fcbbe538c8 100644 --- a/runtime/dotnet/azurefunctions/Startup.cs +++ b/runtime/dotnet/azurefunctions/Startup.cs @@ -43,19 +43,15 @@ private IConfigurationRoot BuildConfiguration(string rootDirectory) var config = new ConfigurationBuilder(); // Config precedence 1: root app.settings - config - .SetBasePath(rootDirectory) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .UseLuisConfigAdapter() - .UseLuisSettings(); + config.SetBasePath(rootDirectory); // Config precedence 2: ComposerDialogs/settings settings which are injected by the composer publish // Hard code the settings path to 'ComposerDialogs' for deployment + var configFile = Path.GetFullPath(Path.Combine(rootDirectory, @"ComposerDialogs/settings/appsettings.json")); config.AddJsonFile(configFile, optional: true, reloadOnChange: true); - // Config Precedence 3: Deployment specific config - config.AddJsonFile("appsettings.deployment.json", optional: true, reloadOnChange: true); + config.UseComposerLuisSettings(); if (!Debugger.IsAttached) { diff --git a/runtime/dotnet/azurefunctions/appsettings.Deployment.json b/runtime/dotnet/azurefunctions/appsettings.Deployment.json deleted file mode 100644 index 5b9a266f9e..0000000000 --- a/runtime/dotnet/azurefunctions/appsettings.Deployment.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "bot": "ComposerDialogs", - "root": "ComposerDialogs" -} \ No newline at end of file diff --git a/runtime/dotnet/azurefunctions/appsettings.Development.json b/runtime/dotnet/azurefunctions/appsettings.Development.json deleted file mode 100644 index 32b3ba9cf9..0000000000 --- a/runtime/dotnet/azurefunctions/appsettings.Development.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "bot": "../", - "root": "../" -} diff --git a/runtime/dotnet/azurefunctions/appsettings.json b/runtime/dotnet/azurefunctions/appsettings.json deleted file mode 100644 index 8b60e096e8..0000000000 --- a/runtime/dotnet/azurefunctions/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "feature": { - "UseShowTypingMiddleware": false, - "UseInspectionMiddleware": false, - "RemoveRecipientMention": false - }, - "microsoftAppId": "", - "cosmosDb": { - "authKey": "", - "collectionId": "botstate-collection", - "cosmosDBEndpoint": "", - "databaseId": "botstate-db" - }, - "applicationInsights": { - "InstrumentationKey": "" - }, - "telemetry": { - "logPersonalInformation": false, - "logActivities": true - }, - "blobStorage": { - "connectionString": "", - "container": "transcripts" - } -} diff --git a/runtime/dotnet/azurewebapp/Program.cs b/runtime/dotnet/azurewebapp/Program.cs index e080ee0004..de3da52710 100644 --- a/runtime/dotnet/azurewebapp/Program.cs +++ b/runtime/dotnet/azurewebapp/Program.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Collections.Generic; -using System.Diagnostics; using System.IO; -using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Bot.Builder.AI.Luis; using Microsoft.BotFramework.Composer.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; @@ -27,13 +22,8 @@ public static IHostBuilder CreateHostBuilder(string[] args) => { var env = hostingContext.HostingEnvironment; - builder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); - - if (env.IsDevelopment()) - { - // Local Debug - builder.AddJsonFile("appsettings.development.json", optional: true, reloadOnChange: true); - } + // Use Composer bot path adapter + builder.UseBotPathConverter(env.IsDevelopment()); var configuration = builder.Build(); @@ -43,15 +33,8 @@ public static IHostBuilder CreateHostBuilder(string[] args) => builder.AddJsonFile(configFile, optional: true, reloadOnChange: true); - // Need to put this part here to override the any customized settings - if (!env.IsDevelopment()) - { - //Azure Deploy - builder.AddJsonFile("appsettings.deployment.json", optional: true, reloadOnChange: true); - } - - builder.UseLuisConfigAdapter() - .UseLuisSettings(); + // Use Composer luis settings extensions + builder.UseComposerLuisSettings(); builder.AddEnvironmentVariables() .AddCommandLine(args); diff --git a/runtime/dotnet/azurewebapp/appsettings.Deployment.json b/runtime/dotnet/azurewebapp/appsettings.Deployment.json deleted file mode 100644 index 5b9a266f9e..0000000000 --- a/runtime/dotnet/azurewebapp/appsettings.Deployment.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "bot": "ComposerDialogs", - "root": "ComposerDialogs" -} \ No newline at end of file diff --git a/runtime/dotnet/azurewebapp/appsettings.Development.json b/runtime/dotnet/azurewebapp/appsettings.Development.json deleted file mode 100644 index edb1022967..0000000000 --- a/runtime/dotnet/azurewebapp/appsettings.Development.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "bot": "../../", - "root": "../../" -} diff --git a/runtime/dotnet/azurewebapp/appsettings.json b/runtime/dotnet/azurewebapp/appsettings.json deleted file mode 100644 index 8b60e096e8..0000000000 --- a/runtime/dotnet/azurewebapp/appsettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "feature": { - "UseShowTypingMiddleware": false, - "UseInspectionMiddleware": false, - "RemoveRecipientMention": false - }, - "microsoftAppId": "", - "cosmosDb": { - "authKey": "", - "collectionId": "botstate-collection", - "cosmosDBEndpoint": "", - "databaseId": "botstate-db" - }, - "applicationInsights": { - "InstrumentationKey": "" - }, - "telemetry": { - "logPersonalInformation": false, - "logActivities": true - }, - "blobStorage": { - "connectionString": "", - "container": "transcripts" - } -} diff --git a/runtime/dotnet/core/ComposerBotPathExtensions.cs b/runtime/dotnet/core/ComposerBotPathExtensions.cs new file mode 100644 index 0000000000..f2d2e953fc --- /dev/null +++ b/runtime/dotnet/core/ComposerBotPathExtensions.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Extensions.Configuration; +using System.Collections.Generic; + +namespace Microsoft.BotFramework.Composer.Core +{ + /// + /// Bot path adapter, for development environment, use '../../' as the bot path, for deployment and production environment, use 'ComposerDialogs' as bot path + /// + public static class ComposerBotPathExtensions + { + public static IConfigurationBuilder UseBotPathConverter(this IConfigurationBuilder builder, bool isDevelopment = true) + { + var settings = new Dictionary(); + if (isDevelopment) + { + settings["bot"] = "../../"; + } + else + { + settings["bot"] = "ComposerDialogs"; + } + builder.AddInMemoryCollection(settings); + return builder; + } + } +} diff --git a/runtime/dotnet/core/ComposerLuisExtensions.cs b/runtime/dotnet/core/ComposerLuisExtensions.cs new file mode 100644 index 0000000000..1fc3943123 --- /dev/null +++ b/runtime/dotnet/core/ComposerLuisExtensions.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.BotFramework.Composer.Core +{ + public static class ComposerLuisExtensions + { + /// + /// Setup configuration to utilize the settings file generated by bf luis:build. This is a luis settings extensions adapter aligning with Composer customized settings. + /// + /// + /// This will pick up LUIS_AUTHORING_REGION or --region settings as the setting to target. + /// This will pick up --environment as the environment to target. If environment is Development it will use the name of the logged in user. + /// This will pick up --root as the root folder to run in. + /// + /// Configuration builder to modify. + /// Modified configuration builder. + public static IConfigurationBuilder UseComposerLuisSettings(this IConfigurationBuilder builder) + { + var configuration = builder.Build(); + var botRoot = configuration.GetValue("bot") ?? "."; + var luisRegion = configuration.GetValue("LUIS_AUTHORING_REGION") ?? configuration.GetValue("luis:authoringRegion") ?? configuration.GetValue("luis:region") ?? "westus"; + var environment = configuration.GetValue("luis:environment") ?? Environment.UserName; + var settings = new Dictionary(); + settings["luis:endpoint"] = configuration.GetValue("luis:endpoint") ?? $"https://{luisRegion}.api.cognitive.microsoft.com"; + settings["BotRoot"] = botRoot; + builder.AddInMemoryCollection(settings); + if (environment == "Development") + { + environment = Environment.UserName; + } + + var settingsPath = Path.GetFullPath(Path.Combine(botRoot, "generated", $"luis.settings.{environment.ToLower()}.{luisRegion}.json")); + var settingsFile = new FileInfo(settingsPath); + if (settingsFile.Exists) + { + builder.AddJsonFile(settingsFile.FullName, optional: false, reloadOnChange: true); + } + + return builder; + } + } +} diff --git a/runtime/dotnet/core/LuisConfigAdapter.cs b/runtime/dotnet/core/LuisConfigAdapter.cs deleted file mode 100644 index c879fd1494..0000000000 --- a/runtime/dotnet/core/LuisConfigAdapter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; - -namespace Microsoft.BotFramework.Composer.Core -{ - public static class LuisConfigAdapter - { - public static IConfigurationBuilder UseLuisConfigAdapter(this IConfigurationBuilder builder) - { - var configuration = builder.Build(); - var settings = new Dictionary(); - settings["environment"] = configuration.GetValue("luis:environment"); - settings["region"] = configuration.GetValue("luis:authoringRegion"); - builder.AddInMemoryCollection(settings); - return builder; - } - } -} diff --git a/runtime/node/.deployment b/runtime/node/.deployment new file mode 100644 index 0000000000..6278331818 --- /dev/null +++ b/runtime/node/.deployment @@ -0,0 +1,2 @@ +[config] +SCM_DO_BUILD_DURING_DEPLOYMENT=true \ No newline at end of file diff --git a/runtime/node/.eslintrc.js b/runtime/node/.eslintrc.js new file mode 100644 index 0000000000..bf92ed9223 --- /dev/null +++ b/runtime/node/.eslintrc.js @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'prettier/@typescript-eslint', + 'plugin:prettier/recommended', + ], + parser: '@typescript-eslint/parser', // Specifies the ESLint parser + parserOptions: { + ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + project: './tsconfig.json', + tsconfigRootDir: __dirname + }, +}; diff --git a/runtime/node/.gitignore b/runtime/node/.gitignore new file mode 100644 index 0000000000..29859bd49d --- /dev/null +++ b/runtime/node/.gitignore @@ -0,0 +1,2 @@ +node_modules +lib \ No newline at end of file diff --git a/runtime/node/.prettierrc b/runtime/node/.prettierrc new file mode 100644 index 0000000000..b605678dbb --- /dev/null +++ b/runtime/node/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 120, + "parser": "typescript", + "singleQuote": true, + "tabWidth": 2, + "endOfLine": "auto" +} diff --git a/runtime/node/README.md b/runtime/node/README.md index 7d450c961c..58670b365b 100644 --- a/runtime/node/README.md +++ b/runtime/node/README.md @@ -1,7 +1,19 @@ -# Node.js bot runtime - -# Folder structure - -- **core**: Includes all core Node.js runtime logic, independent of hosting technology. -- **technology specific folders**: Each hosting technology has one folder in this directory. For example, for Azure Functions, there is an `azurefunction` folder - - **tests**: Node.js runtime tests +# Node.js bot launcher for Azure WebApp and Azure Functions + +# Folder structure + +- **shared**: Includes all core JavaScript runtime logic, independent of hosting technology. +- **webapp**: server code for azure webapp services +- **functions** server code for azure functions +- **__tests__**: Javascript runtime tests + +# Installation before use + +For all users need to install npm before start composer. + +## for windows users + + * user need to install `windows-build-tools` before start composer. By running `npm install --global windows-build-tools`. Otherwise it may throw `gyp build Err` during npm install, because we use `restify` as server and its dependency `dtrace-provider` need `gyp` to build. + +## for Mac users + * user need to have `xcode-select` before start composer. Otherwise it may throw `gyp build Err` during npm install. You can install or re-install it by running `sudo rm -rf $(xcode-select -print-path)`, `xcode-select --install` then `sudo xcode-select -s /Applications/Xcode.app/Contents/Developer` diff --git a/runtime/node/__tests__/actions.test.ts b/runtime/node/__tests__/actions.test.ts new file mode 100644 index 0000000000..b91ff84c37 --- /dev/null +++ b/runtime/node/__tests__/actions.test.ts @@ -0,0 +1,274 @@ +import * as path from "path"; +import { ResourceExplorer } from "botbuilder-dialogs-declarative"; +import { AdaptiveDialogComponentRegistration } from "botbuilder-dialogs-adaptive"; +import { + TestAdapter, + ConversationState, + MemoryStorage, + UserState, +} from "botbuilder"; +import { ComposerBot } from "../src/shared/composerBot"; +import { SkillConversationIdFactory } from "../src/shared/skillConversationIdFactory"; +import * as helpers from "../src/shared/helpers"; +import { ActivityTypes, Activity, ChannelAccount } from "botframework-schema"; +import { TurnContext } from "botbuilder-core"; + +const samplesDirectory = path.resolve( + __dirname, + "../../../Composer/plugins/samples/assets/projects", + "ActionsSample" +); + +const resourceExplorer = new ResourceExplorer(); +const basicActiivty: Partial = { + channelId: "test", + serviceUrl: "https://test.com", + from: { id: "user1", name: "User1" }, + recipient: { id: "bot", name: "Bot" }, + locale: "en-us", + conversation: { + isGroup: false, + conversationType: "testFlowConversationId", + id: "testFlowConversationId", + tenantId: "test", + name: "test", + }, +}; + +const conversationUpdateActivity = { + ...basicActiivty, + type: ActivityTypes.ConversationUpdate, + membersAdded: [{ id: "test", name: "testAccount" } as ChannelAccount], + membersRemoved: [], +} as Activity; + +let bot: ComposerBot; +let adapter: TestAdapter; + +const getProjectRoot = jest + .spyOn(helpers, "getProjectRoot") + .mockImplementation(() => samplesDirectory); +const getSettings = jest + .spyOn(helpers, "getSettings") + .mockImplementation((root: string) => { + return { defaultLocale: "en-us" }; + }); + +beforeAll(() => { + resourceExplorer.addFolders(samplesDirectory, ["runtime"], false); + resourceExplorer.addComponent( + new AdaptiveDialogComponentRegistration(resourceExplorer) + ); + adapter = new TestAdapter( + async (context: TurnContext): Promise => { + // Route activity to bot. + return await bot.onTurnActivity(context); + }, + basicActiivty, + false + ); +}); + +beforeEach(() => { + const memoryStorage = new MemoryStorage(); + + // Create shared user state and conversation state instances. + const userState = new UserState(memoryStorage); + const conversationState = new ConversationState(memoryStorage); + // Create shared skill conversation id factory instance. + const skillConversationIdFactory = new SkillConversationIdFactory(); + bot = new ComposerBot( + userState, + conversationState, + skillConversationIdFactory + ); +}); + +afterEach(() => { + // adapter = null; + bot = null; +}); + +describe("test runtime used ActionsSample", () => { + it("Actions_01Actions", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("01") + .assertReply("Step 1") + .assertReply("Step 2") + .assertReply("Step 3") + .assertReply("user.age is set to 18") + .assertReply("user.age is set to null") + .startTest(); + }); + + it("Actions_02EndTurn", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("02") + .assertReply("What's up?") + .send("Nothing") + .assertReply("Oh I see!") + .startTest(); + }); + it("Actions_03IfCondition", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("03") + .assertReply("Hello, I'm Zoidberg. What is your name?") + .send("Carlos") + .assertReply("Hello Carlos, nice to talk to you!") + .startTest(); + }); + it("Actions_04EditArray", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("04") + .assertReply("Here are the index and values in the array.") + .assertReply("0: 11111") + .assertReply("1: 40000") + .assertReply("2: 222222") + .assertReply( + "If each page shows two items, here are the index and values" + ) + .assertReply("0: 11111") + .assertReply("1: 40000") + .assertReply("0: 222222") + .startTest(); + }); + it("Actions_05EndDialog", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("05") + .assertReply("Hello, I'm Zoidberg. What is your name?") + .send("luhan") + .assertReply("Hello luhan, nice to talk to you!") + .assertReply('I\'m a joke bot. To get started say "joke".') + .send("joke") + .assertReply("Why did the chicken cross the road?") + .send("I don't know") + .assertReply("To get to the other side!") + .startTest(); + }); + + it("Actions_06SwitchCondition", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("07") + .assertReply( + "Please select a value from below:\n\n 1. Test1\n 2. Test2\n 3. Test3" + ) + .send("Test1") + .assertReply("You select: Test1") + .assertReply("You select: 1") + .startTest(); + }); + + it("Actions_07RepeatDialog", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("08") + .assertReply( + "Do you want to repeat this dialog, yes to repeat, no to end this dialog (1) Yes or (2) No" + ) + .send("Yes") + .assertReply( + "Do you want to repeat this dialog, yes to repeat, no to end this dialog (1) Yes or (2) No" + ) + .send("No") + .startTest(); + }); + it("Actions_09EditActions", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("10") + .assertReply("Hello, I'm Zoidberg. What is your name?") + .send("luhan") + .assertReply("Hello luhan, nice to talk to you!") + .assertReply("Goodbye!") + .startTest(); + }); + it("Actions_10ReplaceDialog", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("11") + .assertReply("Hello, I'm Zoidberg. What is your name?") + .send("luhan") + .assertReply( + "Hello luhan, nice to talk to you! Please either enter 'joke' or 'fortune' to replace the dialog you want." + ) + .send("joke") + .assertReply("Why did the chicken cross the road?") + .send("Why?") + .assertReply("To get to the other side!") + .send("future") + .assertReply("Seeing into your future...") + .assertReply("I see great things in your future!") + .assertReply("Potentially a successful demo") + .startTest(); + }); + it("Actions_11EmitEvent", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("12") + .assertReply("Say moo to get a response, say emit to emit a event.") + .send("moo") + .assertReply("Yippee ki-yay!") + .send("emit") + .assertReply("CustomEvent Fired.") + .startTest(); + }); + + it("Actions_08TraceAndLog", async () => { + // use different adapter to support trace activity + adapter = new TestAdapter( + async (context: TurnContext): Promise => { + // Route activity to bot. + return await bot.onTurnActivity(context); + }, + basicActiivty, + true + ); + await adapter + .send(conversationUpdateActivity) + .assertReply( + "I can show you examples on how to use actions. Enter the number next to the entity that you with to see in action.\n01 - Actions\n02 - EndTurn\n03 - IfCondiftion\n04 - EditArray, Foreach\n05 - EndDialog\n06 - HttpRequest\n07 - SwitchCondition\n08 - RepeatDialog\n09 - TraceAndLog\n10 - EditActions\n11 - ReplaceDialog\n12 - EmitEvent\n13 - QnAMaker" + ) + .send("09") + .send("luhan") + .assertReply((activity) => { + expect(activity.type).toBe(ActivityTypes.Trace); + }) + .startTest(); + }); +}); diff --git a/runtime/node/__tests__/controllingConversation.test.ts b/runtime/node/__tests__/controllingConversation.test.ts new file mode 100644 index 0000000000..4f452de7f6 --- /dev/null +++ b/runtime/node/__tests__/controllingConversation.test.ts @@ -0,0 +1,142 @@ +import * as path from "path"; +import { ResourceExplorer } from "botbuilder-dialogs-declarative"; +import { AdaptiveDialogComponentRegistration } from "botbuilder-dialogs-adaptive"; +import { + TestAdapter, + ConversationState, + MemoryStorage, + UserState, +} from "botbuilder"; +import { ComposerBot } from "../src/shared/composerBot"; +import { ActivityTypes, Activity, ChannelAccount } from "botframework-schema"; +import { TurnContext } from "botbuilder-core"; +import * as helpers from "../src/shared/helpers"; +import { SkillConversationIdFactory } from "../src/shared/skillConversationIdFactory"; + +const samplesDirectory = path.resolve( + __dirname, + "../../../Composer/plugins/samples/assets/projects", + "ControllingConversationFlowSample" +); + +const resourceExplorer = new ResourceExplorer(); +const basicActiivty: Partial = { + channelId: "test", + serviceUrl: "https://test.com", + from: { id: "user1", name: "User1" }, + recipient: { id: "bot", name: "Bot" }, + locale: "en-us", + conversation: { + isGroup: false, + conversationType: "testFlowConversationId", + id: "testFlowConversationId", + tenantId: "test", + name: "test", + }, +}; + +const conversationUpdateActivity = { + ...basicActiivty, + type: ActivityTypes.ConversationUpdate, + membersAdded: [{ id: "test", name: "testAccount" } as ChannelAccount], + membersRemoved: [], +} as Activity; + +const getProjectRoot = jest + .spyOn(helpers, "getProjectRoot") + .mockImplementation(() => samplesDirectory); +const getSettings = jest + .spyOn(helpers, "getSettings") + .mockImplementation((root: string) => { + return { defaultLocale: "en-us" }; + }); + +let bot: ComposerBot; +let adapter: TestAdapter; + +beforeAll(() => { + resourceExplorer.addFolders(samplesDirectory, ["runtime"], false); + resourceExplorer.addComponent( + new AdaptiveDialogComponentRegistration(resourceExplorer) + ); + adapter = new TestAdapter( + async (context: TurnContext): Promise => { + // Route activity to bot. + return await bot.onTurnActivity(context); + }, + basicActiivty, + false + ); + + const memoryStorage = new MemoryStorage(); + + // Create shared user state and conversation state instances. + const userState = new UserState(memoryStorage); + const conversationState = new ConversationState(memoryStorage); + // Create shared skill conversation id factory instance. + const skillConversationIdFactory = new SkillConversationIdFactory(); + bot = new ComposerBot( + userState, + conversationState, + skillConversationIdFactory + ); +}); +afterAll(() => { + bot = null; + adapter = null; +}); +describe("test runtime used ControllingConversationFlowSample", () => { + it("runtime can Controlling Conversation", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + 'Welcome to the Controlling Conversation sample. Choose from the list below to try.\nYou can also type "Cancel" to cancel any dialog or "Endturn" to explicitly accept an input.' + ) + .send("01") + .assertReply("Hello, What's your age?") + .send("18") + .assertReply( + "Your age is 18 which satisified the condition that was evaluated" + ) + .send("02") + .assertReply("Who are your?\n\n 1. Susan\n 2. Nick\n 3. Tom") + .send("2") + .assertReply("You selected Nick") + .assertReply('This is the logic inside the "Nick" switch block.') + .send("03") + .assertReply("Pushed dialog.id into a list") + .assertReply("0: 11111") + .assertReply("1: 40000") + .assertReply("2: 222222") + .send("04") + .assertReply("Pushed dialog.ids into a list") + .assertReply("0: 11111") + .assertReply("1: 40000") + .assertReply("0: 222222") + .send("06") + .send("hi") + .send("07") + .assertReply( + "Do you want to repeat this dialog, yes to repeat, no to end this dialog (1) Yes or (2) No" + ) + .send("Yes") + .assertReply( + "Do you want to repeat this dialog, yes to repeat, no to end this dialog (1) Yes or (2) No" + ) + .send("No") + .send("08") + .assertReply("In continue loop, which only outputs dual.") + .assertReply("index: 1 value: 2") + .assertReply("index: 3 value: 4") + .assertReply("index: 5 value: 6") + .assertReply("In break loop, which breaks when index > 2") + .assertReply("index: 0 value: 1") + .assertReply("index: 1 value: 2") + .assertReply("index: 2 value: 3") + .assertReply("done") + .send("09") + .assertReply("counter: 1") + .assertReply("counter: 2") + .startTest(); + }); +}); diff --git a/runtime/node/__tests__/inputs.test.ts b/runtime/node/__tests__/inputs.test.ts new file mode 100644 index 0000000000..5bedd40366 --- /dev/null +++ b/runtime/node/__tests__/inputs.test.ts @@ -0,0 +1,157 @@ +import * as path from "path"; +import { ResourceExplorer } from "botbuilder-dialogs-declarative"; +import { AdaptiveDialogComponentRegistration } from "botbuilder-dialogs-adaptive"; +import { + TestAdapter, + ConversationState, + MemoryStorage, + UserState, +} from "botbuilder"; +import { ComposerBot } from "../src/shared/composerBot"; +import { ActivityTypes, Activity, ChannelAccount } from "botframework-schema"; +import { TurnContext } from "botbuilder-core"; +import { SkillConversationIdFactory } from "../src/shared/skillConversationIdFactory"; +import * as helpers from "../src/shared/helpers"; + +const samplesDirectory = path.resolve( + __dirname, + "../../../Composer/plugins/samples/assets/projects", + "AskingQuestionsSample" +); + +const resourceExplorer = new ResourceExplorer(); +const basicActiivty: Partial = { + channelId: "test", + serviceUrl: "https://test.com", + from: { id: "user1", name: "User1" }, + recipient: { id: "bot", name: "Bot" }, + locale: "en-us", + conversation: { + isGroup: false, + conversationType: "testFlowConversationId", + id: "testFlowConversationId", + tenantId: "test", + name: "test", + }, +}; + +const conversationUpdateActivity = { + ...basicActiivty, + type: ActivityTypes.ConversationUpdate, + membersAdded: [{ id: "test", name: "testAccount" } as ChannelAccount], + membersRemoved: [], +} as Activity; + +const getProjectRoot = jest + .spyOn(helpers, "getProjectRoot") + .mockImplementation(() => samplesDirectory); +const getSettings = jest + .spyOn(helpers, "getSettings") + .mockImplementation((root: string) => { + return { defaultLocale: "en-us" }; + }); + +let bot: ComposerBot; +let adapter: TestAdapter; +beforeAll(() => { + resourceExplorer.addFolders(samplesDirectory, ["runtime"], false); + resourceExplorer.addComponent( + new AdaptiveDialogComponentRegistration(resourceExplorer) + ); + adapter = new TestAdapter( + async (context: TurnContext): Promise => { + // Route activity to bot. + await bot.onTurnActivity(context); + }, + basicActiivty, + false + ); + + const memoryStorage = new MemoryStorage(); + + // Create shared user state and conversation state instances. + const userState = new UserState(memoryStorage); + const conversationState = new ConversationState(memoryStorage); + // Create shared skill conversation id factory instance. + const skillConversationIdFactory = new SkillConversationIdFactory(); + bot = new ComposerBot( + userState, + conversationState, + skillConversationIdFactory + ); +}); +afterAll(() => { + bot = null; + adapter = null; +}); +describe("test runtime used AskingQuestionsSample", () => { + it("runtime can accept text inputs", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "Welcome to Input Sample Bot.\nI can show you examples on how to use actions, You can enter number 01-07\n01 - TextInput\n02 - NumberInput\n03 - ConfirmInput\n04 - ChoiceInput\n05 - AttachmentInput\n06 - DateTimeInput\n07 - OAuthInput" + ) + .send("01") + .assertReply( + "Hello, I'm Zoidberg. What is your name? (This can't be interrupted)" + ) + .send("02") + .assertReply("Hello 02, nice to talk to you!") + .startTest(); + }); + it("runtime can accept number inputs", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "Welcome to Input Sample Bot.\nI can show you examples on how to use actions, You can enter number 01-07\n01 - TextInput\n02 - NumberInput\n03 - ConfirmInput\n04 - ChoiceInput\n05 - AttachmentInput\n06 - DateTimeInput\n07 - OAuthInput" + ) + .send("02") + .assertReply("What is your age?") + .send("18") + .assertReply("Hello, your age is 18!") + .assertReply("2 * 2.2 equals?") + .send("4.4") + .assertReply("2 * 2.2 equals 4.4, that's right!") + .startTest(); + }); + it("runtime can accept confirm inputs", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "Welcome to Input Sample Bot.\nI can show you examples on how to use actions, You can enter number 01-07\n01 - TextInput\n02 - NumberInput\n03 - ConfirmInput\n04 - ChoiceInput\n05 - AttachmentInput\n06 - DateTimeInput\n07 - OAuthInput" + ) + .send("03") + .assertReply("yes or no (1) Yes or (2) No") + .send("asdasd") + .assertReply("I need a yes or no. (1) Yes or (2) No") + .send("yes") + .assertReply("confirmation: true") + .startTest(); + }); + it("runtime can accept choice inputs", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "Welcome to Input Sample Bot.\nI can show you examples on how to use actions, You can enter number 01-07\n01 - TextInput\n02 - NumberInput\n03 - ConfirmInput\n04 - ChoiceInput\n05 - AttachmentInput\n06 - DateTimeInput\n07 - OAuthInput" + ) + .send("04") + .assertReply( + "Please select a value from below:\n\n 1. Test1\n 2. Test2\n 3. Test3" + ) + .send("Test1") + .assertReply("You select: Test1") + .startTest(); + }); + it("runtime can accept datetime inputs", async () => { + await adapter + .send(conversationUpdateActivity) + .assertReply( + "Welcome to Input Sample Bot.\nI can show you examples on how to use actions, You can enter number 01-07\n01 - TextInput\n02 - NumberInput\n03 - ConfirmInput\n04 - ChoiceInput\n05 - AttachmentInput\n06 - DateTimeInput\n07 - OAuthInput" + ) + .send("06") + .assertReply("Please enter a date.") + .send("June 1st 2019") + .assertReply("You entered: 2019-06-01") + .startTest(); + }); +}); diff --git a/runtime/node/__tests__/message.test.ts b/runtime/node/__tests__/message.test.ts new file mode 100644 index 0000000000..1fb114a42a --- /dev/null +++ b/runtime/node/__tests__/message.test.ts @@ -0,0 +1,116 @@ +import * as path from "path"; +import { ResourceExplorer } from "botbuilder-dialogs-declarative"; +import { AdaptiveDialogComponentRegistration } from "botbuilder-dialogs-adaptive"; +import { + TestAdapter, + ConversationState, + MemoryStorage, + UserState, +} from "botbuilder"; +import { ComposerBot } from "../src/shared/composerBot"; +import { ActivityTypes, Activity, ChannelAccount } from "botframework-schema"; +import { TurnContext } from "botbuilder-core"; +import { SkillConversationIdFactory } from "../src/shared/skillConversationIdFactory"; +import * as helpers from "../src/shared/helpers"; + +const samplesDirectory = path.resolve( + __dirname, + "../../../Composer/plugins/samples/assets/projects", + "RespondingWithTextSample" +); + +const resourceExplorer = new ResourceExplorer(); +const basicActiivty: Partial = { + channelId: "test", + serviceUrl: "https://test.com", + from: { id: "user1", name: "User1" }, + recipient: { id: "bot", name: "Bot" }, + locale: "en-us", + conversation: { + isGroup: false, + conversationType: "testFlowConversationId", + id: "testFlowConversationId", + tenantId: "test", + name: "test", + }, +}; + +jest + .spyOn(helpers, "getProjectRoot") + .mockImplementation(() => samplesDirectory); +jest.spyOn(helpers, "getSettings").mockImplementation((root: string) => { + return { defaultLocale: "en-us" }; +}); + +let bot: ComposerBot; +let adapter: TestAdapter; +beforeAll(() => { + resourceExplorer.addFolders(samplesDirectory, ["runtime"], false); + resourceExplorer.addComponent( + new AdaptiveDialogComponentRegistration(resourceExplorer) + ); + adapter = new TestAdapter( + async (context: TurnContext): Promise => { + // Route activity to bot. + await bot.onTurnActivity(context); + }, + basicActiivty, + false + ); + const memoryStorage = new MemoryStorage(); + + // Create shared user state and conversation state instances. + const userState = new UserState(memoryStorage); + const conversationState = new ConversationState(memoryStorage); + // Create shared skill conversation id factory instance. + const skillConversationIdFactory = new SkillConversationIdFactory(); + bot = new ComposerBot( + userState, + conversationState, + skillConversationIdFactory + ); +}); + +describe("test runtime used RespondingWithTextSample", () => { + it("test runtime can send message and receive message correctly", async () => { + // create conversation update activity + const conversationUpdateActivity = { + ...basicActiivty, + type: ActivityTypes.ConversationUpdate, + membersAdded: [{ id: "test", name: "testAccount" } as ChannelAccount], + membersRemoved: [], + } as Activity; + await adapter + .send(conversationUpdateActivity) + .assertReply( + "What type of message would you like to send?\n\n 1. Simple Text\n 2. Text With Memory\n 3. LGWithParam\n 4. LGComposition\n 5. Structured LG\n 6. MultiLineText\n 7. IfElseCondition\n 8. SwitchCondition" + ) + .send("1") + .assertReplyOneOf([ + "Hi, this is simple text", + "Hey, this is simple text", + "Hello, this is simple text", + ]) + .assertReply( + "What type of message would you like to send?\n\n 1. Simple Text\n 2. Text With Memory\n 3. LGWithParam\n 4. LGComposition\n 5. Structured LG\n 6. MultiLineText\n 7. IfElseCondition\n 8. SwitchCondition" + ) + .send("2") + .assertReply("This is a text saved in memory.") + .assertReply( + "What type of message would you like to send?\n\n 1. Simple Text\n 2. Text With Memory\n 3. LGWithParam\n 4. LGComposition\n 5. Structured LG\n 6. MultiLineText\n 7. IfElseCondition\n 8. SwitchCondition" + ) + .send("3") + .assertReply("Hello, I'm Zoidberg. What is your name?") + .send("luhan") + .assertReply("Hello luhan, nice to talk to you!") + .assertReply( + "What type of message would you like to send?\n\n 1. Simple Text\n 2. Text With Memory\n 3. LGWithParam\n 4. LGComposition\n 5. Structured LG\n 6. MultiLineText\n 7. IfElseCondition\n 8. SwitchCondition" + ) + .send("4") + .assertReply("luhan nice to talk to you!") + .assertReply( + "What type of message would you like to send?\n\n 1. Simple Text\n 2. Text With Memory\n 3. LGWithParam\n 4. LGComposition\n 5. Structured LG\n 6. MultiLineText\n 7. IfElseCondition\n 8. SwitchCondition" + ) + .startTest(); + }); +}); diff --git a/runtime/node/__tests__/skillConversationIdFactory.test.ts b/runtime/node/__tests__/skillConversationIdFactory.test.ts new file mode 100644 index 0000000000..fc0fb94e76 --- /dev/null +++ b/runtime/node/__tests__/skillConversationIdFactory.test.ts @@ -0,0 +1,77 @@ +import { SkillConversationIdFactory } from "../src/shared/skillConversationIdFactory"; +import { SkillConversationIdFactoryOptions, BotFrameworkSkill, MessageFactory, ConversationReference, ConversationAccount, TurnContext, ChannelAccount, Activity } from 'botbuilder'; + +const refEquals = (ref1: ConversationReference, ref2: ConversationReference): boolean => { + return ref1.conversation.id == ref2.conversation.id && ref1.serviceUrl == ref2.serviceUrl; +} + +let skillConversationIdFactory: SkillConversationIdFactory; +let skillConversationIdFactoryOptions: SkillConversationIdFactoryOptions; +let conversationReference: ConversationReference; + +beforeAll(() => { + skillConversationIdFactory = new SkillConversationIdFactory(); + const botId = 'BotId'; + const skillId = 'SkillId'; + const bot: ChannelAccount = { + id: botId, + name: botId + }; + const conversation: ConversationAccount = { + conversationType: 'test', + id: '123', + isGroup: false, + name: 'test', + tenantId: 'test' + }; + conversationReference = { + bot, + conversation, + serviceUrl: 'http://testbot.com/api/messages', + channelId: 'test' + }; + const activity = MessageFactory.text('') as Activity; + TurnContext.applyConversationReference(activity, conversationReference); + const skill: BotFrameworkSkill = { + id: 'skill', + appId: skillId, + skillEndpoint: 'http://testbot.com/api/messages' + }; + skillConversationIdFactoryOptions = { + fromBotOAuthScope: botId, + fromBotId: botId, + activity: activity, + botFrameworkSkill: skill + }; +}); + +describe('test skill conversation id factory', () => { + it('should create correct conversation id', async () => { + const conversationId = await skillConversationIdFactory.createSkillConversationIdWithOptions(skillConversationIdFactoryOptions); + expect(conversationId).toBeDefined(); + }); + + it('should get conversation reference from conversation id', async () => { + const conversationId = await skillConversationIdFactory.createSkillConversationIdWithOptions(skillConversationIdFactoryOptions); + expect(conversationId).toBeDefined(); + + const skillConversationRef = await skillConversationIdFactory.getSkillConversationReference(conversationId); + expect(skillConversationRef).toBeTruthy(); + expect(refEquals(skillConversationRef.conversationReference, conversationReference)).toBeTruthy(); + }); + + it('should not get conversation reference after deleted', async () => { + const conversationId = await skillConversationIdFactory.createSkillConversationIdWithOptions(skillConversationIdFactoryOptions); + expect(conversationId).toBeDefined(); + + const skillConversationRef = await skillConversationIdFactory.getSkillConversationReference(conversationId); + expect(skillConversationRef).toBeTruthy(); + expect(refEquals(skillConversationRef.conversationReference, conversationReference)).toBeTruthy(); + + await skillConversationIdFactory.deleteConversationReference(conversationId); + + const skillConversationRefAfterDeleted = await skillConversationIdFactory.getSkillConversationReference(conversationId); + console.log(skillConversationRefAfterDeleted); + expect(skillConversationRefAfterDeleted).toBeUndefined(); + }); +}); \ No newline at end of file diff --git a/runtime/node/__tests__/todobot.test.ts b/runtime/node/__tests__/todobot.test.ts new file mode 100644 index 0000000000..c86d57ea7f --- /dev/null +++ b/runtime/node/__tests__/todobot.test.ts @@ -0,0 +1,104 @@ +import * as path from "path"; +import { ResourceExplorer } from "botbuilder-dialogs-declarative"; +import { AdaptiveDialogComponentRegistration } from "botbuilder-dialogs-adaptive"; +import { + TestAdapter, + ConversationState, + MemoryStorage, + UserState, +} from "botbuilder"; +import { ComposerBot } from "../src/shared/composerBot"; +import { ActivityTypes, Activity, ChannelAccount } from "botframework-schema"; +import { TurnContext } from "botbuilder-core"; +import { SkillConversationIdFactory } from "../src/shared/skillConversationIdFactory"; +import * as helpers from "../src/shared/helpers"; + +const samplesDirectory = path.resolve( + __dirname, + "../../../Composer/plugins/samples/assets/projects", + "TodoSample" +); + +const resourceExplorer = new ResourceExplorer(); +const basicActiivty: Partial = { + channelId: "test", + serviceUrl: "https://test.com", + from: { id: "user1", name: "User1" }, + recipient: { id: "bot", name: "Bot" }, + locale: "en-us", + conversation: { + isGroup: false, + conversationType: "testFlowConversationId", + id: "testFlowConversationId", + tenantId: "test", + name: "test", + }, +}; + +jest + .spyOn(helpers, "getProjectRoot") + .mockImplementation(() => samplesDirectory); +jest.spyOn(helpers, "getSettings").mockImplementation((root: string) => { + return { defaultLocale: "en-us" }; +}); + +let bot: ComposerBot; +let adapter: TestAdapter; +beforeAll(() => { + resourceExplorer.addFolders(samplesDirectory, ["runtime"], false); + resourceExplorer.addComponent( + new AdaptiveDialogComponentRegistration(resourceExplorer) + ); + adapter = new TestAdapter( + async (context: TurnContext): Promise => { + // Route activity to bot. + await bot.onTurnActivity(context); + }, + basicActiivty, + false + ); + const memoryStorage = new MemoryStorage(); + + // Create shared user state and conversation state instances. + const userState = new UserState(memoryStorage); + const conversationState = new ConversationState(memoryStorage); + // Create shared skill conversation id factory instance. + const skillConversationIdFactory = new SkillConversationIdFactory(); + bot = new ComposerBot( + userState, + conversationState, + skillConversationIdFactory + ); +}); + +describe("test runtime used TodoSample", () => { + it("test runtime can run todoBot correctly", async () => { + // create conversation update activity + const conversationUpdateActivity = { + ...basicActiivty, + type: ActivityTypes.ConversationUpdate, + membersAdded: [{ id: "test", name: "testAccount" } as ChannelAccount], + membersRemoved: [], + } as Activity; + await adapter + .send(conversationUpdateActivity) + .assertReply( + 'Hi! I\'m a ToDo bot. Say "add a todo named first" to get started.' + ) + .send("add a todo named first") + .assertReplyOneOf(["Successfully added a todo named first"]) + .send("add a todo named second") + .assertReply("Successfully added a todo named second") + .send("add a todo") + .assertReply("OK, please enter the title of your todo.") + .send("third") + .assertReply("Successfully added a todo named third") + .send("show todos") + .assertReply("Your most recent 3 tasks are\n* first\n* second\n* third") + .send("delete todo named second") + .assertReply("Successfully removed a todo named second") + .send("show todos") + .assertReply("Your most recent 2 tasks are\n* first\n* third") + .startTest(); + }); +}); diff --git a/runtime/node/azurefunctions/README.md b/runtime/node/azurefunctions/README.md deleted file mode 100644 index ae8da00d49..0000000000 --- a/runtime/node/azurefunctions/README.md +++ /dev/null @@ -1 +0,0 @@ -# Node.js bot launcher for Azure Functions diff --git a/runtime/node/azurewebapp/README.md b/runtime/node/azurewebapp/README.md deleted file mode 100644 index 6b88576592..0000000000 --- a/runtime/node/azurewebapp/README.md +++ /dev/null @@ -1 +0,0 @@ -# Node.js bot launcher for Azure WebApp \ No newline at end of file diff --git a/runtime/node/babel.config.js b/runtime/node/babel.config.js new file mode 100644 index 0000000000..f67c1d64e0 --- /dev/null +++ b/runtime/node/babel.config.js @@ -0,0 +1,14 @@ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + modules: 'commonjs', + targets: { + node: 'current', + }, + }, + ], + '@babel/preset-typescript', + ], +}; diff --git a/runtime/node/core/README.md b/runtime/node/core/README.md deleted file mode 100644 index 8046cb557c..0000000000 --- a/runtime/node/core/README.md +++ /dev/null @@ -1 +0,0 @@ -# Node.js core bot runtime logic diff --git a/runtime/node/host.json b/runtime/node/host.json new file mode 100644 index 0000000000..b9f92c0dee --- /dev/null +++ b/runtime/node/host.json @@ -0,0 +1,3 @@ +{ + "version": "2.0" +} \ No newline at end of file diff --git a/runtime/node/messages/function.json b/runtime/node/messages/function.json new file mode 100644 index 0000000000..33d315ba2b --- /dev/null +++ b/runtime/node/messages/function.json @@ -0,0 +1,21 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "res" + } + ], + "scriptFile": "../lib/functions.js", + "entryPoint": "messagesTrigger" +} diff --git a/runtime/node/package-lock.json b/runtime/node/package-lock.json new file mode 100644 index 0000000000..fbb6e3d876 --- /dev/null +++ b/runtime/node/package-lock.json @@ -0,0 +1,8757 @@ +{ + "name": "node-runtime", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@azure/cognitiveservices-luis-runtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@azure/cognitiveservices-luis-runtime/-/cognitiveservices-luis-runtime-2.0.0.tgz", + "integrity": "sha512-NZuqxiwpn8iYM76/QDIBDGq1jJ+YHiwS0S/yprAMeaaQgu1S5VtVhWDbTrZl+AfaqCn6iDpRewI7EKRv1GJx0g==", + "requires": { + "@azure/ms-rest-js": "^1.6.0", + "tslib": "^1.9.3" + } + }, + "@azure/functions": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@azure/functions/-/functions-1.2.2.tgz", + "integrity": "sha512-p/dDHq1sG/iAib+eDY4NxskWHoHW1WFzD85s0SfWxc2wVjJbxB0xz/zBF4s7ymjVgTu+0ceipeBk+tmpnt98oA==" + }, + "@azure/ms-rest-js": { + "version": "1.8.15", + "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-1.8.15.tgz", + "integrity": "sha512-kIB71V3DcrA4iysBbOsYcxd4WWlOE7OFtCUYNfflPODM0lbIR23A236QeTn5iAeYwcHmMjR/TAKp5KQQh/WqoQ==", + "requires": { + "@types/tunnel": "0.0.0", + "axios": "^0.19.0", + "form-data": "^2.3.2", + "tough-cookie": "^2.4.3", + "tslib": "^1.9.2", + "tunnel": "0.0.6", + "uuid": "^3.2.1", + "xml2js": "^0.4.19" + } + }, + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/code-frame/-/@babel/code-frame-7.10.4.tgz", + "integrity": "sha1-Fo2ho26Q2miujUnA8bSMfGJJITo=", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/compat-data/-/@babel/compat-data-7.10.5.tgz", + "integrity": "sha1-04Ql5n6paxSAo/UEBNG/hWdjAaY=", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/core/-/@babel/core-7.10.5.tgz", + "integrity": "sha1-HxXizKitmh14o43bphL158270zA=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-4.1.1.tgz", + "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ms/-/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/generator/-/@babel/generator-7.10.5.tgz", + "integrity": "sha1-G5A1VLyMWD7o0l8eiWlzLmuCmmk=", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-annotate-as-pure/-/@babel/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha1-W/DUlaP3V6w72ki1vzs7ownHK6M=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-builder-binary-assignment-operator-visitor/-/@babel/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", + "integrity": "sha1-uwt18xv5jL+f8UPBrleLhydK4aM=", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-compilation-targets/-/@babel/helper-compilation-targets-7.10.4.tgz", + "integrity": "sha1-gEro4/BDdmB8x5G51H1UAnYzK9I=", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.4", + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-create-class-features-plugin/-/@babel/helper-create-class-features-plugin-7.10.5.tgz", + "integrity": "sha1-n2FEa6gOgkCwpchcb9rIRZ1vJZ0=", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.10.5", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-create-regexp-features-plugin/-/@babel/helper-create-regexp-features-plugin-7.10.4.tgz", + "integrity": "sha1-/dYNiFJGWaC2lZwFeZJeQlcU87g=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-regex": "^7.10.4", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-define-map/-/@babel/helper-define-map-7.10.5.tgz", + "integrity": "sha1-tTwQ23imQIABUmkrEzkxR6y5uzA=", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=", + "dev": true + } + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-explode-assignable-expression/-/@babel/helper-explode-assignable-expression-7.10.4.tgz", + "integrity": "sha1-QKHNkXv/Eoj2malKdbN6Gi29jHw=", + "dev": true, + "requires": { + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-function-name/-/@babel/helper-function-name-7.10.4.tgz", + "integrity": "sha1-0tOyDFmtjEcRL6fSqUvAnV74Lxo=", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-get-function-arity/-/@babel/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha1-mMHL6g4jMvM/mkZhuM4VBbLBm6I=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-hoist-variables/-/@babel/helper-hoist-variables-7.10.4.tgz", + "integrity": "sha1-1JsAHR1aaMpeZgTdoBpil/fJOB4=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-member-expression-to-functions/-/@babel/helper-member-expression-to-functions-7.10.5.tgz", + "integrity": "sha1-Fy9W56Y+eBEvOgQFXyQ2WvcC5+4=", + "dev": true, + "requires": { + "@babel/types": "^7.10.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-module-imports/-/@babel/helper-module-imports-7.10.4.tgz", + "integrity": "sha1-TFxUvgS9MWcKc4J5fXW5+i5bViA=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-module-transforms/-/@babel/helper-module-transforms-7.10.5.tgz", + "integrity": "sha1-EgwnHAszU2c/zf2MBT2zxUSiYNY=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=", + "dev": true + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-optimise-call-expression/-/@babel/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha1-UNyWQT1ZT5lad5BZBbBYk813lnM=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-plugin-utils/-/@babel/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha1-L3WoMSadT2d95JmG3/WZJ1M883U=", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-regex/-/@babel/helper-regex-7.10.5.tgz", + "integrity": "sha1-Mt+7eYmQc8QVVXBToZvQVarlCuA=", + "dev": true, + "requires": { + "lodash": "^4.17.19" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=", + "dev": true + } + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-remap-async-to-generator/-/@babel/helper-remap-async-to-generator-7.10.4.tgz", + "integrity": "sha1-/Oi+pOlpC76SMFbe0h5UtOi2jtU=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-wrap-function": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-replace-supers/-/@babel/helper-replace-supers-7.10.4.tgz", + "integrity": "sha1-1YXNk4jqBuYDHkzUS2cTy+rZ5s8=", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-simple-access/-/@babel/helper-simple-access-7.10.4.tgz", + "integrity": "sha1-D1zNopRSd6KnotOoIeFTle3PNGE=", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-split-export-declaration/-/@babel/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha1-LHBXbqo7VgmyTLmdsoiMw/xCUdE=", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-validator-identifier/-/@babel/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha1-p4x6clHgH2FlEtMbEK3PUq2l4NI=", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helper-wrap-function/-/@babel/helper-wrap-function-7.10.4.tgz", + "integrity": "sha1-im9wHqsP8592W1oc/vQJmQ5iS4c=", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/helpers/-/@babel/helpers-7.10.4.tgz", + "integrity": "sha1-Kr6w1yGv98Cpc3a54fb2XXpHUEQ=", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/highlight/-/@babel/highlight-7.10.4.tgz", + "integrity": "sha1-fRvf1ldTU4+r5sOFls23bZrGAUM=", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/parser/-/@babel/parser-7.10.5.tgz", + "integrity": "sha1-58a/Wn3v+VfOyfBLVR4nYpCdgms=", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-async-generator-functions/-/@babel/plugin-proposal-async-generator-functions-7.10.5.tgz", + "integrity": "sha1-NJHKvy98F5q4IGBs7Cf+0V4OhVg=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-class-properties/-/@babel/plugin-proposal-class-properties-7.10.4.tgz", + "integrity": "sha1-ozv2Mto5ClnHqMVwBF0RFc13iAc=", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-dynamic-import/-/@babel/plugin-proposal-dynamic-import-7.10.4.tgz", + "integrity": "sha1-uleibLmLN3QenVvKG4sN34KR8X4=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-json-strings/-/@babel/plugin-proposal-json-strings-7.10.4.tgz", + "integrity": "sha1-WT5ZxjUoFgIzvTIbGuvgggwjQds=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-nullish-coalescing-operator/-/@babel/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", + "integrity": "sha1-AqfpYfwy5tWy2wZJ4Bv4Dd7n4Eo=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-numeric-separator/-/@babel/plugin-proposal-numeric-separator-7.10.4.tgz", + "integrity": "sha1-zhWQ/wplrRKXCmCdeIVemkwa7wY=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-object-rest-spread/-/@babel/plugin-proposal-object-rest-spread-7.10.4.tgz", + "integrity": "sha1-UBKawha5pqVbOFP92SPnS/VTpMA=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-optional-catch-binding/-/@babel/plugin-proposal-optional-catch-binding-7.10.4.tgz", + "integrity": "sha1-Mck4MJ0kp4pJ1o/av/qoY3WFVN0=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-optional-chaining/-/@babel/plugin-proposal-optional-chaining-7.10.4.tgz", + "integrity": "sha1-dQ8SVekwofgtjN3kUDH4Gg0K3/c=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-private-methods/-/@babel/plugin-proposal-private-methods-7.10.4.tgz", + "integrity": "sha1-sWDZcrj9ulx9ERoUX8jEIfwqaQk=", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-proposal-unicode-property-regex/-/@babel/plugin-proposal-unicode-property-regex-7.10.4.tgz", + "integrity": "sha1-RIPNpTBBzjQTt/4vAAImZd36p10=", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-async-generators/-/@babel/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-bigint/-/@babel/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha1-TJpvZp9dDN8bkKFnHpoUa+UwDOo=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-class-properties/-/@babel/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha1-ZkTmoLqlWmH54yMfbJ7rbuRsEkw=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-dynamic-import/-/@babel/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha1-Yr+Ysto80h1iYVT8lu5bPLaOrLM=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-import-meta/-/@babel/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha1-7mATSMNw+jNNIge+FYd3SWUh/VE=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-json-strings/-/@babel/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-logical-assignment-operators/-/@babel/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha1-ypHvRjA1MESLkGZSusLp/plB9pk=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-nullish-coalescing-operator/-/@babel/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-numeric-separator/-/@babel/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-object-rest-spread/-/@babel/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-optional-catch-binding/-/@babel/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-optional-chaining/-/@babel/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-top-level-await/-/@babel/plugin-syntax-top-level-await-7.10.4.tgz", + "integrity": "sha1-S764kXtU/PdoNk4KgfVg4zo+9X0=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-syntax-typescript/-/@babel/plugin-syntax-typescript-7.10.4.tgz", + "integrity": "sha1-L1XncNNQHoOvIX14LLdRfXuzTSU=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-arrow-functions/-/@babel/plugin-transform-arrow-functions-7.10.4.tgz", + "integrity": "sha1-4ilg135pfHT0HFAdRNc9v4pqZM0=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-async-to-generator/-/@babel/plugin-transform-async-to-generator-7.10.4.tgz", + "integrity": "sha1-QaUBfknrbzzak5KlHu8pQFskWjc=", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-block-scoped-functions/-/@babel/plugin-transform-block-scoped-functions-7.10.4.tgz", + "integrity": "sha1-GvpZV0T3XkOpGvc7DZmOz+Trwug=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-block-scoping/-/@babel/plugin-transform-block-scoping-7.10.5.tgz", + "integrity": "sha1-uBuKr++/5o8PZffvOXuezmimA30=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-classes/-/@babel/plugin-transform-classes-7.10.4.tgz", + "integrity": "sha1-QFE2rys+IYvEoZJiKLyRerGgrcc=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-define-map": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-computed-properties/-/@babel/plugin-transform-computed-properties-7.10.4.tgz", + "integrity": "sha1-ne2DqBboLe0o1S1LTsvdgQzfwOs=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-destructuring/-/@babel/plugin-transform-destructuring-7.10.4.tgz", + "integrity": "sha1-cN3Ss9G+qD0BUJ6bsl3bOnT8heU=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-dotall-regex/-/@babel/plugin-transform-dotall-regex-7.10.4.tgz", + "integrity": "sha1-RpwgYhBcHragQOr0+sS0iAeDle4=", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-duplicate-keys/-/@babel/plugin-transform-duplicate-keys-7.10.4.tgz", + "integrity": "sha1-aX5Qyf7hQ4D+hD0fMGspVhdDHkc=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-exponentiation-operator/-/@babel/plugin-transform-exponentiation-operator-7.10.4.tgz", + "integrity": "sha1-WuM4xX+M9AAb2zVgeuZrktZlry4=", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-for-of/-/@babel/plugin-transform-for-of-7.10.4.tgz", + "integrity": "sha1-wIiS6IGdOl2ykDGxFa9RHbv+uuk=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-function-name/-/@babel/plugin-transform-function-name-7.10.4.tgz", + "integrity": "sha1-akZ4gOD8ljhRS6NpERgR3b4mRLc=", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-literals/-/@babel/plugin-transform-literals-7.10.4.tgz", + "integrity": "sha1-n0K6CEEQChNfInEtDjkcRi9XHzw=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-member-expression-literals/-/@babel/plugin-transform-member-expression-literals-7.10.4.tgz", + "integrity": "sha1-sexE/PGVr8uNssYs2OVRyIG6+Lc=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-modules-amd/-/@babel/plugin-transform-modules-amd-7.10.5.tgz", + "integrity": "sha1-G5zdrwXZ6Is6rTOcs+RFxPAgqbE=", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-modules-commonjs/-/@babel/plugin-transform-modules-commonjs-7.10.4.tgz", + "integrity": "sha1-ZmZ8Pu2h6/eJbUHx8WsXEFovvKA=", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-modules-systemjs/-/@babel/plugin-transform-modules-systemjs-7.10.5.tgz", + "integrity": "sha1-YnAJnIVAZmgbrp4F+H4bnK2+jIU=", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-modules-umd/-/@babel/plugin-transform-modules-umd-7.10.4.tgz", + "integrity": "sha1-moSB/oG4JGVLOgtl2j34nz0hg54=", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-named-capturing-groups-regex/-/@babel/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", + "integrity": "sha1-eLTZeIELbzvPA/njGPL8DtQa7LY=", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-new-target/-/@babel/plugin-transform-new-target-7.10.4.tgz", + "integrity": "sha1-kJfXU8t7Aky3OBo7LlLpUTqcaIg=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-object-super/-/@babel/plugin-transform-object-super-7.10.4.tgz", + "integrity": "sha1-1xRsTROUM+emUm+IjGZ+MUoJOJQ=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-parameters/-/@babel/plugin-transform-parameters-7.10.5.tgz", + "integrity": "sha1-WdM51Y0LGVBDX0BD504lEABeLEo=", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-property-literals/-/@babel/plugin-transform-property-literals-7.10.4.tgz", + "integrity": "sha1-9v5UtlkDUimHhbg+3YFdIUxC48A=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-regenerator/-/@babel/plugin-transform-regenerator-7.10.4.tgz", + "integrity": "sha1-IBXlnYOQdOdoON4hWdtCGWb9i2M=", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-reserved-words/-/@babel/plugin-transform-reserved-words-7.10.4.tgz", + "integrity": "sha1-jyaCvNzvntMn4bCGFYXXAT+KVN0=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-shorthand-properties/-/@babel/plugin-transform-shorthand-properties-7.10.4.tgz", + "integrity": "sha1-n9Jexc3VVbt/Rz5ebuHJce7eTdY=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-spread/-/@babel/plugin-transform-spread-7.10.4.tgz", + "integrity": "sha1-TiyF6g1quu4bJNz7uuQm/o1nTP8=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-sticky-regex/-/@babel/plugin-transform-sticky-regex-7.10.4.tgz", + "integrity": "sha1-jziJ7oZXWBEwop2cyR18c7fEoo0=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-regex": "^7.10.4" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-template-literals/-/@babel/plugin-transform-template-literals-7.10.5.tgz", + "integrity": "sha1-eLxdYmpmQtszEtnQ8AH152Of3ow=", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-typeof-symbol/-/@babel/plugin-transform-typeof-symbol-7.10.4.tgz", + "integrity": "sha1-lQnxp+7DHE7b/+E3wWzDP/C8W/w=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-typescript/-/@babel/plugin-transform-typescript-7.10.5.tgz", + "integrity": "sha1-7fNTlE6Xn0DY/5/k6ZddCkZQN8U=", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.5", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-typescript": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-unicode-escapes/-/@babel/plugin-transform-unicode-escapes-7.10.4.tgz", + "integrity": "sha1-/q5SM5HHZR3awRXa4KnQaFeJIAc=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/plugin-transform-unicode-regex/-/@babel/plugin-transform-unicode-regex-7.10.4.tgz", + "integrity": "sha1-5W1x+SgvrG2wnIJ0IFVXbV5tgKg=", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/preset-env": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/preset-env/-/@babel/preset-env-7.10.4.tgz", + "integrity": "sha1-+/V/moA6/Zf08y5PeYu2Lksr718=", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.4", + "@babel/helper-compilation-targets": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-proposal-async-generator-functions": "^7.10.4", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-dynamic-import": "^7.10.4", + "@babel/plugin-proposal-json-strings": "^7.10.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", + "@babel/plugin-proposal-numeric-separator": "^7.10.4", + "@babel/plugin-proposal-object-rest-spread": "^7.10.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", + "@babel/plugin-proposal-optional-chaining": "^7.10.4", + "@babel/plugin-proposal-private-methods": "^7.10.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.10.4", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.10.4", + "@babel/plugin-transform-arrow-functions": "^7.10.4", + "@babel/plugin-transform-async-to-generator": "^7.10.4", + "@babel/plugin-transform-block-scoped-functions": "^7.10.4", + "@babel/plugin-transform-block-scoping": "^7.10.4", + "@babel/plugin-transform-classes": "^7.10.4", + "@babel/plugin-transform-computed-properties": "^7.10.4", + "@babel/plugin-transform-destructuring": "^7.10.4", + "@babel/plugin-transform-dotall-regex": "^7.10.4", + "@babel/plugin-transform-duplicate-keys": "^7.10.4", + "@babel/plugin-transform-exponentiation-operator": "^7.10.4", + "@babel/plugin-transform-for-of": "^7.10.4", + "@babel/plugin-transform-function-name": "^7.10.4", + "@babel/plugin-transform-literals": "^7.10.4", + "@babel/plugin-transform-member-expression-literals": "^7.10.4", + "@babel/plugin-transform-modules-amd": "^7.10.4", + "@babel/plugin-transform-modules-commonjs": "^7.10.4", + "@babel/plugin-transform-modules-systemjs": "^7.10.4", + "@babel/plugin-transform-modules-umd": "^7.10.4", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", + "@babel/plugin-transform-new-target": "^7.10.4", + "@babel/plugin-transform-object-super": "^7.10.4", + "@babel/plugin-transform-parameters": "^7.10.4", + "@babel/plugin-transform-property-literals": "^7.10.4", + "@babel/plugin-transform-regenerator": "^7.10.4", + "@babel/plugin-transform-reserved-words": "^7.10.4", + "@babel/plugin-transform-shorthand-properties": "^7.10.4", + "@babel/plugin-transform-spread": "^7.10.4", + "@babel/plugin-transform-sticky-regex": "^7.10.4", + "@babel/plugin-transform-template-literals": "^7.10.4", + "@babel/plugin-transform-typeof-symbol": "^7.10.4", + "@babel/plugin-transform-unicode-escapes": "^7.10.4", + "@babel/plugin-transform-unicode-regex": "^7.10.4", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.10.4", + "browserslist": "^4.12.0", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/preset-modules/-/@babel/preset-modules-0.1.3.tgz", + "integrity": "sha1-EyQrU7XvjIg8PPfd3VWzbOgPvHI=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-typescript": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/preset-typescript/-/@babel/preset-typescript-7.10.4.tgz", + "integrity": "sha1-fV0FLlKmgkgNbizFqjG+YcjCXjY=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.10.4" + } + }, + "@babel/runtime": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/runtime/-/@babel/runtime-7.10.5.tgz", + "integrity": "sha1-MD2L1EDs1aSR6uYRf9M2dphnTFw=", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/template/-/@babel/template-7.10.4.tgz", + "integrity": "sha1-MlGZbEIA68cdGo/EBfupQPNrong=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/traverse/-/@babel/traverse-7.10.5.tgz", + "integrity": "sha1-d85GT1sli+Jlr2GNj93wU28gtWQ=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-4.1.1.tgz", + "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ms/-/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@babel/types/-/@babel/types-7.10.5.tgz", + "integrity": "sha1-2Irn4v3oa/v+hR1Nga+nCpl7XRU=", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha1-5I3e2+MLMyF4PFtDAfvTU7weSks=", + "dev": true + } + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@bcoe/v8-coverage/-/@bcoe/v8-coverage-0.2.3.tgz", + "integrity": "sha1-daLotRy3WKdVPWgEpZMteqznXDk=", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@cnakazawa/watch/-/@cnakazawa/watch-1.0.4.tgz", + "integrity": "sha1-+GSuhQBND8q29QvpFBxNo2jRZWo=", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@istanbuljs/load-nyc-config/-/@istanbuljs/load-nyc-config-1.1.0.tgz", + "integrity": "sha1-/T2x1Z7PfPEh6AZQu4ZxL5tV7O0=", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@istanbuljs/schema/-/@istanbuljs/schema-0.1.2.tgz", + "integrity": "sha1-JlIL8Jq+SlZEzVQU43ElqJVCQd0=", + "dev": true + }, + "@jest/console": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/console/-/@jest/console-26.1.0.tgz", + "integrity": "sha1-9nyJ5PTQTbz3sFKu1aucdPkVuVQ=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "jest-message-util": "^26.1.0", + "jest-util": "^26.1.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/core": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/core/-/@jest/core-26.1.0.tgz", + "integrity": "sha1-RYBVW1It5BKnmYs5OMhR5PnaHBg=", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/reporters": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.1.0", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-resolve-dependencies": "^26.1.0", + "jest-runner": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "jest-watcher": "^26.1.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "@jest/environment": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/environment/-/@jest/environment-26.1.0.tgz", + "integrity": "sha1-N4hTvN0cJEO0VVq5CM+6u4Uelto=", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/fake-timers": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/fake-timers/-/@jest/fake-timers-26.1.0.tgz", + "integrity": "sha1-mna3qUw1HNvArVPlp0h4n4GaZf4=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/globals": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/globals/-/@jest/globals-26.1.0.tgz", + "integrity": "sha1-bMXXy7ebdrEg8kA9fXVWk88GOrE=", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/types": "^26.1.0", + "expect": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/reporters": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/reporters/-/@jest/reporters-26.1.0.tgz", + "integrity": "sha1-CJUukMkCguFP9J6Se98Yc2F9rng=", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.1.0", + "jest-resolve": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/source-map/-/@jest/source-map-26.1.0.tgz", + "integrity": "sha1-pqAg0A59lHj0tpAWfF6Ld+Y62yY=", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/test-result/-/@jest/test-result-26.1.0.tgz", + "integrity": "sha1-qT+hWyGtPHzrIcK0w1vi5AfY6XE=", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/test-sequencer": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/test-sequencer/-/@jest/test-sequencer-26.1.0.tgz", + "integrity": "sha1-Qab8i4UMPzP0gojqnqUXwEfn8U4=", + "dev": true, + "requires": { + "@jest/test-result": "^26.1.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.1.0", + "jest-runner": "^26.1.0", + "jest-runtime": "^26.1.0" + } + }, + "@jest/transform": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/transform/-/@jest/transform-26.1.0.tgz", + "integrity": "sha1-aX9IiYwqJ4fJtMtx0J1+YXRk5Qk=", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.1.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.1.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-25.5.0.tgz", + "integrity": "sha1-TWpHk/e5WZ/DaAh3uFapfbzPKp0=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@microsoft/recognizers-text": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text/-/recognizers-text-1.1.4.tgz", + "integrity": "sha512-hlSVXcaX5i8JcjuUJpVxmy2Z/GxvFXarF0KVySCFop57wNEnrLWMHe4I4DjP866G19VyIKRw+vPA32pkGhZgTg==" + }, + "@microsoft/recognizers-text-choice": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-choice/-/recognizers-text-choice-1.1.4.tgz", + "integrity": "sha512-4CddwFe4RVhZeJgW65ocBrEdeukBMghK8pgI0K0Qy2eA5ysPZQpeZ7BGSDz5QMQei5LPY+QaAQ3CHU+ORHoO7A==", + "requires": { + "@microsoft/recognizers-text": "~1.1.4", + "grapheme-splitter": "^1.0.2" + } + }, + "@microsoft/recognizers-text-data-types-timex-expression": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-data-types-timex-expression/-/recognizers-text-data-types-timex-expression-1.1.4.tgz", + "integrity": "sha512-2vICaEJfV9EpaDKs5P1PLAEs+WpNqrtpkl7CLsmc5gKmxgpQtsojG4tk6km5JRKg1mYuLV5ZzJ/65oOEeyTMvQ==" + }, + "@microsoft/recognizers-text-date-time": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-date-time/-/recognizers-text-date-time-1.1.4.tgz", + "integrity": "sha512-leMnjN+KYNwNvRD5T4G0ORUzkjlek/BBZDvQIjAujtyrd/pkViUnuouWIPkFT/dbSOxXML8et54CSk2KfHiWIA==", + "requires": { + "@microsoft/recognizers-text": "~1.1.4", + "@microsoft/recognizers-text-number": "~1.1.4", + "@microsoft/recognizers-text-number-with-unit": "~1.1.4", + "lodash.isequal": "^4.5.0", + "lodash.tonumber": "^4.0.3" + } + }, + "@microsoft/recognizers-text-number": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-number/-/recognizers-text-number-1.1.4.tgz", + "integrity": "sha512-6EmlR+HR+eJBIX7sQby1vs6LJB64wxLowHaGpIU9OCXFvZ5Nb0QT8qh10rC40v3Mtrz4DpScXfSXr9tWkIO5MQ==", + "requires": { + "@microsoft/recognizers-text": "~1.1.4", + "bignumber.js": "^7.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.sortby": "^4.7.0", + "lodash.trimend": "^4.5.1" + } + }, + "@microsoft/recognizers-text-number-with-unit": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-number-with-unit/-/recognizers-text-number-with-unit-1.1.4.tgz", + "integrity": "sha512-zl+CfmfWK0x/x+iSgaBAevKTYO0F4+z7SYHAHztaaaGuX8FERw2jmUjSgVetm5KA3EveyCx0XYGU1mRNY8p7Eg==", + "requires": { + "@microsoft/recognizers-text": "~1.1.4", + "@microsoft/recognizers-text-number": "~1.1.4", + "lodash.escaperegexp": "^4.1.2", + "lodash.last": "^3.0.0", + "lodash.max": "^4.0.1" + } + }, + "@microsoft/recognizers-text-sequence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-sequence/-/recognizers-text-sequence-1.1.4.tgz", + "integrity": "sha512-rb5j8/aE7HSOdIxaVfCGFrj0wWPpSq0CuykFg/A/iJNPP+FnAU71bgP5HexrwQcpCsDinauisX7u0DKIChrHRA==", + "requires": { + "@microsoft/recognizers-text": "~1.1.4", + "grapheme-splitter": "^1.0.2" + } + }, + "@microsoft/recognizers-text-suite": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-suite/-/recognizers-text-suite-1.1.4.tgz", + "integrity": "sha512-hNIaR4M2G0nNeI9WZxt9C0KYh/1vhjeKzX5Ds8XDdT0pxF7zwCSo19WNcPjrVK6aCOeZTw/ULofsAjdu9gSkcA==", + "requires": { + "@microsoft/recognizers-text": "~1.1.4", + "@microsoft/recognizers-text-choice": "~1.1.4", + "@microsoft/recognizers-text-date-time": "~1.1.4", + "@microsoft/recognizers-text-number": "~1.1.4", + "@microsoft/recognizers-text-number-with-unit": "~1.1.4", + "@microsoft/recognizers-text-sequence": "~1.1.4" + } + }, + "@netflix/nerror": { + "version": "1.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@netflix/nerror/-/@netflix/nerror-1.1.3.tgz", + "integrity": "sha1-nYjszKRC8dVE8nYdFepVfcCkTtI=", + "requires": { + "assert-plus": "^1.0.0", + "extsprintf": "^1.4.0", + "lodash": "^4.17.15" + }, + "dependencies": { + "extsprintf": { + "version": "1.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extsprintf/-/extsprintf-1.4.0.tgz", + "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=" + } + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@sinonjs/commons/-/@sinonjs/commons-1.8.1.tgz", + "integrity": "sha1-598A+YogMyT23HzGBsrZ1KirIhc=", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@sinonjs/fake-timers/-/@sinonjs/fake-timers-6.0.1.tgz", + "integrity": "sha1-KTZ0/MsyYqx4LHqt/eyoaxDHXEA=", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha512-7bjymPR7Ffa1/L3HskkaxMgTQDtwFObbISzHm9g3T12VyD89IiHS3BBVojlQHyZRiIilzdh0WT1gwwgyyBtLGQ==" + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/babel__core/-/@types/babel__core-7.1.9.tgz", + "integrity": "sha1-d+WdQ4UipvuJj6Q9w0VcbnLzlj0=", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/babel__generator/-/@types/babel__generator-7.6.1.tgz", + "integrity": "sha1-SQF2ezl+hxGuuZ3405bXunt/DgQ=", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/babel__template/-/@types/babel__template-7.0.2.tgz", + "integrity": "sha1-T/Y9a1Lt2sHee5daUiPtMuzqkwc=", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/babel__traverse/-/@types/babel__traverse-7.0.13.tgz", + "integrity": "sha1-GHSRS+l0pJLhtMsAWFyrsnTouhg=", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/bunyan": { + "version": "1.8.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/bunyan/-/@types/bunyan-1.8.6.tgz", + "integrity": "sha1-ZSdkHMowvt7F/rmrUnt4A7gABYI=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/color-name/-/@types/color-name-1.1.1.tgz", + "integrity": "sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA=", + "dev": true + }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/events/-/@types/events-3.0.0.tgz", + "integrity": "sha1-KGLz9Yqaf3w+eNefEw3U1xwlwqc=", + "dev": true + }, + "@types/formidable": { + "version": "1.0.31", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/formidable/-/@types/formidable-1.0.31.tgz", + "integrity": "sha1-J0+dwtChqc4f7vSMJMoIWefslHs=", + "dev": true, + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/graceful-fs/-/@types/graceful-fs-4.1.3.tgz", + "integrity": "sha1-A5rzX+Jr7DUAPo2G0u6cWGNUNI8=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/istanbul-lib-coverage/-/@types/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha1-S6jdtyAiH0MuRDvV+RF/0iz9R2I=", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/istanbul-lib-report/-/@types/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha1-wUwk8Y6oGQwRjudWK3/5mjZVJoY=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/istanbul-reports/-/@types/istanbul-reports-1.1.2.tgz", + "integrity": "sha1-6HXMaJ5HvOVJ7IHz315vbxHPrrI=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "25.2.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/jest/-/@types/jest-25.2.3.tgz", + "integrity": "sha1-M9J+TEcWyq5OztNVCXpHrTY/3K8=", + "dev": true, + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/jsonwebtoken": { + "version": "7.2.8", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-7.2.8.tgz", + "integrity": "sha512-XENN3YzEB8D6TiUww0O8SRznzy1v+77lH7UmuN54xq/IHIsyWjWOzZuFFTtoiRuaE782uAoRwBe/wwow+vQXZw==", + "requires": { + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.159", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.159.tgz", + "integrity": "sha512-gF7A72f7WQN33DpqOWw9geApQPh4M3PxluMtaHxWHXEGSN12/WbcEk/eNSqWNQcQhF66VSZ06vCF94CrHwXJDg==", + "dev": true + }, + "@types/lru-cache": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz", + "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==" + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/minimist/-/@types/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, + "@types/moment-timezone": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@types/moment-timezone/-/moment-timezone-0.5.13.tgz", + "integrity": "sha512-SWk1qM8DRssS5YR9L4eEX7WUhK/wc96aIr4nMa6p0kTk9YhGGOJjECVhIdPEj13fvJw72Xun69gScXSZ/UmcPg==", + "requires": { + "moment": ">=2.14.0" + } + }, + "@types/node": { + "version": "10.17.26", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/node/-/@types/node-10.17.26.tgz", + "integrity": "sha1-qKEZlgv/FrgjvkxhfaAoVwd5vP0=" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/normalize-package-data/-/@types/normalize-package-data-2.4.0.tgz", + "integrity": "sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=", + "dev": true + }, + "@types/prettier": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/prettier/-/@types/prettier-2.0.2.tgz", + "integrity": "sha1-W7Uu5o0PjvqcwAmZIOVr5sxON/M=", + "dev": true + }, + "@types/restify": { + "version": "8.4.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/restify/-/@types/restify-8.4.2.tgz", + "integrity": "sha1-8HHZcdEK159gc9+77tdynWh2Dn8=", + "dev": true, + "requires": { + "@types/bunyan": "*", + "@types/formidable": "*", + "@types/node": "*", + "@types/spdy": "*" + } + }, + "@types/spdy": { + "version": "3.4.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/spdy/-/@types/spdy-3.4.4.tgz", + "integrity": "sha1-MoL9StjEYDqkn3AX3VIKCKNFsrw=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/stack-utils/-/@types/stack-utils-1.0.1.tgz", + "integrity": "sha1-CoUdO9lkmPolwzq3J47TvWXwbD4=", + "dev": true + }, + "@types/tunnel": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.0.tgz", + "integrity": "sha512-FGDp0iBRiBdPjOgjJmn1NH0KDLN+Z8fRmo+9J7XGBhubq1DPrGrbmG4UTlGzrpbCpesMqD0sWkzi27EYkOMHyg==", + "requires": { + "@types/node": "*" + } + }, + "@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "requires": { + "@types/node": "*" + } + }, + "@types/xmldom": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.30.tgz", + "integrity": "sha512-edqgAFXMEtVvaBZ3YnhamvmrHjoYpuxETmnb0lbTZmf/dXpAsO9ZKotUO4K2rn2SIZBDFCMOuA7fOe0H6dRZcA==" + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/yargs/-/@types/yargs-15.0.5.tgz", + "integrity": "sha1-lH6aZWFIO97prf/Jg+kaaQKvi3k=", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@types/yargs-parser/-/@types/yargs-parser-15.0.0.tgz", + "integrity": "sha1-yz+fdBhp4gzOMw/765JxWQSDiC0=", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", + "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.34.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", + "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "abab": { + "version": "2.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/abab/-/abab-2.0.3.tgz", + "integrity": "sha1-Yj4gdeAustPyR15J+ZyRhGRnkHo=", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha1-hQEHVNtTw/uvO56j4IOqXF0Uf/0=", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha1-Rs3Tnw+P8IqHZhm1X1rIptx3C0U=", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha1-DeiJpgEgOQmw++B7iTjcIdLpZ7w=", + "dev": true + }, + "adal-node": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/adal-node/-/adal-node-0.2.1.tgz", + "integrity": "sha512-C/oasZuTy0NIqh5wPWjG/09XaG+zS7elC8upf1ZVExt9lSRncme4Ejbx8CKYk+wsGgj609y84txtRAXQVvqApg==", + "requires": { + "@types/node": "^8.0.47", + "async": "^2.6.3", + "date-utils": "*", + "jws": "3.x.x", + "request": "^2.88.0", + "underscore": ">= 1.3.1", + "uuid": "^3.1.0", + "xmldom": ">= 0.1.x", + "xpath.js": "~1.1.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.62", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.62.tgz", + "integrity": "sha512-76fupxOYVxk36kb7O/6KtrAPZ9jnSK3+qisAX4tQMEuGNdlvl7ycwatlHqjoE6jHfVtXFM3pCrCixZOidc5cuw==" + } + } + }, + "adaptive-expressions": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/adaptive-expressions/-/adaptive-expressions-4.10.0-rc0.tgz", + "integrity": "sha512-BDizGPxCi/+gShK7/4ijKAgFfV/inJH6vleVuy51uSPeWN/rhIHeD7PZFot1vPRkrwaMChvb3yeCjvxxLd2tug==", + "requires": { + "@microsoft/recognizers-text-data-types-timex-expression": "1.1.4", + "@types/atob-lite": "^2.0.0", + "@types/lru-cache": "^5.1.0", + "@types/moment-timezone": "^0.5.13", + "@types/xmldom": "^0.1.29", + "antlr4ts": "0.5.0-alpha.3", + "atob-lite": "^2.0.0", + "big-integer": "^1.6.48", + "jspath": "^0.4.0", + "lodash": "^4.17.19", + "lru-cache": "^5.1.1", + "moment": "^2.25.1", + "moment-timezone": "^0.5.28" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + } + } + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha1-GMWvOKER3etPJpe9eNaKvByr1wY=", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha1-pcR8xDGB8fOP/XB2g3cA05VSKmE=", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha1-l6vwhyMQ/tiKXEZrJWgVdhReM/E=", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha1-kK51xCTQCNJiTFvynq0xd+v881k=", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "antlr4ts": { + "version": "0.5.0-alpha.3", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.3.tgz", + "integrity": "sha512-La89tKkGcHFIVuruv4Bm1esc3zLmES2NOTEwwNS1pudz+zx/0FNqQeUu9p48i9/QHKPVqjN87LB+q3buTg7oDQ==" + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha1-xV7PAhheJGklk5kxDBc84xIzsUI=", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/atob/-/atob-2.1.2.tgz", + "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=", + "dev": true + }, + "atob-lite": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha1-oXs6jqgRBg501H0wYSJACtRJeuI=" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "babel-jest": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/babel-jest/-/babel-jest-26.1.0.tgz", + "integrity": "sha1-sgdRGF/HVpoPE1cwWEBE0cuTQyg=", + "dev": true, + "requires": { + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha1-hP2hnJduxcbe/vV/lCez3vZuF6M=", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha1-4VnM3Jr5XgtXDHW0Vzt8NNZx12U=", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.1.0.tgz", + "integrity": "sha1-xqd02ggkeigoViCmTfrb0F3VIzo=", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "0.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha1-tLVHrN2/ljy6VVup+cu7cL/QRNo=", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/babel-preset-jest/-/babel-preset-jest-26.1.0.tgz", + "integrity": "sha1-YS9xTltFc5Ss/YY3k8Vky8230cE=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.1.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/base/-/base-0.11.2.tgz", + "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" + }, + "bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + }, + "botbuilder": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.10.0-rc0.tgz", + "integrity": "sha512-xe/SAF50troW5fbQlplnPVSEKcp2lJVIPVEqrgXOsQAPDT0iYyzo7UjXlEOgiFpTGA5aQZV0KvaSP28UW9ED+g==", + "requires": { + "@azure/ms-rest-js": "1.8.15", + "@types/node": "^10.17.27", + "axios": "^0.19.0", + "botbuilder-core": "4.10.0-rc0", + "botframework-connector": "4.10.0-rc0", + "botframework-streaming": "4.10.0-rc0", + "filenamify": "^4.1.0", + "fs-extra": "^7.0.1", + "moment-timezone": "^0.5.28" + }, + "dependencies": { + "@types/node": { + "version": "10.17.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.28.tgz", + "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==" + } + } + }, + "botbuilder-ai": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botbuilder-ai/-/botbuilder-ai-4.10.0-rc0.tgz", + "integrity": "sha512-Elc5Dt8H+fwNoV0nSpLflfG1KwFv/vuuDhjd3SV0CKbjft8IbUF7kxTn2Yu9Ct/xqVd7Z37t0CUKAvJDjgyvnA==", + "requires": { + "@azure/cognitiveservices-luis-runtime": "2.0.0", + "@azure/ms-rest-js": "1.8.15", + "@microsoft/recognizers-text-date-time": "1.1.4", + "@types/node": "^10.17.27", + "botbuilder-core": "4.10.0-rc0", + "botbuilder-dialogs": "4.10.0-rc0", + "node-fetch": "^2.6.0", + "url-parse": "^1.4.4" + }, + "dependencies": { + "@types/node": { + "version": "10.17.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.28.tgz", + "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==" + } + } + }, + "botbuilder-core": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.10.0-rc0.tgz", + "integrity": "sha512-TtoTma9k9hgjcB/C50uECgslKkajEZnQGGQ5+LpQauTROZ+LyokuBweYyO3xli9Ts7pgbxIaEkqYg/59g6+4lQ==", + "requires": { + "assert": "^1.4.1", + "botframework-schema": "4.10.0-rc0" + } + }, + "botbuilder-dialogs": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs/-/botbuilder-dialogs-4.10.0-rc0.tgz", + "integrity": "sha512-O/mygRgOqXaH//TH1xU98+jrZsOttQhDPODizMD3HiMnxSNhi544KvU/SK/K9upDULbN7RzPpkvPdsbHEar2rQ==", + "requires": { + "@microsoft/recognizers-text-choice": "1.1.4", + "@microsoft/recognizers-text-date-time": "1.1.4", + "@microsoft/recognizers-text-number": "1.1.4", + "@microsoft/recognizers-text-suite": "1.1.4", + "@types/node": "^10.17.27", + "botbuilder-core": "4.10.0-rc0", + "globalize": "^1.4.2" + }, + "dependencies": { + "@types/node": { + "version": "10.17.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.28.tgz", + "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==" + } + } + }, + "botbuilder-dialogs-adaptive": { + "version": "4.10.0-rc0-preview", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs-adaptive/-/botbuilder-dialogs-adaptive-4.10.0-rc0-preview.tgz", + "integrity": "sha512-Vxl7gBnE2+jsZrIL1b2Ckv4tHq7noPbkMaEryqG2h1ean2dugAcdYJ2e1Iqv/RbIDuUAjCb0g+eLpSxq34luYg==", + "requires": { + "@microsoft/recognizers-text-suite": "1.1.4", + "adaptive-expressions": "4.10.0-rc0", + "botbuilder-ai": "4.10.0-rc0", + "botbuilder-core": "4.10.0-rc0", + "botbuilder-dialogs": "4.10.0-rc0", + "botbuilder-dialogs-declarative": "4.10.0-rc0-preview", + "botbuilder-lg": "4.10.0-rc0", + "botframework-connector": "4.10.0-rc0", + "botframework-schema": "4.10.0-rc0", + "jsonpath": "^1.0.0", + "node-fetch": "^2.6.0" + } + }, + "botbuilder-dialogs-declarative": { + "version": "4.10.0-rc0-preview", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs-declarative/-/botbuilder-dialogs-declarative-4.10.0-rc0-preview.tgz", + "integrity": "sha512-R4GS2toR7MycwBlpObdlTYcjFYjdH0SwdpMkzC6/hs5enPU6SiUQ3gwLyAA138NUpb0UgZXjG8wKsOscbIDgRA==", + "requires": { + "chokidar": "^3.4.0", + "jsonpath": "^1.0.0" + } + }, + "botbuilder-lg": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botbuilder-lg/-/botbuilder-lg-4.10.0-rc0.tgz", + "integrity": "sha512-729oT/hpD/blOBKqy3C1wldbMHLprqojGwhAzw3m9o+0W/yk3SPX8HxaqjQf1jARQRxszoswSSZhyYQeSYIC8Q==", + "requires": { + "adaptive-expressions": "4.10.0-rc0", + "antlr4ts": "0.5.0-alpha.3", + "lodash": "^4.17.19", + "path": "^0.12.7", + "uuid": "^3.4.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + } + } + }, + "botframework-connector": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.10.0-rc0.tgz", + "integrity": "sha512-Rq81lqJotpg3GDQz9M6BbcXSs0VY+CqRquqGGePRYsEhgdkM6MuPAfFklj/s4+KNM8jEzMQNzSobbhDmckn22Q==", + "requires": { + "@azure/ms-rest-js": "1.8.15", + "@types/jsonwebtoken": "7.2.8", + "@types/node": "^10.17.27", + "adal-node": "0.2.1", + "base64url": "^3.0.0", + "botframework-schema": "4.10.0-rc0", + "form-data": "^2.3.3", + "jsonwebtoken": "8.0.1", + "node-fetch": "^2.6.0", + "rsa-pem-from-mod-exp": "^0.8.4" + }, + "dependencies": { + "@types/node": { + "version": "10.17.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.28.tgz", + "integrity": "sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==" + } + } + }, + "botframework-schema": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.10.0-rc0.tgz", + "integrity": "sha512-ZK6IDvyYUE3SrGvt4ZxQ8DX8AGjSz94HM9Ynhkxr2RvflPlRS7ojVD2X1+WFNiwTpB9MNWX1i/HQM0aX4I7t1Q==" + }, + "botframework-streaming": { + "version": "4.10.0-rc0", + "resolved": "https://registry.npmjs.org/botframework-streaming/-/botframework-streaming-4.10.0-rc0.tgz", + "integrity": "sha512-/2uDX9FZBMC7UvUeBR0DjFf/fMGiHNrPEMtRIBfMksoM9+1qEaLfs3J2agG269V+YflS1UZW4Wf2PFX4W2yrhg==", + "requires": { + "@types/ws": "^6.0.3", + "uuid": "^3.4.0", + "ws": "^7.1.2" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/braces/-/braces-3.0.2.tgz", + "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha1-PJtLfXgsgSHlbxAQbYTA0P/JRiY=", + "dev": true + }, + "browserslist": { + "version": "4.13.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/browserslist/-/browserslist-4.13.0.tgz", + "integrity": "sha1-QlVsugEeGwondbYRy6ao7KGOlA0=", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001093", + "electron-to-chromium": "^1.3.488", + "escalade": "^3.0.1", + "node-releases": "^1.1.58" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/bser/-/bser-2.1.1.tgz", + "integrity": "sha1-5nh9og7OnQeZhTPP2d5vXDj0vAU=", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=", + "dev": true + }, + "bunyan": { + "version": "1.8.14", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/bunyan/-/bunyan-1.8.14.tgz", + "integrity": "sha1-PYwa/qfeFYpSOMfLimarazjdRbQ=", + "requires": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001104", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/caniuse-lite/-/caniuse-lite-1.0.30001104.tgz", + "integrity": "sha1-Tj1bOx3Tw1KfEMt/UZxiuj5Xn10=", + "dev": true + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha1-+5U7+uvreB9iiYI52rtCbQilCaQ=", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha1-10Q1giYhf5ge1Y9Hmx1rzClUXc8=", + "dev": true + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha1-Z6npZL4xpR4V5QENWObxKDQAL0Y=", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cldrjs": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.4.tgz", + "integrity": "sha512-6QkI7oPLUZ9vA5BQAmUOfh5JIpESfnYy/M8d7Ddl9Yx+z2TAnQgnc3kbgjkIgxsk5Y0tOY+n6itMWXzQQQ2IWg==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE=", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha1-zCyOlPwYu9/+ZNZTRXDIpnOyf1k=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true + } + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha1-KlHZpOJd/W5pAlGqgfmePAVIHxw=", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-7.0.0.tgz", + "integrity": "sha1-XzyjV2HkfgWyBsba/yz4FPAxa44=", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/which/-/which-1.3.1.tgz", + "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha1-WmbPk9LQtmHYC/akT7ZfXC5OChA=", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha1-/2ZaDdvcMYZLCWR/NBY0Q9kLCFI=", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha1-nxJ29bK0Y/IRTT8sdSUK+MGjb0o=", + "dev": true + } + } + }, + "csv": { + "version": "5.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/csv/-/csv-5.3.2.tgz", + "integrity": "sha1-ULNE4l37uMYmhKG87BjCJGiyFh4=", + "requires": { + "csv-generate": "^3.2.4", + "csv-parse": "^4.8.8", + "csv-stringify": "^5.3.6", + "stream-transform": "^2.0.1" + } + }, + "csv-generate": { + "version": "3.2.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/csv-generate/-/csv-generate-3.2.4.tgz", + "integrity": "sha1-RA2rkXcznuBnbJ5cFvUOKzRjwBk=" + }, + "csv-parse": { + "version": "4.12.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/csv-parse/-/csv-parse-4.12.0.tgz", + "integrity": "sha1-/ULWKRu6rdUdMAn2ytuz5TtM4CY=" + }, + "csv-stringify": { + "version": "5.5.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/csv-stringify/-/csv-stringify-5.5.1.tgz", + "integrity": "sha1-9CzdN5sPfxQpM6EfZ0sakevQ/NA=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha1-FWSFpyljqXD11YIar2Qr7yvy25s=", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "date-utils": { + "version": "1.2.21", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/date-utils/-/date-utils-1.2.21.tgz", + "integrity": "sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha1-OUZhE6ngNhEdAvgkibX9awte0jE=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha1-RNLqNnm49NT/ujPwPYZfwee/SVU=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha1-V29d/GOuGhkv8ZLYrTr2MImRtlE=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha1-AU7o+PZpxcWAI9pkuBecCDooxGw=" + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha1-X0Z8AO3TU1K3vKRteSfWDmh6dt0=", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha1-+0Su+6eT4VdLCvau0oAdBXUp8wQ=", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha1-rlnIoAsSFUOirMZcBDT1ew/BGv8=", + "dev": true + } + } + }, + "dtrace-provider": { + "version": "0.8.8", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha1-KZbVSQw34TR74mO0I+17KX+w2X4=", + "optional": true, + "requires": { + "nan": "^2.14.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.502", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/electron-to-chromium/-/electron-to-chromium-1.3.502.tgz", + "integrity": "sha1-alXpk+9goB+9whUu9eR+4AyIXJg=", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/escalade/-/escalade-3.0.2.tgz", + "integrity": "sha1-algNcO24eIDyK0yR0NVgeN9pYsQ=", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-regexp-component": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", + "integrity": "sha1-nGO20LJf8qiMOtvRjFthrMO5+qI=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM=", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=" + } + } + }, + "eslint": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.0.0.tgz", + "integrity": "sha512-qY1cwdOxMONHJfGqw52UOpZDeqXy8xmD0u8CT6jIstil72jkhURC704W8CFyTPDPllz4z4lu0Ql1+07PG/XdIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.1.0", + "espree": "^7.0.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-plugin-prettier": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz", + "integrity": "sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz", + "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==", + "dev": true, + "requires": { + "acorn": "^7.3.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + } + }, + "esprima": { + "version": "1.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs=" + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "ewma": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ewma/-/ewma-2.0.1.tgz", + "integrity": "sha1-mHbBxJGsVzPIZmABo5YaBMl88eg=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha1-OgGM61JsxvbfK7UEsr/o46STTsU=", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/execa/-/execa-1.0.0.tgz", + "integrity": "sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg=", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/expect/-/expect-26.1.0.tgz", + "integrity": "sha1-jGLjHQ+NWo67GG7oFHPRXdL798g=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-regex-util": "^26.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend/-/extend-3.0.2.tgz", + "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-decode-uri-component": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha1-Rvi2wisw/3qBNX1PWav66TggJUM=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha1-/IT7OdJwnPP/bXQ3BhV7tXCKioU=", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" + }, + "filenamify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.1.0.tgz", + "integrity": "sha512-KQV/uJDI9VQgN7sHH1Zbk6+42cD6mnQ2HONzkXUfPJ+K2FC8GZ1dpewbbHw0Sz8Tf5k3EVdHVayM4DoAwWlmtg==", + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-my-way": { + "version": "2.2.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/find-my-way/-/find-my-way-2.2.3.tgz", + "integrity": "sha1-Up9ZadvR5uvtZ0p6EIfDQwmI454=", + "requires": { + "fast-decode-uri-component": "^1.0.0", + "safe-regex2": "^2.0.0", + "semver-store": "^0.3.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/formidable/-/formidable-1.2.2.tgz", + "integrity": "sha1-v2muopcpgmdfAIZTQrmCmG9rjdk=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha1-+3OHA66NL5/pAMM4Nt3r7ouX8j4=", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha1-WPQ2H/mH5f9uHnohCCeqNx6qwmk=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha1-jeLYA8/0TfO8bEVuZmizbDkm4Ro=", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha1-wbJVV189wh1Zv8ec09K0axw6VLU=", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "6.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globalize": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/globalize/-/globalize-1.5.0.tgz", + "integrity": "sha512-76fcPQO/WLthtSwjgIZ/Zv2XSXqv9ifvl1PwIxJNCZNFHigGCpg3fBZ0poJ30b2kdDgofPkYl478lVZA6esESQ==", + "requires": { + "cldrjs": "^0.5.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/globals/-/globals-11.12.0.tgz", + "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha1-hX95zjWVgMNA1DCBzGSJcNC7I04=" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha1-HvievT5JllV2de7ZiTEQ3DUPoIA=", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha1-dTm9S8Hg4KiVgVouAmJCCxKFhIg=", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + } + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha1-QqbcT9M/ACgRduiyN1nKTk+hhfM=", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha1-39YAJ9o2o238viNiYsAKWCJoFFM=", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha1-xbHNFPUK6uCatsWf5jujOV/k36M=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha1-qM/QQx0d5KIZlwPQA+PmI2T6bbY=", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY=", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha1-a8YzQYGBDgS1wis9WJ/cpVAmQEw=", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha1-LLDfDnXi0GT+GGTDfN6st7Lc8ls=", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha1-fRQK3DiarzARqPKipM+m+q3/sRg=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha1-dKTHbnfKn9P5MvKQwX6jJs0VcnE=", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha1-9ZRKN8cLVQsCp4pcOyBVsoDOyOw=", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha1-hzxv/4l0UBGCIndGlqPyiQLXfB0=", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-6.3.0.tgz", + "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha1-dRj+UupE3jcvRgp2tezan/tz2KY=", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha1-dXQ85tlruG3H7kNSz2Nmoj8LGtk=", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-4.1.1.tgz", + "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ms/-/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha1-1ZMhDlAAaDdQywn8BkTktuJ/1Ts=", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest/-/jest-26.1.0.tgz", + "integrity": "sha1-LzqnvP+5v9AlRz+Du79Go68CYmM=", + "dev": true, + "requires": { + "@jest/core": "^26.1.0", + "import-local": "^3.0.2", + "jest-cli": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-cli": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-cli/-/jest-cli-26.1.0.tgz", + "integrity": "sha1-657IoYzztqpVbZ3qqeJL4StDrYc=", + "dev": true, + "requires": { + "@jest/core": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-changed-files/-/jest-changed-files-26.1.0.tgz", + "integrity": "sha1-3maw8wRTvKKv+Y6UAPdZBdpJUwU=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/execa/-/execa-4.0.3.tgz", + "integrity": "sha1-CjTau61tZhAL1vLFdshmlAPzF/I=", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha1-ASA83JJZf5uQkGfD5lbMH008Tck=", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha1-venDJoDW+uBBKdasnZIc54FfeOM=", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha1-t+zR5e1T2o43pV4cImnguX7XSOo=", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", + "dev": true + } + } + }, + "jest-config": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-config/-/jest-config-26.1.0.tgz", + "integrity": "sha1-kHT3U5rMGF4BE61tIu1YnBajenM=", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.1.0", + "@jest/types": "^26.1.0", + "babel-jest": "^26.1.0", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.1.0", + "jest-environment-node": "^26.1.0", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "micromatch": "^4.0.2", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha1-HdJu1k+WZnwGjO8Ca2d9+gGvz6k=", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha1-Pi+iCJn8koyxO9D/aL03EaNoibU=", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-each/-/jest-each-26.1.0.tgz", + "integrity": "sha1-41RJh1AJoi100b2hg7MG2yDyhvc=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-environment-jsdom/-/jest-environment-jsdom-26.1.0.tgz", + "integrity": "sha1-nccxP/4bWXYdrR/tt24lA+XTfFs=", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0", + "jsdom": "^16.2.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-environment-node": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-environment-node/-/jest-environment-node-26.1.0.tgz", + "integrity": "sha1-i7OHs+77Ey6reCb5qAjk4FYYlgs=", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha1-Cwoy+riQi0TVCL6BaBSH26u42Hc=", + "dev": true + }, + "jest-haste-map": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-haste-map/-/jest-haste-map-26.1.0.tgz", + "integrity": "sha1-7zEgm+c/CbDZRF59IT4bU9DRR2o=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-jasmine2": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz", + "integrity": "sha1-Tf40mystPGs6J8Ak/Uy1esDtS28=", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.1.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0", + "throat": "^5.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-leak-detector": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-leak-detector/-/jest-leak-detector-26.1.0.tgz", + "integrity": "sha1-A5w6B+vNit+phLasAVdSw1eS4KY=", + "dev": true, + "requires": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-matcher-utils": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-matcher-utils/-/jest-matcher-utils-26.1.0.tgz", + "integrity": "sha1-z3WkG9QT3aeE8CLeWmWipcc6XJI=", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.1.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha1-B2AFmlwodje4Qr1whTEdtwYOiKY=", + "dev": true + }, + "jest-diff": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-diff/-/jest-diff-26.1.0.tgz", + "integrity": "sha1-AKVJvck2yWketNwl0fvXi/RWq7I=", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-message-util": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-message-util/-/jest-message-util-26.1.0.tgz", + "integrity": "sha1-Ulc/u49c6kQ8TRdHgE16I4o+Izw=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.1.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-mock": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-mock/-/jest-mock-26.1.0.tgz", + "integrity": "sha1-gNgobaHwWjRfutG/1vpJqJlGXT0=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha1-twSsCuAoqJEIpNBAs/kZ393I4zw=", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha1-0l5xhLNuOf1GbDvEG+CXHoIf7ig=", + "dev": true + }, + "jest-resolve": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-resolve/-/jest-resolve-26.1.0.tgz", + "integrity": "sha1-pTDqowKx9voEeQedFWHdaavADmg=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.1.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-resolve-dependencies/-/jest-resolve-dependencies-26.1.0.tgz", + "integrity": "sha1-HONkcvhkpdrffcgvoVjhx3lVaRs=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-runner": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-runner/-/jest-runner-26.1.0.tgz", + "integrity": "sha1-RX9/xSKv5Gym2x3M8Z+H9QCzKI0=", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.1.0", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.1.0", + "jest-jasmine2": "^26.1.0", + "jest-leak-detector": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-resolve": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-runtime": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-runtime/-/jest-runtime-26.1.0.tgz", + "integrity": "sha1-RaN69CEV8SPtXFHxJsBVAtokacs=", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/globals": "^26.1.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "jest-serializer": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-serializer/-/jest-serializer-26.1.0.tgz", + "integrity": "sha1-cqOUUx/JsI4XPcfSl0QKxhDZUCI=", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-snapshot/-/jest-snapshot-26.1.0.tgz", + "integrity": "sha1-w27R4DNL170v5a0H6To2Tq1+E0k=", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.1.0", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.1.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.1.0", + "jest-get-type": "^26.0.0", + "jest-haste-map": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-resolve": "^26.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.1.0", + "semver": "^7.3.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha1-B2AFmlwodje4Qr1whTEdtwYOiKY=", + "dev": true + }, + "jest-diff": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-diff/-/jest-diff-26.1.0.tgz", + "integrity": "sha1-AKVJvck2yWketNwl0fvXi/RWq7I=", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-7.3.2.tgz", + "integrity": "sha1-YElisFK4HtB4aq6EOJ/7pw/9OTg=", + "dev": true + } + } + }, + "jest-util": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-util/-/jest-util-26.1.0.tgz", + "integrity": "sha1-gOhdS6gg3srPQaaRwgQtUnbl2Ng=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-validate": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-validate/-/jest-validate-26.1.0.tgz", + "integrity": "sha1-lCyFrT1g94JQxIin+F2PEaKXiOc=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "camelcase": { + "version": "6.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha1-Uln3ww414njxvcKk2RIws3ytmB4=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha1-OB6YanGJmNv6/NXsBZNL5TjbQDk=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha1-Jyuc0fGpJKtdRD3CJImdemXLluw=", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-watcher": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-watcher/-/jest-watcher-26.1.0.tgz", + "integrity": "sha1-mYEqDNkx8Ms9FTGAQmE1q4Pk2PI=", + "dev": true, + "requires": { + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.1.0", + "string-length": "^4.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/@jest/types/-/@jest/types-26.1.0.tgz", + "integrity": "sha1-+K+qrusjtcrUndH3d5aJlB3LYFc=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha1-ThSHCmGNni7dl92DRf2dncMVZGo=", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-worker": { + "version": "26.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jest-worker/-/jest-worker-26.1.0.tgz", + "integrity": "sha1-ZdVkGvdOCMzVYcJA59thKE+C8z0=", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha1-p6NBcPJqIbsWJCTYray0ETpp5II=", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "16.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsdom/-/jsdom-16.3.0.tgz", + "integrity": "sha1-dWkLfaw2xnvknDNtzXIZu77QgQw=", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha1-nfT1fnOcJpMKAYGEiH9K233Kc7I=", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/json5/-/json5-2.1.3.tgz", + "integrity": "sha1-ybD3+pIzv+WAf+ZvzzpWF+1ZfUM=", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonpath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.2.tgz", + "integrity": "sha512-rmzlgFZiQPc6q4HDyK8s9Qb4oxBnI5sF61y/Co5PV0lc3q2bIuRsNdueVbhoSHdKM4fxeimphOAtfz47yjCfeA==", + "requires": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.7.0" + }, + "dependencies": { + "underscore": { + "version": "1.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" + } + } + }, + "jsonwebtoken": { + "version": "8.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsonwebtoken/-/jsonwebtoken-8.0.1.tgz", + "integrity": "sha1-UNrvjQqMfeLNBrwQE7dbBMzz8M8=", + "requires": { + "jws": "^3.1.4", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "jspath": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/jspath/-/jspath-0.4.0.tgz", + "integrity": "sha512-2/R8wkot8NCXrppBT/onp+4mcAUAZqtPxsW6aSJU3hrFAVqKqtFYcat2XJZ7inN4RtATUxfv0UQSYOmvJKiIGA==" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha1-p5yezIbuHOP6YgbRIWxQHxR/wH4=", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/leven/-/leven-3.1.0.tgz", + "integrity": "sha1-d4kd6DQGTMy6gq54QrtrFKE+1/I=", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha1-hCqe6Y0gdap/ru2+MmeekgX0b3c=", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.last": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.last/-/lodash.last-3.0.0.tgz", + "integrity": "sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw=" + }, + "lodash.max": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.max/-/lodash.max-4.0.1.tgz", + "integrity": "sha1-hzVWbGGLNan3YFILSHrnllivE2o=" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lodash.tonumber": { + "version": "4.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz", + "integrity": "sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk=" + }, + "lodash.trimend": { + "version": "4.5.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lodash.trimend/-/lodash.trimend-4.5.1.tgz", + "integrity": "sha1-EoBENyhrmMrYmWt5QU4RMAEUCC8=" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA=", + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha1-QV6WcEazp/HRhSd9hKpYIDcmoT8=", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-6.3.0.tgz", + "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", + "dev": true + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk=", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mime/-/mime-2.4.6.tgz", + "integrity": "sha1-5bQHyQ20QvK+tbFiNz0Htpr/pNE=" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I=" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8=", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mixme": { + "version": "0.3.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mixme/-/mixme-0.3.5.tgz", + "integrity": "sha1-MEZSza8ko98EhyBeYaxhYsaQbd0=" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8=", + "requires": { + "minimist": "^1.2.5" + } + }, + "moment": { + "version": "2.27.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/moment/-/moment-2.27.0.tgz", + "integrity": "sha1-i/9OPiaiNiIN/j423nVrbrqgEF0=" + }, + "moment-timezone": { + "version": "0.5.31", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.31.tgz", + "integrity": "sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "mv": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + } + }, + "nan": { + "version": "2.14.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/nan/-/nan-2.14.1.tgz", + "integrity": "sha1-174036MQW5FJTDFHCJMV7/iHSwE=", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=", + "dev": true + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "7.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-notifier/-/node-notifier-7.0.1.tgz", + "integrity": "sha1-o1XjPmvrrO+b+FYmia7Q9CMMpvk=", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^7.2.1", + "shellwords": "^0.1.1", + "uuid": "^7.0.3", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-7.3.2.tgz", + "integrity": "sha1-YElisFK4HtB4aq6EOJ/7pw/9OTg=", + "dev": true, + "optional": true + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha1-xcnyyM8l3Ao3LE3xRBxB9b0MaAs=", + "dev": true, + "optional": true + } + } + }, + "node-releases": { + "version": "1.1.59", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/node-releases/-/node-releases-1.1.59.tgz", + "integrity": "sha1-TWSDMGQc7HBL/xD45P4o5FOrjo4=", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg=", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha1-IEh5qePQaP8qVROcLHcngGgaOLc=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha1-lovxEA15Vrs8oIbwBvhGs7xACNo=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha1-//DzyRYX/mK7UBiWNumayKbfe+U=", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha1-lhyN0/GV6pbHR+Y2smK4AKaxr0g=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha1-c+URTJhtFD76NxLU6iTbmkJm9g8=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path": { + "version": "0.12.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha1-IfMz6ba46v8CRo9RRupAbTRfTa0=" + }, + "pidusage": { + "version": "2.0.21", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha1-cGiWez2VK66nPldmjJi56qh2iU4=", + "requires": { + "safe-buffer": "^5.2.1" + } + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha1-ZDqSyviUVm+RsrmG0sZpUKji+4c=", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha1-eHPB13T2gsNLjUi2dDor8qxVeRo=", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha1-SAVy2J7POVZtK9P+LJ/Mt8TAsGg=", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/psl/-/psl-1.8.0.tgz", + "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/pump/-/pump-3.0.0.tgz", + "integrity": "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ=", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/qs/-/qs-6.5.2.tgz", + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=" + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=" + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w=", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha1-jSojcNPfiG61yQraHFv2GIrPg4s=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha1-86YTV1hFlzOuK5VjgFbhhU5+9Qc=", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" + } + } + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerate": { + "version": "1.4.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha1-ytkq2Oa1kXc0hfvgWkhcr09Ffm8=", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha1-5d5xEdZV57pgwFfb6f83yH5lzew=", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha1-2Hih0JS0MG0QuQlkhLM+vVXiZpc=", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha1-yY2hVGg2ccnE3LFuznNlF+G3/rQ=", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha1-/L9FjFBDGwu3tF1pZ7gZLZHz2Tg=", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha1-kv8pX7He7L9uzaslQ9IH6RqjNzM=", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha1-p2n4aEMIQBpm6bUp0kNv9NBmYnI=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha1-eC4NglwMWjuzlzH4Tv7mt0Lmsc4=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/request/-/request-2.88.2.tgz", + "integrity": "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM=", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha1-6aPAgbUTgN/qZ3M2Bh/qh5qCnuk=", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha1-pFW5YLgm5E4r+Jma9k3/K/5YyzY=", + "dev": true, + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha1-sllBtUloIxzC0bt2p5y38sC/hEQ=", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha1-DwB18bslRHZs9zumpuKt/ryxPy0=", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha1-w1IlhD3493bfIcV1V7wIfp39/Gk=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restify": { + "version": "8.5.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/restify/-/restify-8.5.1.tgz", + "integrity": "sha1-HLq0HvagmQ56usYqWxIYL1kcGgw=", + "requires": { + "assert-plus": "^1.0.0", + "bunyan": "^1.8.12", + "csv": "^5.1.1", + "dtrace-provider": "^0.8.1", + "escape-regexp-component": "^1.0.2", + "ewma": "^2.0.1", + "find-my-way": "^2.0.1", + "formidable": "^1.2.1", + "http-signature": "^1.2.0", + "lodash": "^4.17.11", + "lru-cache": "^5.1.1", + "mime": "^2.4.3", + "negotiator": "^0.6.2", + "once": "^1.4.0", + "pidusage": "^2.0.17", + "qs": "^6.7.0", + "restify-errors": "^8.0.2", + "semver": "^6.1.1", + "send": "^0.16.2", + "spdy": "^4.0.0", + "uuid": "^3.3.2", + "vasync": "^2.2.0" + }, + "dependencies": { + "qs": { + "version": "6.9.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/qs/-/qs-6.9.4.tgz", + "integrity": "sha1-kJCykNH5FyjTwi5UhDykSupatoc=" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-6.3.0.tgz", + "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=" + } + } + }, + "restify-errors": { + "version": "8.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/restify-errors/-/restify-errors-8.0.2.tgz", + "integrity": "sha1-C5Z4c443iI5P7+Uqpu6Sdx7JVOk=", + "requires": { + "@netflix/nerror": "^1.0.0", + "assert-plus": "^1.0.0", + "lodash": "^4.17.15", + "safe-json-stringify": "^1.0.4" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ret/-/ret-0.1.15.tgz", + "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", + "dev": true + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + }, + "rsa-pem-from-mod-exp": { + "version": "0.8.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.4.tgz", + "integrity": "sha1-NipCxtMEBW1JOz8SvOq7LGV2ptQ=" + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha1-yPFVMR0Wf2jyHhaN9x7FsIMRNzQ=", + "dev": true + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", + "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=" + }, + "safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha1-NW5EvJjx+TzkXfFLzXwBzahuCv0=", + "optional": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safe-regex2": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-regex2/-/safe-regex2-2.0.0.tgz", + "integrity": "sha1-sodSTDl8eimURwNn4BheGRax9bk=", + "requires": { + "ret": "~0.2.0" + }, + "dependencies": { + "ret": { + "version": "0.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ret/-/ret-0.2.2.tgz", + "integrity": "sha1-toYXgqH0di3OQ0Aqcet6KD9EVzw=" + } + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + }, + "sane": { + "version": "4.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/sane/-/sane-4.1.0.tgz", + "integrity": "sha1-7Ygf2SJzOmxGG8GJ3CtsAG8//e0=", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/braces/-/braces-2.3.2.tgz", + "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha1-7rq5U/o7dgjb6U5drbFciI+maW0=", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver/-/semver-5.7.1.tgz", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "dev": true + }, + "semver-store": { + "version": "0.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/semver-store/-/semver-store-0.3.0.tgz", + "integrity": "sha1-zmAv8H3zcIDsn0+0CylXZUe+++k=" + }, + "send": { + "version": "0.16.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/send/-/send-0.16.2.tgz", + "integrity": "sha1-bsyh4PjBVtFBWXVZhI32RzCmu8E=", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "requires": { + "ms": "2.0.0" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/mime/-/mime-1.4.1.tgz", + "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=" + } + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha1-1rkYHBpI05cyTISHHvvPxz/AZUs=", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw=", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha1-E01oEpd1ZDfMBcoBNw06elcQde0=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/slash/-/slash-3.0.0.tgz", + "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha1-GQhmvs51U+H48mei7oLGBrVQmho=", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha1-qYti+G3K9PZzmWSMCFKRq56P7WE=", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha1-3s6BrJweZxPl99G28X1Gj6U9iak=", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha1-PyjOGnegA3JoPq3kpDMYNSeiFj0=", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha1-z3D1BILu/cmOPOCmgz5KU87rpnk=", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha1-NpS1gEVnpFjTyARYQqY1hjL2JlQ=", + "dev": true + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha1-t09GYgOj7aRSwCSSuR+56EonZ3s=", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-4.1.1.tgz", + "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ms/-/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha1-ANSGOmQArXXfkzYaFghgXl3NzzE=", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/debug/-/debug-4.1.1.tgz", + "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ms/-/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc=", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha1-XPSLRVe+y0Y40LxPIdI/XRlYZZM=", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha1-owME6Z2qMuI7L9IPUbq9B8/8o0Q=", + "dev": true + } + } + }, + "static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "requires": { + "escodegen": "^1.8.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "stream-transform": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/stream-transform/-/stream-transform-2.0.2.tgz", + "integrity": "sha1-PLehTIAus5vEDKqrBTXlhPOmXK8=", + "requires": { + "mixme": "^0.3.1" + } + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha1-Spc78x73fE7bzq3WryYRmWmF+KE=", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha1-nDUFwdtFvO3KPZz3oW9cWqOQGHg=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha1-aOMlkd9z4lrRxLSRCKLsUHliv9E=", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha1-9mPfJSr183xdSbvX7u+p4Lnlnkc=", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha1-QwY30ki6d+B4iDlR+5qg7tfGP6I=", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha1-FKZKJ6s8Dfkz6lRvulXy0HjtyZQ=", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha1-BKhphmHYBepvopO2y55jrARO8V4=", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/glob/-/glob-7.1.6.tgz", + "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/throat/-/throat-5.0.0.tgz", + "integrity": "sha1-xRmSNYA6rRh1SmZ9ZZtecs4Wdks=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI=", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha1-Ayc1ht7xWVrgj+2zjXczzukdJHk=", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha1-CeJJ696FHTseSNJ8EFREZn8XuD0=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha1-qX7nqf9CaRufeD/xvFES/j/KkIA=", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.9.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha1-mNYApevcOPQMsndSLxLcgA6eJfo=", + "dev": true + }, + "underscore": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==" + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha1-JhmADEyCWADv3YNDr33Zkzy+KBg=", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha1-jtKjJWmWG86SJ9Cc0/+7j+1fAgw=", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha1-DZH2AO7rMJaqlisdb8iIduZOpTE=", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha1-3Vepn2IHvt/0Yoq++5TFDblByPQ=", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/use/-/use-3.1.1.tgz", + "integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=" + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha1-uXk28hwOLZmW1JheXFFW6dTknNY=", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha1-UwL4FpAxc1ImVECS5kmB91F1A4M=", + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vasync": { + "version": "2.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/vasync/-/vasync-2.2.0.tgz", + "integrity": "sha1-z951GGChWCLbOxMrxZsRakra8Bs=", + "requires": { + "verror": "1.10.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha1-ConN9cwVgi35w2BUNnaWPgzDCM0=", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha1-PnEEoFt1FGzGD1ZDgLf2g6zxAgo=", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha1-wdjRSTFtPqhShIiVy2oL/oh7h98=", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha1-kRG01+qArNQPUnDWZmIa+ni2lRQ=", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha1-WrrPd3wyFmpR0IXWtPPn0nET3bA=", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha1-PUseAxLSB5h5+Cav8Y2+7KWWD78=", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha1-xiis3PRbgidM5yge4x3TyDl5F3E=", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha1-rlnIoAsSFUOirMZcBDT1ew/BGv8=", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/which/-/which-2.0.2.tgz", + "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha1-6Tk7oHEC5skaOyIUePAlfNKFblM=", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha1-Vr1cWlxwSBzRnFcb05q5ZaXeVug=", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.3.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/ws/-/ws-7.3.1.tgz", + "integrity": "sha1-0FR79n985PEqct/jEmLGjX3FUcg=" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha1-auc+Bt5NjG5H+fsYH3jWSK1FfGo=", + "dev": true + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha1-Bg/hvLf5x2/ioX24apvDq4lCEMs=", + "dev": true + }, + "xmldom": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.3.0.tgz", + "integrity": "sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g==" + }, + "xpath.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", + "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha1-le+U+F7MgdAHwmThkKEg8KPIVms=", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0=" + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha1-DYehbeAa7p2L7Cv7909nhRcw9Pg=", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha1-vmjEl1xrKr9GkjawyHA2L6sJp7A=", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/runtime/node/package.json b/runtime/node/package.json new file mode 100644 index 0000000000..e48c49caf9 --- /dev/null +++ b/runtime/node/package.json @@ -0,0 +1,47 @@ +{ + "name": "node-runtime", + "version": "1.0.0", + "description": "", + "main": "./lib/webapp.js", + "scripts": { + "test": "jest", + "test:watch": "jest --watch", + "start": "node ./lib/webapp.js", + "start:function": "node ./lib/function.js", + "build": "tsc", + "lint": "eslint --quiet --ext .js,.ts,.tsx ./src", + "lint:fix": "npm run lint --fix" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@azure/functions": "^1.2.2", + "botbuilder": "4.10.0-rc0", + "botbuilder-dialogs": "4.10.0-rc0", + "botbuilder-dialogs-adaptive": "4.10.0-rc0-preview", + "botbuilder-dialogs-declarative": "4.10.0-rc0-preview", + "debug": "^4.1.1", + "lodash": "^4.17.19", + "minimist": "1.2.5", + "restify": "8.5.1" + }, + "devDependencies": { + "@babel/core": "^7.10.5", + "@babel/preset-env": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", + "@types/jest": "^25.2.3", + "@types/lodash": "^4.14.159", + "@types/minimist": "^1.2.0", + "@types/node": "^10.12.18", + "@types/restify": "^8.4.2", + "babel-jest": "^26.1.0", + "jest": "^26.1.0", + "typescript": "^3.9.7", + "eslint": "7.0.0", + "@typescript-eslint/eslint-plugin": "2.34.0", + "@typescript-eslint/parser": "2.34.0", + "prettier": "2.0.5", + "eslint-plugin-prettier": "3.1.3", + "eslint-config-prettier": "6.11.0" + } +} diff --git a/runtime/node/skills/function.json b/runtime/node/skills/function.json new file mode 100644 index 0000000000..f2b2b79343 --- /dev/null +++ b/runtime/node/skills/function.json @@ -0,0 +1,21 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "post" + ], + "route": "skills/v3/conversations/{conversationId}/activities/{activityId}" + }, + { + "type": "http", + "direction": "out", + "name": "res" + } + ], + "scriptFile": "../lib/functions.js", + "entryPoint": "skillsTrigger" +} diff --git a/runtime/node/src/functions.ts b/runtime/node/src/functions.ts new file mode 100644 index 0000000000..4dac4a8e21 --- /dev/null +++ b/runtime/node/src/functions.ts @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { AzureFunction, Context, HttpRequest } from '@azure/functions'; +import { + Activity, + ConversationState, + MemoryStorage, + UserState, + SkillHandler, + TurnContext, + WebResponse, +} from 'botbuilder'; +import { AuthenticationConfiguration, SimpleCredentialProvider } from 'botframework-connector'; +import { ComposerBot } from './shared/composerBot'; +import { getBotAdapter, getSettings } from './shared/helpers'; +import { SkillConversationIdFactory } from './shared/skillConversationIdFactory'; + +// Create shared memory storage. +const memoryStorage = new MemoryStorage(); + +// Create shared user state and conversation state instances. +const userState = new UserState(memoryStorage); +const conversationState = new ConversationState(memoryStorage); + +// Create shared skill conversation id factory instance. +const skillConversationIdFactory = new SkillConversationIdFactory(); + +// Get botframework adapter. +const adapter = getBotAdapter(userState, conversationState); + +// Create composer bot instance with root dialog. +const bot = new ComposerBot(userState, conversationState, skillConversationIdFactory); + +export const messagesTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise { + context.log('Messages endpoint triggerd.'); + + // Delegate the processing of the HTTP POST to the adapter. + // The adapter will invoke the bot. + await adapter.processActivity(req, context.res as WebResponse, async function ( + turnContext: TurnContext + ): Promise { + // Route activity to bot. + await bot.onTurnActivity(turnContext); + }); +}; + +const settings = getSettings(); +const credentialProvider = new SimpleCredentialProvider(settings.MicrosoftAppId, settings.MicrosoftAppPassword); +const authConfig = new AuthenticationConfiguration([]); +const skillHandler = new SkillHandler(adapter, bot, skillConversationIdFactory, credentialProvider, authConfig); + +export const skillsTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise { + context.log('Skill replyToActivity endpoint triggered.'); + + const conversationId = context.bindingData.conversationId; + const activityId = context.bindingData.activityId; + + const authHeader = req.headers.authorization || req.headers.Authorization || ''; + const activity = JSON.parse(req.body) as Activity; + const result = await skillHandler.handleReplyToActivity(authHeader, conversationId, activityId, activity); + const res = context.res as WebResponse; + res.status(200); + res.send(result); + res.end(); + + context.done(); +}; diff --git a/runtime/node/src/shared/composerBot.ts b/runtime/node/src/shared/composerBot.ts new file mode 100644 index 0000000000..96a70ea5bd --- /dev/null +++ b/runtime/node/src/shared/composerBot.ts @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { ActivityHandler, ActivityTypes, ConversationState, SkillHttpClient, TurnContext, UserState } from 'botbuilder'; +import { DialogManager } from 'botbuilder-dialogs'; +import { + AdaptiveDialog, + AdaptiveDialogComponentRegistration, + LanguageGeneratorExtensions, + LanguagePolicy, + ResourceExtensions, + SkillExtensions, +} from 'botbuilder-dialogs-adaptive'; +import { ResourceExplorer } from 'botbuilder-dialogs-declarative'; +import { SimpleCredentialProvider, SkillValidation } from 'botframework-connector'; +import { BotSettings } from './settings'; +import { SkillConversationIdFactory } from './skillConversationIdFactory'; +import { getSettings, getProjectRoot, getRootDialog } from './helpers'; + +/** + * A composer bot to handle botframework activity requests. + */ +export class ComposerBot extends ActivityHandler { + private readonly userState: UserState; + private readonly conversationState: ConversationState; + private readonly skillConversationIdFactory: SkillConversationIdFactory; + private readonly projectRoot: string; + private readonly settings: BotSettings; + private readonly resourceExplorer: ResourceExplorer; + private dialogManager: DialogManager; + + public constructor( + userState: UserState, + conversationState: ConversationState, + skillConversationIdFactory: SkillConversationIdFactory + ) { + super(); + this.userState = userState; + this.conversationState = conversationState; + this.skillConversationIdFactory = skillConversationIdFactory; + this.projectRoot = getProjectRoot(); + this.settings = getSettings(this.projectRoot); + + // Create and configure resource explorer. + this.resourceExplorer = new ResourceExplorer(); + this.resourceExplorer.addFolders(this.projectRoot, ['runtime'], false); + this.resourceExplorer.addComponent(new AdaptiveDialogComponentRegistration(this.resourceExplorer)); + + this.loadRootDialog(); + this.configureLanguageGeneration(); + this.configureSkills(); + } + + public async onTurnActivity(turnContext: TurnContext): Promise { + const rootDialog = this.dialogManager.rootDialog as AdaptiveDialog; + const claimIdentity = turnContext.turnState.get(turnContext.adapter.BotIdentityKey); + if (claimIdentity && SkillValidation.isSkillClaim(claimIdentity.claims)) { + rootDialog.autoEndDialog = true; + } else { + rootDialog.autoEndDialog = false; + } + + const removeRecipientMention = (this.settings.feature && this.settings.feature.removeRecipientMention) || false; + if (removeRecipientMention && turnContext.activity.type == ActivityTypes.Message) { + TurnContext.removeRecipientMention(turnContext.activity); + } + + await this.dialogManager.onTurn(turnContext); + await this.conversationState.saveChanges(turnContext, false); + await this.userState.saveChanges(turnContext, false); + } + + private loadRootDialog() { + const rootDialogFile = getRootDialog(this.projectRoot); + const rootDialog = this.resourceExplorer.loadType(rootDialogFile) as AdaptiveDialog; + this.dialogManager = new DialogManager(rootDialog); + ResourceExtensions.useResourceExplorer(this.dialogManager, this.resourceExplorer); + this.dialogManager.initialTurnState.set('settings', this.settings); + this.dialogManager.conversationState = this.conversationState; + this.dialogManager.userState = this.userState; + } + + private configureLanguageGeneration() { + const defaultLocale = this.settings.defaultLocale || 'en-us'; + const languagePolicy = new LanguagePolicy(defaultLocale); + LanguageGeneratorExtensions.useLanguageGeneration(this.dialogManager); + LanguageGeneratorExtensions.useLanguagePolicy(this.dialogManager, languagePolicy); + } + + private configureSkills() { + const credentialProvider = new SimpleCredentialProvider( + this.settings.MicrosoftAppId, + this.settings.MicrosoftAppPassword + ); + const skillClient = new SkillHttpClient(credentialProvider, this.skillConversationIdFactory); + SkillExtensions.useSkillClient(this.dialogManager, skillClient); + SkillExtensions.useSkillConversationIdFactory(this.dialogManager, this.skillConversationIdFactory); + } +} diff --git a/runtime/node/src/shared/helpers.ts b/runtime/node/src/shared/helpers.ts new file mode 100644 index 0000000000..9e23b3144c --- /dev/null +++ b/runtime/node/src/shared/helpers.ts @@ -0,0 +1,207 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import fs from 'fs'; +import minimist from 'minimist'; +import path from 'path'; +import { Server } from 'restify'; +import merge from 'lodash/merge'; +import { + BotFrameworkAdapter, + BotFrameworkAdapterSettings, + ChannelServiceRoutes, + ConversationState, + InputHints, + SkillHandler, + TurnContext, + UserState, + WebRequest, + WebResponse, + Activity, + StatusCodeError, + StatusCodes, +} from 'botbuilder'; +import { AuthenticationConfiguration, SimpleCredentialProvider } from 'botframework-connector'; +import { ComposerBot } from './composerBot'; +import { BotSettings } from './settings'; +import { SkillConversationIdFactory } from './skillConversationIdFactory'; + +/** + * Get listening port for listening from environment variables or arguments. + */ +export const getServerPort = () => { + const argv = minimist(process.argv.slice(2)); + // prefer the argv port --port=XXXX over process.env because the parent Composer app uses that. + const port = argv.port || process.env.port || process.env.PORT || 3979; + return port; +}; + +/** + * Get path of bot project. + */ +export const getProjectRoot = (): string => { + // get the root folder according to environment + if (process.env.runtime_environment === 'production') { + return path.join(__dirname, '../../azurewebapp/ComposerDialogs'); + } else { + return path.join(__dirname, '../../../'); + } +}; + +/** + * Get bot settings from configuration file, generated luis configuration or arguments. + * @param projectRoot Root path of bot project. + */ +export const getSettings = (projectRoot = getProjectRoot()): BotSettings => { + // Find settings json file + let settings = {} as BotSettings; + // load appsettings.json + const appsettingsPath = path.join(projectRoot, 'settings/appsettings.json'); + if (fs.existsSync(appsettingsPath)) { + settings = JSON.parse(fs.readFileSync(appsettingsPath, 'utf8')); + } + + // load generated settings + const generatedPath = path.join(projectRoot, 'generated'); + if (fs.existsSync(generatedPath)) { + const generatedFiles = fs.readdirSync(generatedPath); + for (const file of generatedFiles) { + if (file.endsWith('.json')) { + const items = JSON.parse(fs.readFileSync(path.join(generatedPath, file), 'utf8')); + settings.luis = merge({}, settings.luis, items.luis); // merge luis settings + } + } + } + + // load settings from arguments + const argv = minimist(process.argv.slice(2)); + for (const key in argv) { + if (key.includes(':')) { + const segments: string[] = key.split(':'); + let base = settings; + segments.forEach((segment, index) => { + if (!Object.prototype.hasOwnProperty.call(base, segment)) { + base[segment] = {}; + } + + if (index === segments.length - 1) { + base[segment] = argv[key]; + } else { + base = base[segment]; + } + }); + } else { + settings[key] = argv[key]; + } + } + settings.MicrosoftAppId = settings.MicrosoftAppId || process.env.MicrosoftAppId; + settings.MicrosoftAppPassword = settings.MicrosoftAppPassword || process.env.MicrosoftAppPassword; + return settings; +}; + +/** + * Get root dialog of the bot project. + * @param folderPath Path of bot project. + */ +export const getRootDialog = (folderPath: string): string => { + // Find entry dialog file + const files = fs.readdirSync(folderPath); + const rootDialog = files.find((file) => file.endsWith('.dialog')) ?? 'main.dialog'; + return rootDialog; +}; + +/** + * Get botframework adapter with user state and conversation state. + * @param userState User state required by a botframework adapter. + * @param conversationState Conversation state required by a botframework adapter. + */ +export const getBotAdapter = (userState: UserState, conversationState: ConversationState): BotFrameworkAdapter => { + const settings = getSettings(); + const adapterSettings: Partial = { + appId: settings.MicrosoftAppId, + appPassword: settings.MicrosoftAppPassword, + }; + const adapter = new BotFrameworkAdapter(adapterSettings); + adapter.onTurnError = async (turnContext: TurnContext, error: Error) => { + try { + // Send a message to the user. + let onTurnErrorMessage = 'The bot encountered an error or bug.'; + await turnContext.sendActivity(onTurnErrorMessage, onTurnErrorMessage, InputHints.IgnoringInput); + + onTurnErrorMessage = 'To continue to run this bot, please fix the bot source code.'; + await turnContext.sendActivity(onTurnErrorMessage, onTurnErrorMessage, InputHints.ExpectingInput); + + // Send a trace activity, which will be displayed in Bot Framework Emulator. + await turnContext.sendTraceActivity( + 'OnTurnError Trace', + `${error}`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + } catch (err) { + console.error(`\n [onTurnError] Exception caught in sendErrorMessage: ${err}`); + } + await conversationState.clear(turnContext); + await conversationState.saveChanges(turnContext); + }; + return adapter; +}; + +/** + * Configure a server to work with botframework message requests. + * @param server Web server to be configured. + * @param adapter Botframework adapter to handle message requests. + * @param bot Composer bot to process message requests. + */ +export const configureMessageEndpoint = (server: Server, adapter: BotFrameworkAdapter, bot: ComposerBot) => { + server.post('/api/messages', (req: WebRequest, res: WebResponse): void => { + adapter.processActivity( + req, + res, + async (context: TurnContext): Promise => { + // Route activity to bot. + await bot.onTurnActivity(context); + } + ); + }); +}; + +/** + * Configure a server to work with botframework skill requests. + * @param server Web server to be configured. + * @param adapter Botframework adapter to handle skill requests. + * @param bot Composer bot to process skill requests. + */ +export const configureSkillEndpoint = ( + server: Server, + adapter: BotFrameworkAdapter, + bot: ComposerBot, + skillConversationIdFactory: SkillConversationIdFactory +) => { + const settings = getSettings(); + const credentialProvider = new SimpleCredentialProvider(settings.MicrosoftAppId, settings.MicrosoftAppPassword); + const authConfig = new AuthenticationConfiguration([]); + const handler = new SkillHandler(adapter, bot, skillConversationIdFactory, credentialProvider, authConfig); + const skillEndpoint = new ChannelServiceRoutes(handler); + skillEndpoint.register(server, '/api/skills'); +}; + +/** + * Configure a server to serve manifest files. + * @param server Web server to be configured. + */ +export const configureManifestsEndpoint = (server: Server) => { + const projectRoot = getProjectRoot(); + const manifestsPath = path.join(projectRoot, 'manifests'); + if (fs.existsSync(manifestsPath)) { + const manifestFiles = fs.readdirSync(manifestsPath); + for (const file of manifestFiles) { + if (file.endsWith('.json')) { + server.get(`/${file}`, (_req, res): void => { + const manifest = JSON.parse(fs.readFileSync(path.join(manifestsPath, file), 'utf8')); + res.send(manifest); + }); + } + } + } +}; diff --git a/runtime/node/src/shared/settings.ts b/runtime/node/src/shared/settings.ts new file mode 100644 index 0000000000..659971c13a --- /dev/null +++ b/runtime/node/src/shared/settings.ts @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export interface BotSettings { + feature: BotFeatureSettings; + blobStorage: BlobStorageConfiguration; + MicrosoftAppId: string; + MicrosoftAppPassword: string; + cosmosDb: CosmosDbConfiguration; + applicationInsights: ApplicationInsightsConfiguration; + luis: LuisConfiguration; + telemetry: TelemetryConfiguration; + [key: string]: any; +} + +export interface BotFeatureSettings { + useShowTypingMiddleware: boolean; + useInspectionMiddleware: boolean; + removeRecipientMention: boolean; +} + +export interface BlobStorageConfiguration { + connectionString: string; + container: string; +} + +export interface CosmosDbConfiguration { + authKey: string; + collectionId: string; + cosmosDBEndpoint: string; + databaseId: string; +} + +export interface ApplicationInsightsConfiguration { + InstrumentationKey: string; +} + +export interface LuisConfiguration { + name: string; + authoringKey: string; + endpointKey: string; + endpoint: string; + authoringEndpoint: string; + authoringRegion: string; + defaultLanguage: string; + environment: string; +} + +export interface TelemetryConfiguration { + logPersonalInformation: boolean; + logActivities: boolean; +} diff --git a/runtime/node/src/shared/skillConversationIdFactory.ts b/runtime/node/src/shared/skillConversationIdFactory.ts new file mode 100644 index 0000000000..931eff811a --- /dev/null +++ b/runtime/node/src/shared/skillConversationIdFactory.ts @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { SkillConversationIdFactoryBase, SkillConversationIdFactoryOptions, TurnContext } from 'botbuilder'; + +/** + * A SkillConversationIdFactory that uses an in memory dictionary + * to store and retrieve ConversationReference instances. + */ +export class SkillConversationIdFactory extends SkillConversationIdFactoryBase { + private _refs: { [key: string]: any } = {}; + + /** + * Creates a conversation ID for a skill conversation based on the caller's conversation reference. + * @param options Skill conversation id options. + */ + public async createSkillConversationIdWithOptions(options: SkillConversationIdFactoryOptions) { + if (!options) { + throw new Error('Options cannot be null.'); + } + + // Create the storage key based on the SkillConversationIdFactoryOptions. + const conversationReference = TurnContext.getConversationReference(options.activity); + const skillConversationId = `${options.fromBotId}-${options.botFrameworkSkill.appId}-${conversationReference.conversation.id}-${conversationReference.channelId}-skillconvo`; + + // Create the SkillConversationReference instance. + const skillConversationReference = { + conversationReference, + oAuthScope: options.fromBotOAuthScope, + }; + + // Store the SkillConversationReference with skillConversationId as key. + this._refs[skillConversationId] = skillConversationReference; + + // Return the generated skillConversationId (that will be also used as the conversation ID to call the skill). + return skillConversationId; + } + + /** + * Gets the SkillConversationReference created with createSkillConversationId() or createSkillConversationIdWithOptions(). + * @param skillConversationId Conversation ID. + */ + public async getSkillConversationReference(skillConversationId: string) { + if (!skillConversationId) { + throw new Error('SkillConversationId cannot be null.'); + } + + return this._refs[skillConversationId]; + } + + /** + * Deletes a ConversationReference. + * @param skillConversationId Conversation ID. + */ + public async deleteConversationReference(skillConversationId: string) { + if (!skillConversationId) { + throw new Error('SkillConversationId cannot be null.'); + } + + this._refs[skillConversationId] = undefined; + } +} diff --git a/runtime/node/src/webapp.ts b/runtime/node/src/webapp.ts new file mode 100644 index 0000000000..2162700831 --- /dev/null +++ b/runtime/node/src/webapp.ts @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as restify from 'restify'; +import { ConversationState, MemoryStorage, UserState } from 'botbuilder'; +import { ComposerBot } from './shared/composerBot'; +import { + getBotAdapter, + configureSkillEndpoint, + configureMessageEndpoint, + getServerPort, + configureManifestsEndpoint, +} from './shared/helpers'; +import { SkillConversationIdFactory } from './shared/skillConversationIdFactory'; +import debug from 'debug'; + +const logger = debug('composer:runtime:nodejs'); + +// Create shared memory storage. +const memoryStorage = new MemoryStorage(); + +// Create shared user state and conversation state instances. +const userState = new UserState(memoryStorage); +const conversationState = new ConversationState(memoryStorage); + +// Create shared skill conversation id factory instance. +const skillConversationIdFactory = new SkillConversationIdFactory(); + +// Create HTTP server. +const server = restify.createServer({ maxParamLength: 1000 }); + +// Get botframework adapter. +const adapter = getBotAdapter(userState, conversationState); + +// Create composer bot instance with root dialog. +const bot = new ComposerBot(userState, conversationState, skillConversationIdFactory); + +// Configure message endpoint. +configureMessageEndpoint(server, adapter, bot); + +// Configure skill endpoint. +configureSkillEndpoint(server, adapter, bot, skillConversationIdFactory); + +// Configure manifests endpoint. +configureManifestsEndpoint(server); + +// Get port and listen. +const port = getServerPort(); +server.listen(port, (): void => { + logger(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator`); + logger(`\nTo talk to your bot, open http://localhost:${port}/api/messages in the Emulator.`); +}); diff --git a/runtime/node/tsconfig.json b/runtime/node/tsconfig.json new file mode 100644 index 0000000000..40ad490d5b --- /dev/null +++ b/runtime/node/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "declaration": true, + "esModuleInterop": true, + "sourceMap": true, + "outDir": "./lib", + "rootDir": "./src", + "types": ["node"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/runtime/node/web.config b/runtime/node/web.config new file mode 100644 index 0000000000..dcb97dd678 --- /dev/null +++ b/runtime/node/web.config @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +