From 85edd76739b86ad4303f8c19b9b9c73313ad0eae Mon Sep 17 00:00:00 2001 From: Ben Brown Date: Fri, 3 Jul 2020 09:22:04 -0500 Subject: [PATCH] Remove language specific features from core and into runtime plugin (#3453) * Remove language specific features from core and into runtime plugin * cleanup a bit of the azurepublish plugin for readability * move some code, add some comments * refactor bot project deploy and split into several sub-classes. move this from inside composer into the plugin * remove bot-deploy package combine azurePublish and azureFunctionsPublish refine buildDeploy api method to allow for knowledge of what target is being built for * remove azureFunctionsPublish (replaced by azureFunctions) * fix to node runtime * allow start bot button to be async * clean up dependencies, paths * remove rimraf yarn.lock in package.json and catch error during setBot * merge settings and write once inside the runtime plugin * make sure to use exec instead of execSync * make sure everything happens in the right order don't use console.log * identify runtime by name field * update luis package in azurePublish plugin and fix getRuntimeByProject * remove lib folder in azurePublish * test: increase 'adaptive-flow' test coverage to 77% (#3530) * + UT: adaptive-flow-renderer/widgets * + UT: adaptive-flow-editor/utils * remove unref hook: useWindowDimension * + UT: KeyboardZone * + UT: cursorTracker * + UT: adaptive-flow-editor/constants * +UT: AdaptiveFlowEditor * + UT: adaptive-flow-editor/contexts * + UT: useEditorEventApi * fix CI error * + UT: NodeWrapper * + UT: EdgeMenu * KeyboardZone behavioror test * change the test file structure of cursorTracker * update a test case (#3531) Co-authored-by: Chris Whitten * fix lgWorker test failure (#3529) Co-authored-by: Chris Whitten * chore: adds webpack bundle analyzer (#3542) * issues#3309 * fixes lints * Default to bot settings if no route cache * fix: #3485 * fix: #3486 Debug/Fix HMR support * webpack bundle analyzer Co-authored-by: Soroush Co-authored-by: Chris Whitten Co-authored-by: Andy Brown * refactor: split some actions off setSettings (#3525) * split some actions off setSettings * add more actions - eject still not working * fix arguments in eject * split some actions off setSettings * add more actions - eject still not working * fix arguments in eject * Update setting.ts * fix some tests * Update index.ts * move logo-clicking to commands.ts * Update commands.ts * fix: Dialog validate throw error when delete an action (#3537) * fix: Dialog validate throw error when delete an action * use optional chaining and more explicit length check * fix lint Co-authored-by: Chris Whitten Co-authored-by: Andy Brown * use const instead of raw http status values * rename js runtime to node-azurewebapp Co-authored-by: Wenyi Luo Co-authored-by: zeye <2295905420@qq.com> Co-authored-by: liweitian Co-authored-by: Chris Whitten Co-authored-by: Zhixiang Zhan Co-authored-by: Soroush Co-authored-by: Soroush Co-authored-by: Andy Brown Co-authored-by: Ben Yackley <61990921+beyackle@users.noreply.github.com> Co-authored-by: leileizhang --- .../integration/NotificationPage.spec.ts | 3 - Composer/cypress/support/commands.ts | 3 + Composer/package.json | 6 +- .../LocationBrowser/FileSelector.test.tsx | 10 +- .../packages/client/config/webpack.config.js | 6 + Composer/packages/client/package.json | 3 +- .../TestController/TestController.tsx | 24 +- Composer/packages/client/src/constants.ts | 5 + .../client/src/pages/publish/index.tsx | 12 +- .../pages/setting/dialog-settings/index.tsx | 3 +- .../pages/setting/runtime-settings/index.tsx | 11 +- .../packages/client/src/store/action/eject.ts | 19 +- .../client/src/store/action/publisher.ts | 31 +- .../client/src/store/action/setting.ts | 39 + Composer/packages/client/src/store/index.tsx | 1 + .../src/store/persistence/FilePersistence.ts | 2 + .../client/src/store/reducer/index.ts | 65 +- Composer/packages/client/src/store/types.ts | 1 + .../AdaptiveFlowEditor.test.tsx | 27 + .../components/KeyboardZone.test.tsx | 39 + .../constants/ElementAttributes.test.tsx | 18 + .../constants/KeyboardCommandTypes.test.ts | 66 + .../constants/MenuTypes.test.ts | 12 + .../constants/ScreenReaderMessage.test.ts | 24 + .../constants/editorConfig.test.ts | 17 + .../contexts/NodeRendererContext.test.tsx | 50 + .../contexts/SelectionContext.test.tsx | 45 + .../hooks/useEditorEventApi.test.ts | 50 + .../renderers/EdgeMenu.test.tsx | 45 + .../renderers/ElementWrapper.test.tsx | 21 + .../renderers/NodeWrapper.test.tsx | 30 + .../stubs/ShellApiStub.ts | 45 + .../utils/NodeIndexGetter.test.ts | 25 + .../utils/calculateRangeSelection.test.ts | 11 + .../utils/cursorTracker/index.test.ts | 46 + .../utils/cursorTracker/type.test.ts | 18 + .../mapKeyboardCommandToEditorEvent.test.ts | 34 + .../utils/mergePluginConfig.test.ts | 34 + .../widgets/ActionCard.test.tsx | 31 + .../widgets/DialogRef.test.tsx | 36 + .../widgets/ForeachWidget.test.tsx | 23 + .../widgets/IfConditionWidget.test.tsx | 23 + .../widgets/PromptWidget.test.tsx | 25 + .../widgets/SwitchConditionWidget.test.tsx | 23 + .../AdaptiveFlowEditor.tsx | 2 +- .../components/KeyboardZone.tsx | 2 +- .../contexts/NodeRendererContext.ts | 7 +- .../contexts/SelectionContext.ts | 5 +- .../hooks/useWindowDimensions.ts | 25 - .../renderers/NodeWrapper.tsx | 1 + ....ts => mapKeyboardCommandToEditorEvent.ts} | 0 .../extensions/extension/src/index.ts | 3 + .../src/composerPluginRegistration.ts | 25 +- .../plugin-loader/src/pluginLoader.ts | 28 +- .../extensions/plugin-loader/src/types.ts | 19 +- Composer/packages/lib/bot-deploy/.gitignore | 2 - Composer/packages/lib/bot-deploy/README.md | 50 - .../lib/bot-deploy/lib/botProjectDeploy.d.ts | 99 + .../bot-deploy/lib/botProjectDeploy.d.ts.map | 1 + .../lib/bot-deploy/lib/botProjectDeploy.js | 1465 ++++++++++ .../bot-deploy/lib/botProjectDeploy.js.map | 1 + .../lib/botProjectDeployConfig.d.ts | 18 + .../lib/botProjectDeployConfig.d.ts.map | 1 + .../bot-deploy/lib/botProjectDeployConfig.js | 5 + .../lib/botProjectDeployConfig.js.map | 1 + .../bot-deploy/lib/botProjectLoggerType.d.ts | 12 + .../lib/botProjectLoggerType.d.ts.map | 1 + .../bot-deploy/lib/botProjectLoggerType.js | 20 + .../lib/botProjectLoggerType.js.map | 1 + .../{src/index.ts => lib/index.d.ts} | 5 +- .../lib/bot-deploy/lib/index.d.ts.map | 1 + Composer/packages/lib/bot-deploy/lib/index.js | 29 + .../packages/lib/bot-deploy/lib/index.js.map | 1 + Composer/packages/lib/bot-deploy/package.json | 34 - .../packages/lib/bot-deploy/tsconfig.json | 12 - .../validations/expressionValidation.test.ts | 3 + .../validations/expressionValidation/index.ts | 21 +- Composer/packages/lib/package.json | 3 +- .../packages/lib/shared/src/types/indexers.ts | 2 +- .../__tests__/controllers/project.test.ts | 4 +- .../server/__tests__/services/project.test.ts | 5 +- .../server/src/controllers/publisher.ts | 5 +- .../models/settings/defaultSettingManager.ts | 2 - .../packages/server/src/services/project.ts | 11 +- .../language-generation/src/lgParser.ts | 42 +- .../plugins/azureFunctionsPublish/.gitignore | 6 - .../azureFunctionsPublish/package.json | 25 - .../azureFunctionsPublish/src/index.ts | 363 --- .../azureFunctionsPublish/src/schema.ts | 138 - .../plugins/azureFunctionsPublish/yarn.lock | 2438 ----------------- Composer/plugins/azurePublish/.gitignore | 3 +- Composer/plugins/azurePublish/package.json | 18 +- .../src/botProjectDeployConfig.ts | 0 .../azurePublish}/src/botProjectLoggerType.ts | 0 .../src/botProjectRuntimeType.ts | 0 Composer/plugins/azurePublish/src/deploy.ts | 184 ++ Composer/plugins/azurePublish/src/index.ts | 685 +++-- Composer/plugins/azurePublish/src/luis.ts | 247 ++ .../plugins/azurePublish/src/mergeDeep.ts | 39 + .../azurePublish/src/provision.ts} | 494 +--- Composer/plugins/azurePublish/yarn.lock | 211 +- Composer/plugins/localPublish/.eslintrc.js | 16 +- Composer/plugins/localPublish/.gitignore | 3 +- Composer/plugins/localPublish/package.json | 15 +- Composer/plugins/localPublish/src/index.ts | 254 +- Composer/plugins/localPublish/yarn.lock | 1130 ++++---- Composer/plugins/runtimes/.eslintrc.js | 10 + Composer/plugins/runtimes/.gitignore | 4 + Composer/plugins/runtimes/package.json | 22 + .../{localPublish => runtimes}/src/copyDir.ts | 0 Composer/plugins/runtimes/src/index.ts | 186 ++ .../src/interface.ts | 0 .../tsconfig.json | 4 +- Composer/plugins/runtimes/yarn.lock | 540 ++++ Composer/yarn.lock | 148 +- runtime/node/azurewebapp/src/index.ts | 6 +- 116 files changed, 5363 insertions(+), 4862 deletions(-) create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/AdaptiveFlowEditor.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/components/KeyboardZone.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ElementAttributes.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/KeyboardCommandTypes.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/MenuTypes.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ScreenReaderMessage.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/editorConfig.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/NodeRendererContext.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/SelectionContext.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/hooks/useEditorEventApi.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/EdgeMenu.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/ElementWrapper.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/NodeWrapper.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/stubs/ShellApiStub.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/NodeIndexGetter.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/calculateRangeSelection.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/index.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/type.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mergePluginConfig.test.ts create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ActionCard.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/DialogRef.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ForeachWidget.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/IfConditionWidget.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/PromptWidget.test.tsx create mode 100644 Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/SwitchConditionWidget.test.tsx delete mode 100644 Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/hooks/useWindowDimensions.ts rename Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/utils/{mapKeyboardCommandToEditorEvent.ts.ts => mapKeyboardCommandToEditorEvent.ts} (100%) delete mode 100644 Composer/packages/lib/bot-deploy/.gitignore delete mode 100644 Composer/packages/lib/bot-deploy/README.md create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts.map create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js.map create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts.map create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js.map create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts.map create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js create mode 100644 Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js.map rename Composer/packages/lib/bot-deploy/{src/index.ts => lib/index.d.ts} (50%) create mode 100644 Composer/packages/lib/bot-deploy/lib/index.d.ts.map create mode 100644 Composer/packages/lib/bot-deploy/lib/index.js create mode 100644 Composer/packages/lib/bot-deploy/lib/index.js.map delete mode 100644 Composer/packages/lib/bot-deploy/package.json delete mode 100644 Composer/packages/lib/bot-deploy/tsconfig.json delete mode 100644 Composer/plugins/azureFunctionsPublish/.gitignore delete mode 100644 Composer/plugins/azureFunctionsPublish/package.json delete mode 100644 Composer/plugins/azureFunctionsPublish/src/index.ts delete mode 100644 Composer/plugins/azureFunctionsPublish/src/schema.ts delete mode 100644 Composer/plugins/azureFunctionsPublish/yarn.lock rename Composer/{packages/lib/bot-deploy => plugins/azurePublish}/src/botProjectDeployConfig.ts (100%) rename Composer/{packages/lib/bot-deploy => plugins/azurePublish}/src/botProjectLoggerType.ts (100%) rename Composer/{packages/lib/bot-deploy => plugins/azurePublish}/src/botProjectRuntimeType.ts (100%) create mode 100644 Composer/plugins/azurePublish/src/deploy.ts create mode 100644 Composer/plugins/azurePublish/src/luis.ts create mode 100644 Composer/plugins/azurePublish/src/mergeDeep.ts rename Composer/{packages/lib/bot-deploy/src/botProjectDeploy.ts => plugins/azurePublish/src/provision.ts} (59%) create mode 100644 Composer/plugins/runtimes/.eslintrc.js create mode 100644 Composer/plugins/runtimes/.gitignore create mode 100644 Composer/plugins/runtimes/package.json rename Composer/plugins/{localPublish => runtimes}/src/copyDir.ts (100%) create mode 100644 Composer/plugins/runtimes/src/index.ts rename Composer/plugins/{localPublish => runtimes}/src/interface.ts (100%) rename Composer/plugins/{azureFunctionsPublish => runtimes}/tsconfig.json (99%) create mode 100644 Composer/plugins/runtimes/yarn.lock diff --git a/Composer/cypress/integration/NotificationPage.spec.ts b/Composer/cypress/integration/NotificationPage.spec.ts index de9a31bb17..8912de9409 100644 --- a/Composer/cypress/integration/NotificationPage.spec.ts +++ b/Composer/cypress/integration/NotificationPage.spec.ts @@ -44,9 +44,6 @@ context('Notification Page', () => { it('can show dialog expression error ', () => { cy.visitPage('Design'); - // click the logo to clear any stray tooltips from page navigation - cy.findByAltText('Composer Logo').click(); - cy.findByTestId('ProjectTree').within(() => { cy.findByText('WelcomeUser').click(); }); diff --git a/Composer/cypress/support/commands.ts b/Composer/cypress/support/commands.ts index 4b9d179903..4471ed8bd3 100644 --- a/Composer/cypress/support/commands.ts +++ b/Composer/cypress/support/commands.ts @@ -26,6 +26,9 @@ Cypress.Commands.add('withinEditor', (editorName, cb) => { Cypress.Commands.add('visitPage', (page) => { cy.findByTestId(`LeftNav-CommandBarButton${page}`).click(); cy.findByTestId('ActiveLeftNavItem').should('contain', page); + + // click the logo to clear any stray tooltips from page navigation + cy.findByAltText('Composer Logo').click({ force: true }); }); Cypress.Commands.add('enterTextAndSubmit', (textElement: string, text: string, submitBtn?: string) => { diff --git a/Composer/package.json b/Composer/package.json index 605f496cf0..fc73da6ddb 100644 --- a/Composer/package.json +++ b/Composer/package.json @@ -40,11 +40,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": "yarn build:plugins:localpublish && yarn build:plugins:samples && yarn build:plugins:azurePublish && yarn build:plugins:azureFunctionsPublish", + "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:azureFunctionsPublish": "cd plugins/azureFunctionsPublish && 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\"", @@ -120,4 +120,4 @@ "dependencies": { "cross-env": "^6.0.3" } -} \ No newline at end of file +} diff --git a/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx b/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx index 4454a51810..2cd9b23ebc 100644 --- a/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx +++ b/Composer/packages/client/__tests__/components/CreationFlow/LocationBrowser/FileSelector.test.tsx @@ -82,14 +82,18 @@ describe('', () => { expect(await component.findByText('You do not have permission to save bots here')).toBeInTheDocument(); }); - it('should update folder name', async () => { + it('should create a new folder', async () => { const component = renderComponent(); const createFolderBtn = await component.findByText('create new folder'); fireEvent.click(createFolderBtn); const textField = await component.findByTestId('newFolderTextField'); fireEvent.change(textField, { target: { value: 'newFolder' } }); fireEvent.keyDown(textField, { key: 'Enter' }); - //locally this should be 'C:\\test-folder\\Desktop', but it should be 'C:/test-folder/Desktop' online - expect(createFolder).toBeCalledWith('C:/test-folder/Desktop', 'newFolder'); + //locally this should be 'C:\\test-folder\\Desktop', but online it should be 'C:/test-folder/Desktop' + expect( + createFolder.mock.calls[0][0] === 'C:/test-folder/Desktop' || + createFolder.mock.calls[0][0] === 'C:\\test-folder\\Desktop' + ).toBeTruthy(); + expect(createFolder.mock.calls[0][1]).toBe('newFolder'); }); }); diff --git a/Composer/packages/client/config/webpack.config.js b/Composer/packages/client/config/webpack.config.js index cbf2051ab8..4014117ae6 100644 --- a/Composer/packages/client/config/webpack.config.js +++ b/Composer/packages/client/config/webpack.config.js @@ -17,6 +17,7 @@ const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeM const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const getClientEnvironment = require('./env'); const paths = require('./paths'); @@ -492,6 +493,11 @@ module.exports = function (webpackEnv) { new RegExp('/[^/]+\\.[^/]+$'), ], }), + // Generate static visualization of the bundle + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + }), ].filter(Boolean), // Some libraries import Node modules but don't use them in the browser. // Tell Webpack to provide empty mocks for them so importing them works. diff --git a/Composer/packages/client/package.json b/Composer/packages/client/package.json index 9443d501df..0899312c37 100644 --- a/Composer/packages/client/package.json +++ b/Composer/packages/client/package.json @@ -53,7 +53,8 @@ "react-dom": "16.13.0", "react-frame-component": "^4.0.2", "react-timeago": "^4.4.0", - "styled-components": "^4.1.3" + "styled-components": "^4.1.3", + "webpack-bundle-analyzer": "^3.8.0" }, "browserslist": [ ">0.2%", diff --git a/Composer/packages/client/src/components/TestController/TestController.tsx b/Composer/packages/client/src/components/TestController/TestController.tsx index 3b9b8beb21..05d3cb9327 100644 --- a/Composer/packages/client/src/components/TestController/TestController.tsx +++ b/Composer/packages/client/src/components/TestController/TestController.tsx @@ -30,7 +30,15 @@ export const TestController: React.FC = () => { const botActionRef = useRef(null); const notifications = useNotifications(); const { botEndpoints, botName, botStatus, dialogs, luFiles, settings, projectId, botLoadErrorMsg } = state; - const { publishToTarget, onboardingAddCoachMarkRef, publishLuis, getPublishStatus, setBotStatus } = actions; + const { + publishToTarget, + onboardingAddCoachMarkRef, + publishLuis, + getPublishStatus, + setBotStatus, + startPollingRuntime, + stopPollingRuntime, + } = actions; const connected = botStatus === BotStatus.connected; const publishing = botStatus === BotStatus.publishing; const reloading = botStatus === BotStatus.reloading; @@ -48,12 +56,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() { diff --git a/Composer/packages/client/src/constants.ts b/Composer/packages/client/src/constants.ts index 28d47e3613..840ab9ca4a 100644 --- a/Composer/packages/client/src/constants.ts +++ b/Composer/packages/client/src/constants.ts @@ -102,6 +102,11 @@ export enum ActionTypes { REMOVE_SKILL_MANIFEST = 'REMOVE_SKILL_MANIFEST', DISPLAY_SKILL_MANIFEST_MODAL = 'DISPLAY_SKILL_MANIFEST_MODAL', DISMISS_SKILL_MANIFEST_MODAL = 'DISMISS_SKILL_MANIFEST_MODAL', + RUNTIME_POLLING_UPDATE = 'RUNTIME_POLLING_UPDATE', + SET_PUBLISH_TARGETS = 'SET_PUBLISH_TARGETS', + SET_RUNTIME_SETTINGS = 'SET_RUNTIME_SETTINGS', + SET_CUSTOM_RUNTIME_TOGGLE = 'SET_CUSTOM_RUNTIME_TOGGLE', + SET_RUNTIME_FIELD = 'SET_RUNTIME_FIELD', } export const Tips = { diff --git a/Composer/packages/client/src/pages/publish/index.tsx b/Composer/packages/client/src/pages/publish/index.tsx index 41bf64d9f8..b6276d2683 100644 --- a/Composer/packages/client/src/pages/publish/index.tsx +++ b/Composer/packages/client/src/pages/publish/index.tsx @@ -221,14 +221,14 @@ const Publish: React.FC = (props) => { const savePublishTarget = useCallback( async (name: string, type: string, configuration: string) => { - const target = (settings.publishTargets || []).concat([ + const targets = (settings.publishTargets || []).concat([ { name, type, configuration, }, ]); - await actions.setSettings(projectId, { ...settings, publishTargets: target }); + await actions.setPublishTargets(targets); onSelectTarget(name); }, [settings.publishTargets, projectId, botName] @@ -248,7 +248,7 @@ const Publish: React.FC = (props) => { configuration, }; - await actions.setSettings(projectId, { ...settings, publishTargets: targets }); + await actions.setPublishTargets(targets); onSelectTarget(name); }, @@ -314,7 +314,7 @@ const Publish: React.FC = (props) => { } }); - await actions.setSettings(projectId, { ...settings, publishTargets: updatedPublishTargets }); + await actions.setPublishTargets(updatedPublishTargets); } }, [projectId, selectedTarget, settings.publishTargets] @@ -339,8 +339,8 @@ const Publish: React.FC = (props) => { if (result) { if (settings.publishTargets && settings.publishTargets.length > index) { - const target = settings.publishTargets.slice(0, index).concat(settings.publishTargets.slice(index + 1)); - await actions.setSettings(projectId, { ...settings, publishTargets: target }); + const targets = settings.publishTargets.slice(0, index).concat(settings.publishTargets.slice(index + 1)); + await actions.setPublishTargets(targets); // redirect to all profiles setSelectedTarget(undefined); onSelectTarget('all'); diff --git a/Composer/packages/client/src/pages/setting/dialog-settings/index.tsx b/Composer/packages/client/src/pages/setting/dialog-settings/index.tsx index 36fdf7901e..6ac67a6d1a 100644 --- a/Composer/packages/client/src/pages/setting/dialog-settings/index.tsx +++ b/Composer/packages/client/src/pages/setting/dialog-settings/index.tsx @@ -30,8 +30,7 @@ export const DialogSettings: React.FC = () => { const saveChangeResult = (result) => { try { - const mergedResult = result; - actions.setSettings(projectId, mergedResult); + actions.setSettings(projectId, result); } catch (err) { // eslint-disable-next-line no-console console.error(err.message); diff --git a/Composer/packages/client/src/pages/setting/runtime-settings/index.tsx b/Composer/packages/client/src/pages/setting/runtime-settings/index.tsx index ca3c554e77..a6f7627fd6 100644 --- a/Composer/packages/client/src/pages/setting/runtime-settings/index.tsx +++ b/Composer/packages/client/src/pages/setting/runtime-settings/index.tsx @@ -18,12 +18,13 @@ import { breathingSpace, runtimeSettingsStyle, runtimeControls, runtimeToggle, c export const RuntimeSettings: React.FC = () => { const { state, actions } = useContext(StoreContext); + const { setCustomRuntime, setRuntimeField } = actions; const { botName, settings, projectId } = state; const [formDataErrors, setFormDataErrors] = useState({ command: '', path: '' }); const [ejectModalVisible, setEjectModalVisible] = useState(false); - const changeEnabled = (_, on) => { - actions.setSettings(projectId, { ...settings, runtime: { ...settings.runtime, customRuntime: on } }); + const handleChangeToggle = (_, isOn = false) => { + setCustomRuntime(projectId, isOn); }; const updateSetting = (field) => (e, newValue) => { @@ -34,7 +35,7 @@ export const RuntimeSettings: React.FC = () => { error = 'This is a required field.'; } - actions.setSettings(projectId, { ...settings, runtime: { ...settings.runtime, [field]: newValue } }); + setRuntimeField(projectId, field, newValue); if (valid) { setFormDataErrors({ ...formDataErrors, [field]: '' }); @@ -53,9 +54,9 @@ export const RuntimeSettings: React.FC = () => {
); diff --git a/Composer/packages/client/src/store/action/eject.ts b/Composer/packages/client/src/store/action/eject.ts index 0053272829..2249c81068 100644 --- a/Composer/packages/client/src/store/action/eject.ts +++ b/Composer/packages/client/src/store/action/eject.ts @@ -5,7 +5,7 @@ import { ActionCreator } from '../types'; import { ActionTypes } from '../../constants'; import httpClient from './../../utils/httpUtil'; -import { setSettings } from './setting'; +import { setRuntimeSettings } from './setting'; export const getRuntimeTemplates: ActionCreator = async ({ dispatch }) => { try { @@ -23,26 +23,15 @@ export const getRuntimeTemplates: ActionCreator = async ({ dispatch }) => { }; export const ejectRuntime: ActionCreator = async (store, projectId, name) => { - const { dispatch, getState } = store; + const { dispatch } = store; try { const response = await httpClient.post(`/runtime/eject/${projectId}/${name}`); dispatch({ type: ActionTypes.EJECT_SUCCESS, payload: response.data, }); - if (response.data.settings && response.data.settings.path) { - const { settings: oldsettings } = getState(); - setSettings(store, projectId, { - ...oldsettings, - runtime: { - ...oldsettings.runtime, - customRuntime: true, - key: response.data.settings.key, - name: response.data.settings.name, - path: response.data.settings.path, - command: response.data.settings.startCommand, - }, - }); + if (response.data.settings?.path) { + setRuntimeSettings(store, projectId, response.data.settings.path, response.data.settings.startCommand); } } catch (err) { dispatch({ diff --git a/Composer/packages/client/src/store/action/publisher.ts b/Composer/packages/client/src/store/action/publisher.ts index c21ac4d530..3b5d48a620 100644 --- a/Composer/packages/client/src/store/action/publisher.ts +++ b/Composer/packages/client/src/store/action/publisher.ts @@ -5,9 +5,38 @@ import formatMessage from 'format-message'; import { ActionCreator } from '../types'; import filePersistence from '../persistence/FilePersistence'; -import { ActionTypes } from '../../constants'; +import { ActionTypes, DefaultPublishConfig } from '../../constants'; import httpClient from './../../utils/httpUtil'; + +// this is the interval at which the runtime manager will be polled +const POLLING_INTERVAL = 2500; + +export const stopPollingRuntime: ActionCreator = ({ getState, dispatch }) => { + const botStatusInterval = getState().botStatusInterval; + if (botStatusInterval) { + clearInterval(botStatusInterval); + } + dispatch({ + type: ActionTypes.RUNTIME_POLLING_UPDATE, + payload: null, + }); +}; + +export const startPollingRuntime: ActionCreator = (store) => { + const botStatusInterval = store.getState().botStatusInterval; + const projectId = store.getState().projectId; + if (!botStatusInterval) { + const cancelInterval = setInterval(function () { + getPublishStatus(store, projectId, DefaultPublishConfig); + }, POLLING_INTERVAL); + store.dispatch({ + type: ActionTypes.RUNTIME_POLLING_UPDATE, + payload: cancelInterval, + }); + } +}; + export const getPublishTargetTypes: ActionCreator = async ({ dispatch }) => { try { const response = await httpClient.get(`/publish/types`); diff --git a/Composer/packages/client/src/store/action/setting.ts b/Composer/packages/client/src/store/action/setting.ts index a756073a6e..a25dd321e4 100644 --- a/Composer/packages/client/src/store/action/setting.ts +++ b/Composer/packages/client/src/store/action/setting.ts @@ -13,3 +13,42 @@ export const setSettings: ActionCreator = async ({ dispatch }, projectId: string }, }); }; + +export const setPublishTarget: ActionCreator = async ({ dispatch }, _, publishTarget) => { + dispatch({ + type: ActionTypes.SET_PUBLISH_TARGETS, + payload: { + publishTarget, + }, + }); +}; + +export const setRuntimeSettings: ActionCreator = async ({ dispatch }, projectId: string, path, command) => { + dispatch({ + type: ActionTypes.SET_RUNTIME_SETTINGS, + payload: { + projectId, + path, + command, + }, + }); +}; + +export const setCustomRuntime: ActionCreator = async ({ dispatch }, _, isOn) => { + dispatch({ + type: ActionTypes.SET_CUSTOM_RUNTIME_TOGGLE, + payload: { + isOn, + }, + }); +}; + +export const setRuntimeField: ActionCreator = async ({ dispatch }, _, field, newValue) => { + dispatch({ + type: ActionTypes.SET_RUNTIME_FIELD, + payload: { + field, + newValue, + }, + }); +}; diff --git a/Composer/packages/client/src/store/index.tsx b/Composer/packages/client/src/store/index.tsx index 6ead1e5b4a..5dabe51214 100644 --- a/Composer/packages/client/src/store/index.tsx +++ b/Composer/packages/client/src/store/index.tsx @@ -67,6 +67,7 @@ export const initialBotState: BotState = { diagnostics: [], remoteEndpoints: {}, botStatus: BotStatus.unConnected, + botStatusInterval: undefined, botLoadErrorMsg: { title: '', message: '' }, lgFiles: [], schemas: {}, diff --git a/Composer/packages/client/src/store/persistence/FilePersistence.ts b/Composer/packages/client/src/store/persistence/FilePersistence.ts index af3787420b..a3abf10a25 100644 --- a/Composer/packages/client/src/store/persistence/FilePersistence.ts +++ b/Composer/packages/client/src/store/persistence/FilePersistence.ts @@ -25,6 +25,8 @@ const actionType2ChangeType = { [ActionTypes.REMOVE_SKILL_MANIFEST]: { changeType: ChangeType.DELETE, fileExtension: FileExtensions.Manifest }, [ActionTypes.UPDATE_SKILL_MANIFEST]: { changeType: ChangeType.UPDATE, fileExtension: FileExtensions.Manifest }, [ActionTypes.SYNC_ENV_SETTING]: { changeType: ChangeType.UPDATE, fileExtension: FileExtensions.Setting }, + [ActionTypes.SET_PUBLISH_TARGETS]: { changeType: ChangeType.UPDATE, fileExtension: FileExtensions.Setting }, + [ActionTypes.SET_RUNTIME_SETTINGS]: { changeType: ChangeType.UPDATE, fileExtension: FileExtensions.Setting }, }; class FilePersistence { diff --git a/Composer/packages/client/src/store/reducer/index.ts b/Composer/packages/client/src/store/reducer/index.ts index 9ba0eb1dc1..5c2b30c09c 100644 --- a/Composer/packages/client/src/store/reducer/index.ts +++ b/Composer/packages/client/src/store/reducer/index.ts @@ -32,6 +32,10 @@ import createReducer from './createReducer'; const projectFiles = ['bot', 'botproj']; +const PUBLISH_SUCCESS = 200; +const PUBLISH_PENDING = 202; +const PUBLISH_FAILED = 500; + const processSchema = (projectId: string, schema: any) => ({ ...schema, definitions: dereferenceDefinitions(schema.definitions), @@ -342,7 +346,7 @@ const saveTemplateId: ReducerFunc = (state, { templateId }) => { const setError: ReducerFunc = (state, payload) => { // if the error originated at the server and the server included message, use it... - if (payload && payload.status && payload.status === 409) { + if (payload?.status === 409) { state.error = { status: 409, message: formatMessage( @@ -351,7 +355,7 @@ const setError: ReducerFunc = (state, payload) => { summary: formatMessage('Modification Rejected'), }; } else { - if (payload && payload.response && payload.response.data && payload.response.data.message) { + if (payload?.response?.data?.message) { state.error = payload.response.data; } else { state.error = payload; @@ -447,6 +451,30 @@ const syncEnvSetting: ReducerFunc = (state, { settings, projectId }) => { return state; }; +const setPublishTargets: ReducerFunc = (state, { publishTarget }) => { + state.publishTargets = publishTarget; + return state; +}; + +const setRuntimeSettings: ReducerFunc = (state, { path, command }) => { + state.settings.runtime = { + customRuntime: true, + path, + command, + }; + return state; +}; + +const setRuntimeField: ReducerFunc = (state, { field, newValue }) => { + if (state.settings.runtime != null) state.settings.runtime[field] = newValue; + return state; +}; + +const setCustomRuntimeToggle: ReducerFunc = (state, { isOn }) => { + setRuntimeField(state, { field: 'customRuntime', newValue: isOn }); + return state; +}; + const setTemplateProjects: ReducerFunc = (state, { response } = {}) => { const data = response && response.data; @@ -484,10 +512,19 @@ const setPublishTypes: ReducerFunc = (state, { typelist }) => { return state; }; +const runtimePollingUpdate: ReducerFunc = (state, payload) => { + state.botStatusInterval = payload; + return state; +}; + const publishSuccess: ReducerFunc = (state, payload) => { - if (payload.target.name === 'default' && payload.endpointURL) { - state.botEndpoints[state.projectId] = `${payload.endpointURL}/api/messages`; - state.botStatus = BotStatus.connected; + if (payload.target.name === 'default') { + if (payload.status == PUBLISH_SUCCESS && payload.endpointURL) { + state.botEndpoints[state.projectId] = `${payload.endpointURL}/api/messages`; + state.botStatus = BotStatus.connected; + } else { + state.botStatus = BotStatus.reloading; + } } // prepend the latest publish results to the history @@ -516,9 +553,16 @@ const publishFailure: (title: string) => ReducerFunc = (title) => (state, { erro const getPublishStatus: ReducerFunc = (state, payload) => { // 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 (payload.target.name === 'default' && payload.endpointURL) { - state.botStatus = BotStatus.connected; - state.botEndpoints[state.projectId] = `${payload.endpointURL}/api/messages`; + if (payload.target.name === 'default') { + if (payload.status == PUBLISH_SUCCESS && payload.endpointURL) { + state.botEndpoints[state.projectId] = `${payload.endpointURL}/api/messages`; + state.botStatus = BotStatus.connected; + } else if (payload.status == PUBLISH_PENDING) { + state.botStatus = BotStatus.reloading; + } else if (payload.status == PUBLISH_FAILED) { + state.botStatus = BotStatus.failed; + state.botLoadErrorMsg = { ...payload, title: 'Start bot failed' }; + } } // if no history exists, create one with the latest status @@ -702,4 +746,9 @@ export const reducer = createReducer({ [ActionTypes.SET_APP_UPDATE_STATUS]: setAppUpdateStatus, [ActionTypes.DISPLAY_SKILL_MANIFEST_MODAL]: displaySkillManifestModal, [ActionTypes.DISMISS_SKILL_MANIFEST_MODAL]: dismissSkillManifestModal, + [ActionTypes.RUNTIME_POLLING_UPDATE]: runtimePollingUpdate, + [ActionTypes.SET_PUBLISH_TARGETS]: setPublishTargets, + [ActionTypes.SET_RUNTIME_SETTINGS]: setRuntimeSettings, + [ActionTypes.SET_CUSTOM_RUNTIME_TOGGLE]: setCustomRuntimeToggle, + [ActionTypes.SET_RUNTIME_FIELD]: setRuntimeField, }); diff --git a/Composer/packages/client/src/store/types.ts b/Composer/packages/client/src/store/types.ts index 5445e706b0..bfa9535a88 100644 --- a/Composer/packages/client/src/store/types.ts +++ b/Composer/packages/client/src/store/types.ts @@ -111,6 +111,7 @@ export interface BotState { remoteEndpoints: { [key: string]: string }; // possibly unused? botStatus: BotStatus; + botStatusInterval: NodeJS.Timeout | undefined; botLoadErrorMsg: { title: string; message: string; diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/AdaptiveFlowEditor.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/AdaptiveFlowEditor.test.tsx new file mode 100644 index 0000000000..ad83d07308 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/AdaptiveFlowEditor.test.tsx @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; +import { ExtensionContext } from '@bfc/extension'; + +import AdaptiveFlowEditor from '../../src/adaptive-flow-editor/AdaptiveFlowEditor'; + +import { ShellApiStub } from './stubs/ShellApiStub'; + +describe('', () => { + it('can render.', () => { + const visualDesigner = render( + + + + ); + expect(visualDesigner).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/components/KeyboardZone.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/components/KeyboardZone.test.tsx new file mode 100644 index 0000000000..0625746ee8 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/components/KeyboardZone.test.tsx @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render, fireEvent } from '@bfc/test-utils'; + +import { KeyboardZone } from '../../../src/adaptive-flow-editor/components/KeyboardZone'; + +describe('KeyboardZone', () => { + it('can be rendered.', () => { + const zone = render( + undefined}> + children + + ); + expect(zone).toBeTruthy(); + expect(zone.getByTestId('zone-child')).toBeTruthy(); + }); + + it('can trigger onCommand.', () => { + const mockOnCommand = jest.fn(); + const zone = render( + + children + + ).getByTestId('keyboard-zone'); + + fireEvent.focus(zone); + fireEvent.keyDown( + zone, + new KeyboardEvent('keydown', { + key: 'C', + code: 'C', + ctrlKey: true, + }) + ); + expect(mockOnCommand).toHaveBeenCalled(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ElementAttributes.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ElementAttributes.test.tsx new file mode 100644 index 0000000000..70471db044 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ElementAttributes.test.tsx @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { AttrNames } from '../../../src/adaptive-flow-editor/constants/ElementAttributes'; + +describe('ElementAttributes', () => { + it('should contain necessary attrs.', () => { + expect(AttrNames.SelectableElement).toBeTruthy(); + expect(AttrNames.NodeElement).toBeTruthy(); + expect(AttrNames.EdgeMenuElement).toBeTruthy(); + expect(AttrNames.FocusedId).toBeTruthy(); + expect(AttrNames.InlineLinkElement).toBeTruthy(); + expect(AttrNames.SelectedId).toBeTruthy(); + expect(AttrNames.Tab).toBeTruthy(); + expect(AttrNames.FocusedId).toBeTruthy(); + expect(AttrNames.SelectionIndex).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/KeyboardCommandTypes.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/KeyboardCommandTypes.test.ts new file mode 100644 index 0000000000..edbcb96764 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/KeyboardCommandTypes.test.ts @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { + KeyboardCommandTypes, + KeyboardPrimaryTypes, + mapShortcutToKeyboardCommand, +} from '../../../src/adaptive-flow-editor/constants/KeyboardCommandTypes'; + +describe('KeyboardCommandTypes', () => { + it('should be truthy.', () => { + expect(KeyboardCommandTypes).toBeTruthy(); + }); + + it('should contain 3 categories.', () => { + expect(KeyboardCommandTypes.Cursor).toBeTruthy(); + expect(KeyboardCommandTypes.Node).toBeTruthy(); + expect(KeyboardCommandTypes.Operation).toBeTruthy(); + }); + + it(' should contain necessary commands.', () => { + const { Cursor } = KeyboardCommandTypes; + + expect(Cursor.MoveUp).toBeTruthy(); + expect(Cursor.MoveDown).toBeTruthy(); + expect(Cursor.MoveLeft).toBeTruthy(); + expect(Cursor.MoveRight).toBeTruthy(); + expect(Cursor.ShortMoveUp).toBeTruthy(); + expect(Cursor.ShortMoveDown).toBeTruthy(); + expect(Cursor.ShortMoveLeft).toBeTruthy(); + expect(Cursor.ShortMoveRight).toBeTruthy(); + expect(Cursor.MovePrevious).toBeTruthy(); + expect(Cursor.MoveNext).toBeTruthy(); + }); + + it(' should contain necessary actions.', () => { + const { Node } = KeyboardCommandTypes; + + expect(Node.Delete).toBeTruthy(); + expect(Node.Copy).toBeTruthy(); + expect(Node.Cut).toBeTruthy(); + expect(Node.Paste).toBeTruthy(); + }); + + it(' should contain necessary operations.', () => { + const { Operation } = KeyboardCommandTypes; + + expect(Operation.Undo).toBeTruthy(); + expect(Operation.Redo).toBeTruthy(); + }); +}); + +describe('KeyboardPrimaryTypes', () => { + it('should contain 3 types.', () => { + expect(KeyboardPrimaryTypes.Cursor).toBeTruthy(); + expect(KeyboardPrimaryTypes.Node).toBeTruthy(); + expect(KeyboardPrimaryTypes.Operation).toBeTruthy(); + }); +}); + +describe('mapShortcutToKeyboardCommand', () => { + expect(mapShortcutToKeyboardCommand('Windows.Control.Z')).toEqual({ + area: 'Operation', + command: 'undo', + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/MenuTypes.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/MenuTypes.test.ts new file mode 100644 index 0000000000..07c2f13ac2 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/MenuTypes.test.ts @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { MenuTypes, MenuEventTypes } from '../../../src/adaptive-flow-editor/constants/MenuTypes'; + +describe('MenuTypes', () => { + it('should contain necessary keys.', () => { + expect(MenuTypes.EdgeMenu).toBeTruthy(); + expect(MenuTypes.NodeMenu).toBeTruthy(); + expect(MenuEventTypes.Paste).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ScreenReaderMessage.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ScreenReaderMessage.test.ts new file mode 100644 index 0000000000..b477462737 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/ScreenReaderMessage.test.ts @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { ScreenReaderMessage } from '../../../src/adaptive-flow-editor/constants/ScreenReaderMessage'; + +describe('ScreenReaderMessage', () => { + it('should contain necessary messages.', () => { + expect(ScreenReaderMessage.EventFocused).toBeTruthy(); + expect(ScreenReaderMessage.ActionFocused).toBeTruthy(); + expect(ScreenReaderMessage.ActionUnfocused).toBeTruthy(); + expect(ScreenReaderMessage.RangeSelection).toBeTruthy(); + expect(ScreenReaderMessage.DialogOpened).toBeTruthy(); + expect(ScreenReaderMessage.ActionDeleted).toBeTruthy(); + expect(ScreenReaderMessage.ActionsDeleted).toBeTruthy(); + expect(ScreenReaderMessage.ActionCreated).toBeTruthy(); + expect(ScreenReaderMessage.ActionsCreated).toBeTruthy(); + expect(ScreenReaderMessage.EventCreated).toBeTruthy(); + expect(ScreenReaderMessage.ActionsCopied).toBeTruthy(); + expect(ScreenReaderMessage.ActionsCut).toBeTruthy(); + expect(ScreenReaderMessage.ActionsMoved).toBeTruthy(); + expect(ScreenReaderMessage.ActionUndo).toBeTruthy(); + expect(ScreenReaderMessage.ActionRedo).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/editorConfig.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/editorConfig.test.ts new file mode 100644 index 0000000000..38abeef675 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/constants/editorConfig.test.ts @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { EditorConfig } from '../../../src/adaptive-flow-editor/constants/editorConfig'; + +describe('EditorConfig', () => { + it('should cover several features.', () => { + expect(EditorConfig).toBeTruthy(); + expect(EditorConfig.features).toBeDefined(); + + expect(EditorConfig.features.showEvents).toBeDefined(); + expect(EditorConfig.features.arrowNavigation).toBeDefined(); + expect(EditorConfig.features.tabNavigation).toBeDefined(); + expect(EditorConfig.features.keyboardNodeEditing).toBeDefined(); + expect(EditorConfig.features.keyboardOperationEditing).toBeDefined(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/NodeRendererContext.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/NodeRendererContext.test.tsx new file mode 100644 index 0000000000..40a9108bca --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/NodeRendererContext.test.tsx @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React, { useContext } from 'react'; +import { render } from '@bfc/test-utils'; +import { DialogFactory } from '@bfc/shared'; + +import { NodeRendererContext } from '../../../src/adaptive-flow-editor/contexts/NodeRendererContext'; + +describe('NodeRendererContext', () => { + const CtxtConsumer = () => { + const { focusedId, focusedEvent, focusedTab, clipboardActions, dialogFactory, customSchemas } = useContext( + NodeRendererContext + ); + + return ( +
+ {focusedId} + {focusedEvent} + {focusedTab} + {clipboardActions.length} + {'' + !!dialogFactory} + {customSchemas.length} +
+ ); + }; + it('can be consumed.', () => { + const ele = render( + + + + ); + + expect(ele.getByTestId('focusedId-value').textContent).toEqual('id1'); + expect(ele.getByTestId('focusedEvent-value').textContent).toEqual('event1'); + expect(ele.getByTestId('focusedTab-value').textContent).toEqual('tab1'); + expect(ele.getByTestId('clipboardAction-length').textContent).toEqual('1'); + expect(ele.getByTestId('dialogFactory-existence').textContent).toEqual('true'); + expect(ele.getByTestId('customSchemas-length').textContent).toEqual('1'); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/SelectionContext.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/SelectionContext.test.tsx new file mode 100644 index 0000000000..9f3e15288a --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/contexts/SelectionContext.test.tsx @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React, { useContext } from 'react'; +import { render } from '@bfc/test-utils'; + +import { SelectionContext } from '../../../src/adaptive-flow-editor/contexts/SelectionContext'; + +describe('SelectionContext', () => { + const ContextConsumer = () => { + const { getNodeIndex, getSelectableIds, selectedIds, setSelectedIds, selectableElements } = useContext( + SelectionContext + ); + return ( +
+ {getNodeIndex('')} + {getSelectableIds().join(',')} + {selectedIds.join(',')} + {'' + !!setSelectedIds} + {selectableElements.length} +
+ ); + }; + it('can be provided.', () => { + const ele = render( + 1, + getSelectableIds: () => ['a', 'b', 'c'], + selectedIds: ['a'], + setSelectedIds: () => null, + selectableElements: [], + }} + > + + + ); + + expect(ele.getByTestId('getNodeIndex-result').textContent).toEqual('1'); + expect(ele.getByTestId('getSelectableIds-result').textContent).toEqual('a,b,c'); + expect(ele.getByTestId('selectedIds-str').textContent).toEqual('a'); + expect(ele.getByTestId('setSelectedIds-existence').textContent).toEqual('true'); + expect(ele.getByTestId('selectableElements-length').textContent).toEqual('0'); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/hooks/useEditorEventApi.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/hooks/useEditorEventApi.test.ts new file mode 100644 index 0000000000..64bfc2d68b --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/hooks/useEditorEventApi.test.ts @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { renderHook } from '@bfc/test-utils/lib/hooks'; + +import { useEditorEventApi } from '../../../src/adaptive-flow-editor/hooks/useEditorEventApi'; +import { ShellApiStub } from '../stubs/ShellApiStub'; +import { defaultRendererContextValue } from '../../../src/adaptive-flow-editor/contexts/NodeRendererContext'; +import { defaultSelectionContextValue } from '../../../src/adaptive-flow-editor/contexts/SelectionContext'; +import { NodeEventTypes } from '../../../src/adaptive-flow-renderer/constants/NodeEventTypes'; + +describe('useSelectionEffect', () => { + const hook = renderHook(() => + useEditorEventApi( + { + path: '', + data: {}, + nodeContext: { ...defaultRendererContextValue, focusedId: 'a' }, + selectionContext: { ...defaultSelectionContextValue, selectedIds: ['a'] }, + }, + ShellApiStub + ) + ).result.current; + + it('returns necessary apis.', () => { + expect(hook.handleEditorEvent).toBeTruthy(); + }); + + it('can handle events.', () => { + const { handleEditorEvent } = hook; + + handleEditorEvent('event.view.focus' as NodeEventTypes, {}); + handleEditorEvent('event.view.ctrl-click' as NodeEventTypes, {}); + handleEditorEvent('event.view.shift-click' as NodeEventTypes, {}); + handleEditorEvent('event.view.focus-event' as NodeEventTypes, {}); + handleEditorEvent('event.view.move-cursor' as NodeEventTypes, {}); + handleEditorEvent('event.nav.opendialog' as NodeEventTypes, {}); + handleEditorEvent('event.data.delete' as NodeEventTypes, {}); + handleEditorEvent('event.data.insert' as NodeEventTypes, {}); + handleEditorEvent('event.data.copy-selection' as NodeEventTypes, {}); + handleEditorEvent('event.data.cut-selection' as NodeEventTypes, {}); + handleEditorEvent('event.data.paste-selection' as NodeEventTypes, {}); + handleEditorEvent('event.data.move-selection' as NodeEventTypes, {}); + handleEditorEvent('event.data.delete-selection' as NodeEventTypes, {}); + handleEditorEvent('event.data.paste-selection--keyboard' as NodeEventTypes, {}); + handleEditorEvent('event.data.paste-selection--menu' as NodeEventTypes, {}); + handleEditorEvent('event.operation.undo' as NodeEventTypes, {}); + handleEditorEvent('event.operation.redo' as NodeEventTypes, {}); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/EdgeMenu.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/EdgeMenu.test.tsx new file mode 100644 index 0000000000..177479e59a --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/EdgeMenu.test.tsx @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; +import { DialogGroup } from '@bfc/shared'; + +import { EdgeMenu } from '../../../src/adaptive-flow-editor/renderers/EdgeMenu'; +import { createActionMenu } from '../../../src/adaptive-flow-editor/renderers/EdgeMenu/createSchemaMenu'; + +describe('', () => { + it('can render.', () => { + const menu = render( undefined} />); + expect(menu).toBeTruthy(); + }); +}); + +describe('createActionMenu()', () => { + it('options.enablePaste should control Paste button state.', () => { + const menuItems1 = createActionMenu(() => null, { isSelfHosted: false, enablePaste: true }); + expect(menuItems1.findIndex((x) => x.key === 'Paste')).toEqual(0); + expect(menuItems1[0].disabled).toBeFalsy(); + + const menuItems2 = createActionMenu(() => null, { isSelfHosted: false, enablePaste: false }); + expect(menuItems2[0].disabled).toBeTruthy(); + }); + + it('should return builtin $kinds.', () => { + const menuItemsHosted = createActionMenu(() => null, { isSelfHosted: true, enablePaste: true }); + expect(menuItemsHosted.findIndex((x) => x.key === DialogGroup.RESPONSE)).toBeTruthy(); + }); + + it('should show custom actions as last item.', () => { + const menuItemsWithoutCustomActions = createActionMenu(() => null, { isSelfHosted: false, enablePaste: false }, []); + expect(menuItemsWithoutCustomActions.findIndex((x) => x.key === 'Custom Actions')).toEqual(-1); + + const customActions = [ + [{ title: 'Custom1', description: 'Custom1', $ref: 'Group1.Custom1' }], + [{ title: 'Custom2', description: 'Custom2', $ref: 'Group2.Custom2' }], + ]; + const withCustomActions = createActionMenu(() => null, { isSelfHosted: false, enablePaste: false }, customActions); + expect(withCustomActions.findIndex((x) => x.key === 'Custom Actions')).toEqual(withCustomActions.length - 1); + expect(withCustomActions[withCustomActions.length - 1].subMenuProps?.items.length).toEqual(3); // 2 action labels + 1 sep line + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/ElementWrapper.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/ElementWrapper.test.tsx new file mode 100644 index 0000000000..81a2850a7b --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/ElementWrapper.test.tsx @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { ElementWrapper } from '../../../src/adaptive-flow-editor/renderers/ElementWrapper'; + +describe('', () => { + it('can render.', () => { + const ele = render( + + Content + + ); + + expect(ele).toBeTruthy(); + expect(ele.getByTestId('wrapped-content')).toBeTruthy(); + expect(ele.getByTestId('wrapped-content').textContent).toEqual('Content'); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/NodeWrapper.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/NodeWrapper.test.tsx new file mode 100644 index 0000000000..8ae45c2f02 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/renderers/NodeWrapper.test.tsx @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render, fireEvent } from '@bfc/test-utils'; +import ExtensionContext from '@bfc/extension/lib/extensionContext'; + +import { ActionNodeWrapper } from '../../../src/adaptive-flow-editor/renderers/NodeWrapper'; +import { ShellApiStub } from '../stubs/ShellApiStub'; + +describe('', () => { + it('can render.', () => { + const mockOnEvent = jest.fn(); + const ele = render( + + + + ); + expect(ele.getByTestId('ActionNodeWrapper')).toBeTruthy(); + + fireEvent.click(ele.getByTestId('ActionNodeWrapper')); + expect(mockOnEvent).toHaveBeenCalled(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/stubs/ShellApiStub.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/stubs/ShellApiStub.ts new file mode 100644 index 0000000000..71a0939388 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/stubs/ShellApiStub.ts @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { ShellApi } from '@bfc/shared'; + +const fn = () => ({} as any); +const fnList = () => [] as any[]; +const fnPromise = () => Promise.resolve({} as any); + +export const ShellApiStub: ShellApi = { + getDialog: fn, + saveDialog: fn, + saveData: fn, + navTo: fn, + onFocusSteps: fn, + onFocusEvent: fn, + onSelect: fn, + getLgTemplates: fnList, + copyLgTemplate: fnPromise, + addLgTemplate: fnPromise, + updateLgTemplate: fnPromise, + removeLgTemplate: fnPromise, + removeLgTemplates: fnPromise, + getLuIntent: fn, + getLuIntents: fnList, + addLuIntent: fnPromise, + updateLuIntent: fnPromise, + removeLuIntent: fn, + updateRegExIntent: fn, + createDialog: fnPromise, + addCoachMarkRef: fn, + onCopy: fn, + undo: fn, + redo: fn, + updateUserSettings: fn, + addSkillDialog: fnPromise, + announce: fn, + displayManifestModal: fn, +}; + +describe('ShellApiStub', () => { + it('be truthy.', () => { + expect(ShellApiStub).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/NodeIndexGetter.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/NodeIndexGetter.test.ts new file mode 100644 index 0000000000..ebda36e5e4 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/NodeIndexGetter.test.ts @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { NodeIndexGenerator } from '../../../src/adaptive-flow-editor/utils/NodeIndexGetter'; + +describe('NodeIndexGetter', () => { + it('can work e2e.', () => { + const n = new NodeIndexGenerator(); + + const aId = n.getNodeIndex('a'); + expect(aId).toEqual(0); + expect(n.getItemList()).toEqual([{ key: 'a' }]); + + const bId = n.getNodeIndex('b'); + expect(bId).toEqual(1); + expect(n.getItemList()).toEqual([{ key: 'a' }, { key: 'b' }]); + + const bId2 = n.getNodeIndex('b'); + expect(bId2).toEqual(1); + expect(n.getItemList()).toEqual([{ key: 'a' }, { key: 'b' }]); + + n.reset(); + expect(n.getItemList()).toEqual([]); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/calculateRangeSelection.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/calculateRangeSelection.test.ts new file mode 100644 index 0000000000..85457c6b55 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/calculateRangeSelection.test.ts @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { calculateRangeSelection } from '../../../src/adaptive-flow-editor/utils/calculateRangeSelection'; + +describe('calculateRangeSelection()', () => { + it('could pick correct range.', () => { + expect(calculateRangeSelection('b', 'd', ['a', 'b', 'c', 'd'])).toEqual(['b', 'c', 'd']); + expect(calculateRangeSelection('d', 'b', ['a', 'b', 'c', 'd'])).toEqual(['b', 'c', 'd']); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/index.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/index.test.ts new file mode 100644 index 0000000000..6e83131758 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/index.test.ts @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { moveCursor } from '../../../../src/adaptive-flow-editor/utils/cursorTracker'; +import { KeyboardCommandTypes } from '../../../../src/adaptive-flow-editor/constants/KeyboardCommandTypes'; + +describe('moveCursor', () => { + it('returns undfined when no selectableElements.', () => { + expect(moveCursor([], 'test', KeyboardCommandTypes.Cursor.MovePrevious)).toEqual({ + selected: 'test', + focused: undefined, + }); + }); + + it('can handle Tab move.', () => { + expect( + moveCursor( + [ + { + selectedId: 'test', + focusedId: 'test-focused', + bounds: { left: 0, top: 0, right: 10, bottom: 10 }, + } as any, + ], + 'test', + KeyboardCommandTypes.Cursor.MoveNext + ) + ).toEqual({ focused: 'test-focused', selected: 'test', tab: '' }); + }); + + it('can handle Arrow move.', () => { + expect( + moveCursor( + [ + { + selectedId: 'test', + focusedId: 'test-focused', + bounds: { left: 0, top: 0, right: 10, bottom: 10 }, + } as any, + ], + 'test', + KeyboardCommandTypes.Cursor.MoveLeft + ) + ).toEqual({ focused: 'test-focused', selected: 'test', tab: '' }); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/type.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/type.test.ts new file mode 100644 index 0000000000..f2a8ab5f92 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/cursorTracker/type.test.ts @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { + SelectorElement, + Direction, + BoundRect, + Axle, +} from '../../../../src/adaptive-flow-editor/utils/cursorTracker/type'; + +describe('types', () => { + it('should be declared.', () => { + expect(SelectorElement).toBeTruthy(); + expect(Direction).toBeTruthy(); + expect(BoundRect).toBeTruthy(); + expect(Axle).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.test.ts new file mode 100644 index 0000000000..1c0d4b5658 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.test.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { mapKeyboardCommandToEditorEvent } from '../../../src/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent'; +import { + KeyboardPrimaryTypes, + KeyboardCommandTypes, +} from '../../../src/adaptive-flow-editor/constants/KeyboardCommandTypes'; +import { NodeEventTypes } from '../../../src/adaptive-flow-renderer/constants/NodeEventTypes'; + +describe('mapKeyboardCommandToEditorEvent()', () => { + it('can map event to correct result.', () => { + const validationChart = { + [KeyboardPrimaryTypes.Node]: { + [KeyboardCommandTypes.Node.Delete]: NodeEventTypes.DeleteSelection, + [KeyboardCommandTypes.Node.Copy]: NodeEventTypes.CopySelection, + [KeyboardCommandTypes.Node.Cut]: NodeEventTypes.CutSelection, + [KeyboardCommandTypes.Node.Paste]: NodeEventTypes.PasteSelection, + }, + [KeyboardPrimaryTypes.Operation]: { + [KeyboardCommandTypes.Operation.Undo]: NodeEventTypes.Undo, + [KeyboardCommandTypes.Operation.Redo]: NodeEventTypes.Redo, + }, + }; + + Object.keys(validationChart).forEach((area) => { + const subchart = validationChart[area]; + Object.keys(subchart).forEach((command) => { + const resultType = subchart[command]; + expect(mapKeyboardCommandToEditorEvent({ area, command })?.type).toEqual(resultType); + }); + }); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mergePluginConfig.test.ts b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mergePluginConfig.test.ts new file mode 100644 index 0000000000..e6f444199c --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-editor/utils/mergePluginConfig.test.ts @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { mergePluginConfig } from '../../../src/adaptive-flow-editor/utils/mergePluginConfig'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('mergePluginConfig()', () => { + it('can generate correct config.', () => { + const plugins: any = [ + { + visualSchema: { + widgets: { widget1: 'w1' }, + schema: { [AdaptiveKinds.IfCondition]: 'widget1' }, + }, + }, + { + visualSchema: { + widgets: { widget2: 'w2' }, + schema: { [AdaptiveKinds.SwitchCondition]: 'widget2' }, + }, + }, + ]; + expect(mergePluginConfig(...plugins)).toMatchObject({ + widgets: { + widget1: 'w1', + widget2: 'w2', + }, + schema: { + [AdaptiveKinds.IfCondition]: 'widget1', + [AdaptiveKinds.SwitchCondition]: 'widget2', + }, + }); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ActionCard.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ActionCard.test.tsx new file mode 100644 index 0000000000..0ff082eae3 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ActionCard.test.tsx @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { ActionCard } from '../../../src/adaptive-flow-renderer/widgets'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('ActionCard', () => { + it('can be rendered.', () => { + const card = render( null} />); + expect(card).toBeTruthy(); + }); + + it('can be rendered with injected content.', () => { + const card = render( + Body} + data={{ $kind: AdaptiveKinds.SendActivity }} + footer={Footer} + header={Header} + id="test" + onEvent={() => null} + /> + ); + expect(card.getByTestId('test-header')).toBeTruthy(); + expect(card.getByTestId('test-body')).toBeTruthy(); + expect(card.getByTestId('test-footer')).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/DialogRef.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/DialogRef.test.tsx new file mode 100644 index 0000000000..477089175c --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/DialogRef.test.tsx @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { DialogRef } from '../../../src/adaptive-flow-renderer/widgets'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('DialogRef', () => { + it('can be rendered.', () => { + const dialogRef = render( + null} /> + ); + expect(dialogRef).toBeTruthy(); + }); + + it('can ref string dialog value correctly.', () => { + const dialogRef = render( + null} /> + ); + expect(dialogRef.queryAllByText('test-dialog')).toHaveLength(1); + }); + + it('can ref object dialog value correctly.', () => { + const dialogRef = render( + null} + /> + ); + expect(dialogRef.queryAllByText('test-dialog-obj')).toHaveLength(1); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ForeachWidget.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ForeachWidget.test.tsx new file mode 100644 index 0000000000..c9f3f24d09 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/ForeachWidget.test.tsx @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { ForeachWidget } from '../../../src/adaptive-flow-renderer/widgets'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('ForeachWidget', () => { + it('can be rendered correctly.', () => { + const foreachNode = render( + Loop Head} + onEvent={() => null} + /> + ); + expect(foreachNode).toBeTruthy(); + expect(foreachNode.getByTestId('test-loop')).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/IfConditionWidget.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/IfConditionWidget.test.tsx new file mode 100644 index 0000000000..a6a872cf52 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/IfConditionWidget.test.tsx @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { IfConditionWidget } from '../../../src/adaptive-flow-renderer/widgets'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('IfConditionWidget', () => { + it('can be rendered correctly.', () => { + const ifCondition = render( + Condition Judgement} + onEvent={() => null} + /> + ); + expect(ifCondition).toBeTruthy(); + expect(ifCondition.getByTestId('test-judgement')).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/PromptWidget.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/PromptWidget.test.tsx new file mode 100644 index 0000000000..5d3c89a208 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/PromptWidget.test.tsx @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { PromptWidget } from '../../../src/adaptive-flow-renderer/widgets'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('PromptWidget', () => { + it('can be rendered correctly.', () => { + const promptNode = render( + BotAsks} + data={{ $kind: AdaptiveKinds.TextInput }} + id="test" + userInput={UserInput} + onEvent={() => null} + /> + ); + expect(promptNode).toBeTruthy(); + expect(promptNode.getByTestId('test-botAsks')).toBeTruthy(); + expect(promptNode.getByTestId('test-userInput')).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/SwitchConditionWidget.test.tsx b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/SwitchConditionWidget.test.tsx new file mode 100644 index 0000000000..89c65e65a5 --- /dev/null +++ b/Composer/packages/extensions/adaptive-flow/__tests__/adaptive-flow-renderer/widgets/SwitchConditionWidget.test.tsx @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import React from 'react'; +import { render } from '@bfc/test-utils'; + +import { SwitchConditionWidget } from '../../../src/adaptive-flow-renderer/widgets'; +import { AdaptiveKinds } from '../../../src/adaptive-flow-renderer/constants/AdaptiveKinds'; + +describe('SwitchConditionWidget', () => { + it('can be rendered correctly.', () => { + const switchCondition = render( + Condition Judgement} + onEvent={() => null} + /> + ); + expect(switchCondition).toBeTruthy(); + expect(switchCondition.getByTestId('test-judgement')).toBeTruthy(); + }); +}); diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx index 0118d98d45..810167bdb5 100644 --- a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx +++ b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/AdaptiveFlowEditor.tsx @@ -21,7 +21,7 @@ import { mergePluginConfig } from './utils/mergePluginConfig'; import { getCustomSchema } from './utils/getCustomSchema'; import { SelectionContext } from './contexts/SelectionContext'; import { KeyboardZone } from './components/KeyboardZone'; -import { mapKeyboardCommandToEditorEvent } from './utils/mapKeyboardCommandToEditorEvent.ts'; +import { mapKeyboardCommandToEditorEvent } from './utils/mapKeyboardCommandToEditorEvent'; import { useSelectionEffect } from './hooks/useSelectionEffect'; import { useEditorEventApi } from './hooks/useEditorEventApi'; import { diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/components/KeyboardZone.tsx b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/components/KeyboardZone.tsx index 788e76d8ae..7f97598d45 100644 --- a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/components/KeyboardZone.tsx +++ b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/components/KeyboardZone.tsx @@ -62,7 +62,7 @@ export const KeyboardZone = React.forwardRef( }; return ( -
+
{children}
); diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/NodeRendererContext.ts b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/NodeRendererContext.ts index 4a8cc7d126..d78c9e64e5 100644 --- a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/NodeRendererContext.ts +++ b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/NodeRendererContext.ts @@ -13,11 +13,12 @@ export interface NodeRendererContextValue { customSchemas: OBISchema[]; } -export const NodeRendererContext = React.createContext({ +export const defaultRendererContextValue = { focusedId: '', focusedEvent: '', focusedTab: '', clipboardActions: [], - dialogFactory: new DialogFactory(), + dialogFactory: new DialogFactory({}), customSchemas: [], -}); +}; +export const NodeRendererContext = React.createContext(defaultRendererContextValue); diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/SelectionContext.ts b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/SelectionContext.ts index a7b576af26..c3a48ee572 100644 --- a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/SelectionContext.ts +++ b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/contexts/SelectionContext.ts @@ -13,10 +13,11 @@ export interface SelectionContextData { selectableElements: SelectorElement[]; } -export const SelectionContext = React.createContext({ +export const defaultSelectionContextValue = { getNodeIndex: (_: string): number => 0, getSelectableIds: () => [], selectedIds: [] as string[], setSelectedIds: () => null, selectableElements: [], -}); +}; +export const SelectionContext = React.createContext(defaultSelectionContextValue); diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/hooks/useWindowDimensions.ts b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/hooks/useWindowDimensions.ts deleted file mode 100644 index 6707cce97a..0000000000 --- a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/hooks/useWindowDimensions.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import { useState, useEffect, useRef } from 'react'; -import debounce from 'lodash/debounce'; - -const getWindowDimensions = () => { - const { innerWidth: width, innerHeight: height } = window; - return { - width, - height, - }; -}; - -export const useWindowDimensions = () => { - const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()); - const handleResize = useRef(debounce(() => setWindowDimensions(getWindowDimensions()), 200)).current; - - useEffect(() => { - window.addEventListener('resize', handleResize); - return () => window.removeEventListener('resize', handleResize); - }, []); - - return windowDimensions; -}; diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/renderers/NodeWrapper.tsx b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/renderers/NodeWrapper.tsx index 3255718da8..c8799f64df 100644 --- a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/renderers/NodeWrapper.tsx +++ b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/renderers/NodeWrapper.tsx @@ -74,6 +74,7 @@ export const ActionNodeWrapper: FC = ({ id, tab, data, onEvent ${!nodeFocused && nodeBorderHoveredStyle} } `} + data-testid="ActionNodeWrapper" {...declareElementAttributes(selectableId, id)} aria-label={generateSDKTitle(data, '', tab)} onClick={(e) => { diff --git a/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.ts.ts b/Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.ts similarity index 100% rename from Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.ts.ts rename to Composer/packages/extensions/adaptive-flow/src/adaptive-flow-editor/utils/mapKeyboardCommandToEditorEvent.ts diff --git a/Composer/packages/extensions/extension/src/index.ts b/Composer/packages/extensions/extension/src/index.ts index 3ecebc1a7c..931425d29c 100644 --- a/Composer/packages/extensions/extension/src/index.ts +++ b/Composer/packages/extensions/extension/src/index.ts @@ -1,9 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Extension } from './components'; +import extensionContext from './extensionContext'; export * from './components'; export * from './hooks'; export * from './types'; export default Extension; + +export const ExtensionContext = extensionContext; diff --git a/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts b/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts index 74b5d291e1..f0f1512184 100644 --- a/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts +++ b/Composer/packages/extensions/plugin-loader/src/composerPluginRegistration.ts @@ -56,10 +56,19 @@ export class ComposerPluginRegistration { /************************************************************************************** * Publish related features *************************************************************************************/ - public async addPublishMethod(plugin: PublishPlugin, schema?: JSONSchema7, instructions?: string) { + public async addPublishMethod( + plugin: PublishPlugin, + schema?: JSONSchema7, + instructions?: string, + customName?: string, + customDescription?: string + ) { log('registering publish method', this.name); - this.loader.extensions.publish[this.name] = { - plugin: this, + this.loader.extensions.publish[customName || this.name] = { + plugin: { + name: customName || this.name, + description: customDescription || this.description, + }, instructions: instructions, methods: plugin, schema: schema, @@ -89,6 +98,16 @@ export class ComposerPluginRegistration { this.loader.extensions.runtimeTemplates.push(plugin); } + // return a reference to the plugin used by the app + public getRuntimeByProject(project): RuntimeTemplate { + return this.loader.getRuntimeByProject(project); + } + + // return a reference to the plugin used by the app + 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..a07d8b3b14 100644 --- a/Composer/packages/extensions/plugin-loader/src/pluginLoader.ts +++ b/Composer/packages/extensions/plugin-loader/src/pluginLoader.ts @@ -10,9 +10,11 @@ import { pathToRegexp } from 'path-to-regexp'; import glob from 'globby'; import { ComposerPluginRegistration } from './composerPluginRegistration'; -import { UserIdentity, ExtensionCollection } from './types'; +import { UserIdentity, ExtensionCollection, RuntimeTemplate } from './types'; import log from './logger'; +const DEFAULT_RUNTIME = 'csharp-azurewebapp'; + export class PluginLoader { private _passport: passport.PassportStatic; private _webserver: Express | undefined; @@ -109,6 +111,30 @@ export class PluginLoader { } } + // return a reference to the plugin used by the app + public getRuntimeByProject(project): RuntimeTemplate { + const type = project.settings.runtime?.key || DEFAULT_RUNTIME; + const templates = this.extensions.runtimeTemplates.filter((t) => t.key === type); + if (templates.length) { + return templates[0]; + } else { + throw new Error(`Support for runtime with name ${type} not available`); + } + } + + // return a reference to the plugin used by the app + public getRuntime(type: string | undefined): RuntimeTemplate { + if (!type) { + type = DEFAULT_RUNTIME; + } + const templates = this.extensions.runtimeTemplates.filter((t) => t.key === type); + if (templates.length) { + return templates[0]; + } else { + throw new Error(`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 ba8d174e35..8c30fdbe76 100644 --- a/Composer/packages/extensions/plugin-loader/src/types.ts +++ b/Composer/packages/extensions/plugin-loader/src/types.ts @@ -6,8 +6,6 @@ import { JSONSchema7 } from 'json-schema'; // 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; comment?: string; @@ -48,6 +46,18 @@ export interface RuntimeTemplate { /** method used to eject the runtime into a project. returns resulting path of runtime! */ eject: (project: any, localDisk?: any) => Promise; + /** build method */ + build: (runtimePath: string, project: any) => Promise; + + /** run */ + run: (project: any, localDisk?: any) => Promise; + + /** build for deploy method */ + buildDeploy: (runtimePath: string, project: any, settings: any, profileName: string) => Promise; + + /** path to code template */ + path: string; + /** internal use key */ key: string; @@ -69,7 +79,10 @@ export interface ExtensionCollection { }; publish: { [key: string]: { - plugin: ComposerPluginRegistration; + plugin: { + name: string; + description: string; + }; methods: PublishPlugin; /** (Optional instructions displayed in the UI) */ instructions?: string; diff --git a/Composer/packages/lib/bot-deploy/.gitignore b/Composer/packages/lib/bot-deploy/.gitignore deleted file mode 100644 index 1ccc52a7fb..0000000000 --- a/Composer/packages/lib/bot-deploy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/node_modules -/lib \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/README.md b/Composer/packages/lib/bot-deploy/README.md deleted file mode 100644 index bac3d47eee..0000000000 --- a/Composer/packages/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/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts new file mode 100644 index 0000000000..f69517f7b2 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts @@ -0,0 +1,99 @@ +import { BotProjectDeployConfig } from './botProjectDeployConfig'; +export declare class BotProjectDeploy { + private subId; + private accessToken; + private creds; + private projPath; + private deploymentSettingsPath; + private deployFilePath; + private zipPath; + private publishFolder; + private settingsPath; + private templatePath; + private dotnetProjectPath; + private generatedFolder; + private remoteBotPath; + private logger; + private tenantId; + constructor(config: BotProjectDeployConfig); + private getErrorMesssage; + private pack; + /** + * For more information about this api, please refer to this doc: https://docs.microsoft.com/en-us/rest/api/resources/Tenants/List + */ + private getTenantId; + private unpackObject; + /** + * Format the parameters + */ + private getDeploymentTemplateParam; + private readTemplateFile; + /*********************************************************************************************** + * Azure API accessors + **********************************************************************************************/ + /** + * Use the Azure API to create a new resource group + */ + private createResourceGroup; + /** + * Validate the deployment using the Azure API + */ + private validateDeployment; + /** + * Using an ARM template, provision a bunch of resources + */ + private createDeployment; + private createApp; + /** + * Write updated settings back to the settings file + */ + private updateDeploymentJsonFile; + private getFiles; + private botPrepareDeploy; + private dotnetPublish; + private zipDirectory; + private notEmptyLuisModel; + private publishLuis; + /** + * Deploy a bot to a location + */ + deploy( + name: string, + environment: string, + luisAuthoringKey?: string, + luisAuthoringRegion?: string, + botPath?: string, + language?: string, + hostname?: string, + luisResource?: string + ): Promise; + private getAccount; + private deployZip; + /** + * Provision a set of Azure resources for use with a bot + */ + create( + name: string, + location: string, + environment: string, + appPassword: string, + createLuisResource?: boolean, + createLuisAuthoringResource?: boolean, + createCosmosDb?: boolean, + createStorage?: boolean, + createAppInsights?: boolean + ): Promise; + /** + * createAndDeploy + * provision the Azure resources AND deploy a bot to those resources + */ + createAndDeploy( + name: string, + location: string, + environment: string, + appPassword: string, + luisAuthoringKey?: string, + luisAuthoringRegion?: string + ): Promise; +} +//# sourceMappingURL=botProjectDeploy.d.ts.map diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts.map b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts.map new file mode 100644 index 0000000000..bb990ed9cf --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"botProjectDeploy.d.ts","sourceRoot":"","sources":["../src/botProjectDeploy.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAUlE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAkB;IAGhC,OAAO,CAAC,QAAQ,CAAM;gBAEV,MAAM,EAAE,sBAAsB;IAuC1C,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,IAAI;IAMZ;;OAEG;YACW,WAAW;IAyBzB,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,0BAA0B;YAwBpB,gBAAgB;IAW9B;;oGAEgG;IAEhG;;OAEG;YACW,mBAAmB;IAgBjC;;OAEG;YACW,kBAAkB;IAuBhC;;OAEG;YACW,gBAAgB;YAwBhB,SAAS;IAgBvB;;OAEG;YACW,wBAAwB;YAwBxB,QAAQ;YAWR,gBAAgB;YAYhB,aAAa;YAyBb,YAAY;IAe1B,OAAO,CAAC,iBAAiB;YAMX,WAAW;IAwIzB;;OAEG;IACU,MAAM,CACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,gBAAgB,CAAC,EAAE,MAAM,EACzB,mBAAmB,CAAC,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM;IA+EvB,OAAO,CAAC,UAAU;YASJ,SAAS;IAkCvB;;OAEG;IACU,MAAM,CACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,kBAAkB,UAAO,EACzB,2BAA2B,UAAO,EAClC,cAAc,UAAO,EACrB,aAAa,UAAO,EACpB,iBAAiB,UAAO;IAwR1B;;;OAGG;IACU,eAAe,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,gBAAgB,CAAC,EAAE,MAAM,EACzB,mBAAmB,CAAC,EAAE,MAAM;CAK/B"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js new file mode 100644 index 0000000000..707e611af4 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js @@ -0,0 +1,1465 @@ +'use strict'; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +var __createBinding = + (this && this.__createBinding) || + (Object.create + ? function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: function () { + return m[k]; + }, + }); + } + : function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); +var __setModuleDefault = + (this && this.__setModuleDefault) || + (Object.create + ? function (o, v) { + Object.defineProperty(o, 'default', { enumerable: true, value: v }); + } + : function (o, v) { + o['default'] = v; + }); +var __importStar = + (this && this.__importStar) || + function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; + }; +var __awaiter = + (this && this.__awaiter) || + function (thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P + ? value + : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator['throw'](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; +var __generator = + (this && this.__generator) || + function (thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [], + }, + f, + y, + t, + g; + return ( + (g = { next: verb(0), throw: verb(1), return: verb(2) }), + typeof Symbol === 'function' && + (g[Symbol.iterator] = function () { + return this; + }), + g + ); + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + function step(op) { + if (f) throw new TypeError('Generator is already executing.'); + while (_) + try { + if ( + ((f = 1), + y && + (t = op[0] & 2 ? y['return'] : op[0] ? y['throw'] || ((t = y['return']) && t.call(y), 0) : y.next) && + !(t = t.call(y, op[1])).done) + ) + return t; + if (((y = 0), t)) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!((t = _.trys), (t = t.length > 0 && t[t.length - 1])) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + }; +Object.defineProperty(exports, '__esModule', { value: true }); +exports.BotProjectDeploy = void 0; +var path = __importStar(require('path')); +var util = __importStar(require('util')); +var arm_resources_1 = require('@azure/arm-resources'); +var arm_appinsights_1 = require('@azure/arm-appinsights'); +var arm_botservice_1 = require('@azure/arm-botservice'); +var graph_1 = require('@azure/graph'); +var ms_rest_nodeauth_1 = require('@azure/ms-rest-nodeauth'); +var fs = __importStar(require('fs-extra')); +var rp = __importStar(require('request-promise')); +var botProjectLoggerType_1 = require('./botProjectLoggerType'); +var archiver = require('archiver'); +var exec = util.promisify(require('child_process').exec); +var promisify = require('util').promisify; +var luBuild = require('@microsoft/bf-lu/lib/parser/lubuild/builder.js'); +var readdir = promisify(fs.readdir); +var BotProjectDeploy = /** @class */ (function () { + function BotProjectDeploy(config) { + var _a, _b, _c, _d, _e, _f, _g, _h, _j; + // Will be assigned by create or deploy + this.tenantId = ''; + this.subId = config.subId; + this.logger = config.logger; + this.accessToken = config.accessToken; + this.creds = config.creds; + this.projPath = config.projPath; + // set path to .deployment file which points at the BotProject.csproj + this.deployFilePath = + (_a = config.deployFilePath) !== null && _a !== void 0 ? _a : path.join(this.projPath, '.deployment'); + // path to the zipped assets + this.zipPath = (_b = config.zipPath) !== null && _b !== void 0 ? _b : path.join(this.projPath, 'code.zip'); + // path to the built, ready to deploy code assets + this.publishFolder = + (_c = config.publishFolder) !== null && _c !== void 0 + ? _c + : path.join(this.projPath, 'bin', 'Release', 'netcoreapp3.1'); + // path to the source appsettings.deployment.json file + this.settingsPath = + (_d = config.settingsPath) !== null && _d !== void 0 + ? _d + : path.join(this.projPath, 'appsettings.deployment.json'); + // path to the deployed settings file that contains additional luis information + this.deploymentSettingsPath = + (_e = config.deploymentSettingsPath) !== null && _e !== void 0 + ? _e + : path.join(this.publishFolder, 'appsettings.deployment.json'); + // path to the ARM template + // this is currently expected to live in the code project + this.templatePath = + (_f = config.templatePath) !== null && _f !== void 0 + ? _f + : path.join(this.projPath, 'DeploymentTemplates', 'template-with-preexisting-rg.json'); + // path to the dotnet project file + this.dotnetProjectPath = + (_g = config.dotnetProjectPath) !== null && _g !== void 0 + ? _g + : path.join(this.projPath, 'Microsoft.BotFramework.Composer.WebApp.csproj'); + // path to the built, ready to deploy declarative assets + this.remoteBotPath = + (_h = config.remoteBotPath) !== null && _h !== void 0 ? _h : path.join(this.publishFolder, 'ComposerDialogs'); + // path to the ready to deploy generated folder + this.generatedFolder = + (_j = config.generatedFolder) !== null && _j !== void 0 ? _j : path.join(this.remoteBotPath, 'generated'); + } + BotProjectDeploy.prototype.getErrorMesssage = function (err) { + if (err.body) { + if (err.body.error) { + if (err.body.error.details) { + var details = err.body.error.details; + var errMsg = ''; + for (var _i = 0, details_1 = details; _i < details_1.length; _i++) { + var detail = details_1[_i]; + errMsg += detail.message; + } + return errMsg; + } else { + return err.body.error.message; + } + } else { + return JSON.stringify(err.body, null, 2); + } + } else { + return JSON.stringify(err, null, 2); + } + }; + BotProjectDeploy.prototype.pack = function (scope) { + return { + value: scope, + }; + }; + /** + * For more information about this api, please refer to this doc: https://docs.microsoft.com/en-us/rest/api/resources/Tenants/List + */ + BotProjectDeploy.prototype.getTenantId = function () { + return __awaiter(this, void 0, void 0, function () { + var tenantUrl, options, response, jsonRes, err_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + 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.'); + } + _a.label = 1; + case 1: + _a.trys.push([1, 3, , 4]); + tenantUrl = 'https://management.azure.com/subscriptions/' + this.subId + '?api-version=2020-01-01'; + options = { + headers: { Authorization: 'Bearer ' + this.accessToken }, + }; + return [4 /*yield*/, rp.get(tenantUrl, options)]; + case 2: + response = _a.sent(); + jsonRes = JSON.parse(response); + if (jsonRes.tenantId === undefined) { + throw new Error('No tenants found in the account.'); + } + return [2 /*return*/, jsonRes.tenantId]; + case 3: + err_1 = _a.sent(); + throw new Error('Get Tenant Id Failed, details: ' + this.getErrorMesssage(err_1)); + case 4: + return [2 /*return*/]; + } + }); + }); + }; + BotProjectDeploy.prototype.unpackObject = function (output) { + var unpacked = {}; + for (var key in output) { + var objValue = output[key]; + if (objValue.value) { + unpacked[key] = objValue.value; + } + } + return unpacked; + }; + /** + * Format the parameters + */ + BotProjectDeploy.prototype.getDeploymentTemplateParam = function ( + appId, + appPwd, + location, + name, + shouldCreateAuthoringResource, + shouldCreateLuisResource, + useAppInsights, + useCosmosDb, + useStorage + ) { + return { + appId: this.pack(appId), + appSecret: this.pack(appPwd), + appServicePlanLocation: this.pack(location), + botId: this.pack(name), + shouldCreateAuthoringResource: this.pack(shouldCreateAuthoringResource), + shouldCreateLuisResource: this.pack(shouldCreateLuisResource), + useAppInsights: this.pack(useAppInsights), + useCosmosDb: this.pack(useCosmosDb), + useStorage: this.pack(useStorage), + }; + }; + BotProjectDeploy.prototype.readTemplateFile = function (templatePath) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [ + 2 /*return*/, + new Promise(function (resolve, reject) { + fs.readFile(templatePath, { encoding: 'utf-8' }, function (err, data) { + if (err) { + reject(err); + } + resolve(data); + }); + }), + ]; + }); + }); + }; + /*********************************************************************************************** + * Azure API accessors + **********************************************************************************************/ + /** + * Use the Azure API to create a new resource group + */ + BotProjectDeploy.prototype.createResourceGroup = function (client, location, resourceGroupName) { + return __awaiter(this, void 0, void 0, function () { + var param; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Creating resource group ...', + }); + param = { + location: location, + }; + return [4 /*yield*/, client.resourceGroups.createOrUpdate(resourceGroupName, param)]; + case 1: + return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + /** + * Validate the deployment using the Azure API + */ + BotProjectDeploy.prototype.validateDeployment = function ( + client, + templatePath, + location, + resourceGroupName, + deployName, + templateParam + ) { + return __awaiter(this, void 0, void 0, function () { + var templateFile, deployParam; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Validating Azure deployment ...', + }); + return [4 /*yield*/, this.readTemplateFile(templatePath)]; + case 1: + templateFile = _a.sent(); + deployParam = { + properties: { + template: JSON.parse(templateFile), + parameters: templateParam, + mode: 'Incremental', + }, + }; + return [4 /*yield*/, client.deployments.validate(resourceGroupName, deployName, deployParam)]; + case 2: + return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + /** + * Using an ARM template, provision a bunch of resources + */ + BotProjectDeploy.prototype.createDeployment = function ( + client, + templatePath, + location, + resourceGroupName, + deployName, + templateParam + ) { + return __awaiter(this, void 0, void 0, function () { + var templateFile, deployParam; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Deploying Azure services (this could take a while)...', + }); + return [4 /*yield*/, this.readTemplateFile(templatePath)]; + case 1: + templateFile = _a.sent(); + deployParam = { + properties: { + template: JSON.parse(templateFile), + parameters: templateParam, + mode: 'Incremental', + }, + }; + return [4 /*yield*/, client.deployments.createOrUpdate(resourceGroupName, deployName, deployParam)]; + case 2: + return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + BotProjectDeploy.prototype.createApp = function (graphClient, displayName, appPassword) { + return __awaiter(this, void 0, void 0, function () { + var createRes; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + graphClient.applications.create({ + displayName: displayName, + passwordCredentials: [ + { + value: appPassword, + startDate: new Date(), + endDate: new Date(new Date().setFullYear(new Date().getFullYear() + 2)), + }, + ], + availableToOtherTenants: true, + replyUrls: ['https://token.botframework.com/.auth/web/redirect'], + }), + ]; + case 1: + createRes = _a.sent(); + return [2 /*return*/, createRes]; + } + }); + }); + }; + /** + * Write updated settings back to the settings file + */ + BotProjectDeploy.prototype.updateDeploymentJsonFile = function ( + client, + resourceGroupName, + deployName, + appId, + appPwd + ) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var outputs, outputResult, applicationResult, outputObj, result; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + return [4 /*yield*/, client.deployments.get(resourceGroupName, deployName)]; + case 1: + outputs = _b.sent(); + if ( + (_a = outputs === null || outputs === void 0 ? void 0 : outputs.properties) === null || _a === void 0 + ? void 0 + : _a.outputs + ) { + outputResult = outputs.properties.outputs; + applicationResult = { + MicrosoftAppId: appId, + MicrosoftAppPassword: appPwd, + }; + outputObj = this.unpackObject(outputResult); + result = {}; + Object.assign(result, outputObj, applicationResult); + return [2 /*return*/, result]; + } else { + return [2 /*return*/, null]; + } + return [2 /*return*/]; + } + }); + }); + }; + BotProjectDeploy.prototype.getFiles = function (dir) { + return __awaiter(this, void 0, void 0, function () { + var dirents, files; + var _a; + var _this = this; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + return [4 /*yield*/, readdir(dir, { withFileTypes: true })]; + case 1: + dirents = _b.sent(); + return [ + 4 /*yield*/, + Promise.all( + dirents.map(function (dirent) { + var res = path.resolve(dir, dirent.name); + return dirent.isDirectory() ? _this.getFiles(res) : res; + }) + ), + ]; + case 2: + files = _b.sent(); + return [2 /*return*/, (_a = Array.prototype).concat.apply(_a, files)]; + } + }); + }); + }; + BotProjectDeploy.prototype.botPrepareDeploy = function (pathToDeploymentFile) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [ + 2 /*return*/, + new Promise(function (resolve, reject) { + var data = '[config]\nproject = Microsoft.BotFramework.Composer.WebApp.csproj'; + fs.writeFile(pathToDeploymentFile, data, function (err) { + if (err) { + reject(err); + } + resolve(); + }); + }), + ]; + }); + }); + }; + BotProjectDeploy.prototype.dotnetPublish = function (publishFolder, projFolder, botPath) { + return __awaiter(this, void 0, void 0, function () { + var remoteBotPath, localBotPath; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + // perform the dotnet publish command + // this builds the app and prepares it to be deployed + // results in a built copy in publishFolder/ + return [ + 4 /*yield*/, + exec('dotnet publish "' + this.dotnetProjectPath + '" -c release -o "' + publishFolder + '" -v q'), + ]; + case 1: + // perform the dotnet publish command + // this builds the app and prepares it to be deployed + // results in a built copy in publishFolder/ + _a.sent(); + remoteBotPath = path.join(publishFolder, 'ComposerDialogs'); + localBotPath = path.join(projFolder, 'ComposerDialogs'); + if (!botPath) return [3 /*break*/, 3]; + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Publishing dialogs from external bot project: ' + botPath, + }); + return [ + 4 /*yield*/, + fs.copy(botPath, remoteBotPath, { + overwrite: true, + recursive: true, + }), + ]; + case 2: + _a.sent(); + return [3 /*break*/, 5]; + case 3: + return [ + 4 /*yield*/, + fs.copy(localBotPath, remoteBotPath, { + overwrite: true, + recursive: true, + }), + ]; + case 4: + _a.sent(); + _a.label = 5; + case 5: + return [2 /*return*/]; + } + }); + }); + }; + BotProjectDeploy.prototype.zipDirectory = function (source, out) { + return __awaiter(this, void 0, void 0, function () { + var archive, stream; + return __generator(this, function (_a) { + archive = archiver('zip', { zlib: { level: 9 } }); + stream = fs.createWriteStream(out); + return [ + 2 /*return*/, + new Promise(function (resolve, reject) { + archive + .directory(source, false) + .on('error', function (err) { + return reject(err); + }) + .pipe(stream); + stream.on('close', function () { + return resolve(); + }); + archive.finalize(); + }), + ]; + }); + }); + }; + BotProjectDeploy.prototype.notEmptyLuisModel = function (file) { + return fs.readFileSync(file).length > 0; + }; + // Run through the lubuild process + // This happens in the build folder, NOT in the original source folder + BotProjectDeploy.prototype.publishLuis = function ( + name, + environment, + language, + luisEndpoint, + luisAuthoringEndpoint, + luisEndpointKey, + luisAuthoringKey, + luisAuthoringRegion, + luisResource + ) { + var _a, _b, _c, _d; + return __awaiter(this, void 0, void 0, function () { + var botFiles, + modelFiles, + builder, + loadResult, + buildResult, + luisConfigFiles, + luisAppIds, + _i, + luisConfigFiles_1, + luisConfigFile, + luisSettings, + luisConfig, + settings, + jsonRes, + getAccountUri, + options, + response, + err_2, + error, + account, + _e, + _f, + _g, + k, + luisAppId, + luisAssignEndpoint, + options, + response; + var _this = this; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + if (!(luisAuthoringKey && luisAuthoringRegion)) return [3 /*break*/, 23]; + return [4 /*yield*/, this.getFiles(this.remoteBotPath)]; + case 1: + botFiles = _h.sent(); + modelFiles = botFiles.filter(function (name) { + return name.endsWith('.lu') && _this.notEmptyLuisModel(name); + }); + return [4 /*yield*/, fs.pathExists(this.generatedFolder)]; + case 2: + if (!!_h.sent()) return [3 /*break*/, 4]; + return [4 /*yield*/, fs.mkdir(this.generatedFolder)]; + case 3: + _h.sent(); + _h.label = 4; + case 4: + builder = new luBuild.Builder(function (msg) { + return _this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: msg, + }); + }); + return [ + 4 /*yield*/, + builder.loadContents(modelFiles, language || '', environment || '', luisAuthoringRegion || ''), + ]; + case 5: + loadResult = _h.sent(); + if (!luisEndpoint) { + luisEndpoint = 'https://' + luisAuthoringRegion + '.api.cognitive.microsoft.com'; + } + if (!luisAuthoringEndpoint) { + luisAuthoringEndpoint = luisEndpoint; + } + return [ + 4 /*yield*/, + builder.build( + loadResult.luContents, + loadResult.recognizers, + luisAuthoringKey, + luisAuthoringEndpoint, + name, + environment, + language, + false, + loadResult.multiRecognizers, + loadResult.settings + ), + ]; + case 6: + buildResult = _h.sent(); + return [4 /*yield*/, builder.writeDialogAssets(buildResult, true, this.generatedFolder)]; + case 7: + _h.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'lubuild succeed', + }); + return [4 /*yield*/, this.getFiles(this.remoteBotPath)]; + case 8: + luisConfigFiles = _h.sent().filter(function (filename) { + return filename.includes('luis.settings'); + }); + luisAppIds = {}; + (_i = 0), (luisConfigFiles_1 = luisConfigFiles); + _h.label = 9; + case 9: + if (!(_i < luisConfigFiles_1.length)) return [3 /*break*/, 12]; + luisConfigFile = luisConfigFiles_1[_i]; + return [4 /*yield*/, fs.readJson(luisConfigFile)]; + case 10: + luisSettings = _h.sent(); + Object.assign(luisAppIds, luisSettings.luis); + _h.label = 11; + case 11: + _i++; + return [3 /*break*/, 9]; + case 12: + luisConfig = { + endpoint: luisEndpoint, + endpointKey: luisEndpointKey, + authoringRegion: luisAuthoringRegion, + authoringKey: luisAuthoringRegion, + }; + Object.assign(luisConfig, luisAppIds); + return [4 /*yield*/, fs.readJson(this.deploymentSettingsPath)]; + case 13: + settings = _h.sent(); + settings.luis = luisConfig; + return [ + 4 /*yield*/, + fs.writeJson(this.deploymentSettingsPath, settings, { + spaces: 4, + }), + ]; + case 14: + _h.sent(); + jsonRes = void 0; + _h.label = 15; + case 15: + _h.trys.push([15, 17, , 18]); + getAccountUri = luisEndpoint + '/luis/api/v2.0/azureaccounts'; + options = { + headers: { Authorization: 'Bearer ' + this.accessToken, 'Ocp-Apim-Subscription-Key': luisAuthoringKey }, + }; + return [4 /*yield*/, rp.get(getAccountUri, options)]; + case 16: + response = _h.sent(); + jsonRes = JSON.parse(response); + return [3 /*break*/, 18]; + case 17: + err_2 = _h.sent(); + error = JSON.parse(err_2.error); + if ( + ((_a = error === null || error === void 0 ? void 0 : error.error) === null || _a === void 0 + ? void 0 + : _a.message) && + ((_b = error === null || error === void 0 ? void 0 : error.error) === null || _b === void 0 + ? void 0 + : _b.message.indexOf('access token expiry')) > 0 + ) { + throw new Error( + 'Type: ' + + ((_c = error === null || error === void 0 ? void 0 : error.error) === null || _c === void 0 + ? void 0 + : _c.code) + + ', Message: ' + + ((_d = error === null || error === void 0 ? void 0 : error.error) === null || _d === void 0 + ? void 0 + : _d.message) + + ', run az account get-access-token, then replace the accessToken in your configuration' + ); + } else { + throw err_2; + } + return [3 /*break*/, 18]; + case 18: + account = this.getAccount(jsonRes, luisResource ? luisResource : name + '-' + environment + '-luis'); + _e = []; + for (_f in luisAppIds) _e.push(_f); + _g = 0; + _h.label = 19; + case 19: + if (!(_g < _e.length)) return [3 /*break*/, 22]; + k = _e[_g]; + luisAppId = luisAppIds[k]; + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Assigning to luis app id: ' + luisAppId, + }); + luisAssignEndpoint = luisEndpoint + '/luis/api/v2.0/apps/' + luisAppId + '/azureaccounts'; + options = { + body: account, + json: true, + headers: { Authorization: 'Bearer ' + this.accessToken, 'Ocp-Apim-Subscription-Key': luisAuthoringKey }, + }; + return [4 /*yield*/, rp.post(luisAssignEndpoint, options)]; + case 20: + response = _h.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: response, + }); + _h.label = 21; + case 21: + _g++; + return [3 /*break*/, 19]; + case 22: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Luis Publish Success! ...', + }); + _h.label = 23; + case 23: + return [2 /*return*/]; + } + }); + }); + }; + /** + * Deploy a bot to a location + */ + BotProjectDeploy.prototype.deploy = function ( + name, + environment, + luisAuthoringKey, + luisAuthoringRegion, + botPath, + language, + hostname, + luisResource + ) { + return __awaiter(this, void 0, void 0, function () { + var settings, luisSettings, luisEndpointKey, luisEndpoint, luisAuthoringEndpoint, error_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 11, , 12]); + if (!!fs.pathExistsSync(this.deployFilePath)) return [3 /*break*/, 2]; + return [4 /*yield*/, this.botPrepareDeploy(this.deployFilePath)]; + case 1: + _a.sent(); + _a.label = 2; + case 2: + return [4 /*yield*/, fs.pathExists(this.zipPath)]; + case 3: + if (!_a.sent()) return [3 /*break*/, 5]; + return [4 /*yield*/, fs.remove(this.zipPath)]; + case 4: + _a.sent(); + _a.label = 5; + case 5: + // dotnet publish + return [4 /*yield*/, this.dotnetPublish(this.publishFolder, this.projPath, botPath)]; + case 6: + // dotnet publish + _a.sent(); + return [4 /*yield*/, fs.readJSON(this.settingsPath)]; + case 7: + settings = _a.sent(); + luisSettings = settings.luis; + luisEndpointKey = ''; + luisEndpoint = ''; + 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'; + } + return [ + 4 /*yield*/, + this.publishLuis( + name, + environment, + language, + luisEndpoint, + luisAuthoringEndpoint, + luisEndpointKey, + luisAuthoringKey, + luisAuthoringRegion, + luisResource + ), + ]; + case 8: + _a.sent(); + // Build a zip file of the project + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Packing up the bot service ...', + }); + return [4 /*yield*/, this.zipDirectory(this.publishFolder, this.zipPath)]; + case 9: + _a.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Packing Service Success!', + }); + // Deploy the zip file to the web app + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Publishing to Azure ...', + }); + return [4 /*yield*/, this.deployZip(this.accessToken, this.zipPath, name, environment, hostname)]; + case 10: + _a.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_SUCCESS, + message: 'Publish To Azure Success!', + }); + return [3 /*break*/, 12]; + case 11: + error_1 = _a.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_ERROR, + message: JSON.stringify(error_1, Object.getOwnPropertyNames(error_1)), + }); + throw error_1; + case 12: + return [2 /*return*/]; + } + }); + }); + }; + BotProjectDeploy.prototype.getAccount = function (accounts, filter) { + for (var _i = 0, accounts_1 = accounts; _i < accounts_1.length; _i++) { + var account = accounts_1[_i]; + if (account.AccountName === filter) { + return account; + } + } + }; + // Upload the zip file to Azure + BotProjectDeploy.prototype.deployZip = function (token, zipPath, name, env, hostname) { + return __awaiter(this, void 0, void 0, function () { + var publishEndpoint, fileContent, options, response, err_3; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: 'Retrieve publishing details ...', + }); + publishEndpoint = + 'https://' + (hostname ? hostname : name + '-' + env) + '.scm.azurewebsites.net/zipdeploy'; + return [4 /*yield*/, fs.readFile(zipPath)]; + case 1: + fileContent = _a.sent(); + options = { + body: fileContent, + encoding: null, + headers: { + Authorization: 'Bearer ' + token, + 'Content-Type': 'application/zip', + 'Content-Length': fileContent.length, + }, + }; + _a.label = 2; + case 2: + _a.trys.push([2, 4, , 5]); + return [4 /*yield*/, rp.post(publishEndpoint, options)]; + case 3: + response = _a.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.DEPLOY_INFO, + message: response, + }); + return [3 /*break*/, 5]; + case 4: + err_3 = _a.sent(); + if (err_3.statusCode === 403) { + throw new Error( + 'Token expired, please run az account get-access-token, then replace the accessToken in your configuration' + ); + } else { + throw err_3; + } + return [3 /*break*/, 5]; + case 5: + return [2 /*return*/]; + } + }); + }); + }; + /** + * Provision a set of Azure resources for use with a bot + */ + BotProjectDeploy.prototype.create = function ( + name, + location, + environment, + appPassword, + createLuisResource, + createLuisAuthoringResource, + createCosmosDb, + createStorage, + createAppInsights + ) { + if (createLuisResource === void 0) { + createLuisResource = true; + } + if (createLuisAuthoringResource === void 0) { + createLuisAuthoringResource = true; + } + if (createCosmosDb === void 0) { + createCosmosDb = true; + } + if (createStorage === void 0) { + createStorage = true; + } + if (createAppInsights === void 0) { + createAppInsights = true; + } + return __awaiter(this, void 0, void 0, function () { + var _a, + graphCreds, + graphClient, + settings, + appId, + appCreated, + resourceGroupName, + timeStamp, + client, + rpres, + deploymentTemplateParam, + validation, + deployment, + appinsightsClient, + appComponents, + appinsightsId, + appinsightsInstrumentationKey, + apiKeyOptions, + appinsightsApiKeyResponse, + appinsightsApiKey, + botServiceClient, + botCreated, + botUpdateResult, + updateResult, + operations, + failedOperations; + var _this = this; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + if (!!this.tenantId) return [3 /*break*/, 2]; + _a = this; + return [4 /*yield*/, this.getTenantId()]; + case 1: + _a.tenantId = _b.sent(); + _b.label = 2; + case 2: + graphCreds = new ms_rest_nodeauth_1.DeviceTokenCredentials( + this.creds.clientId, + this.tenantId, + this.creds.username, + 'graph', + this.creds.environment, + this.creds.tokenCache + ); + graphClient = new graph_1.GraphRbacManagementClient(graphCreds, this.tenantId, { + baseUri: 'https://graph.windows.net', + }); + settings = {}; + if (!fs.existsSync(this.settingsPath)) return [3 /*break*/, 4]; + return [4 /*yield*/, fs.readJson(this.settingsPath)]; + case 3: + settings = _b.sent(); + _b.label = 4; + case 4: + appId = settings.MicrosoftAppId; + if (!!appId) return [3 /*break*/, 6]; + // this requires an app password. if one not specified, fail. + if (!appPassword) { + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: 'App password is required', + }); + throw new Error('App password is required'); + } + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Creating App Registration ...', + }); + return [4 /*yield*/, this.createApp(graphClient, name, appPassword)]; + case 5: + appCreated = _b.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: appCreated, + }); + // use the newly created app + appId = appCreated.appId; + _b.label = 6; + case 6: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Create App Id Success! ID: ' + appId, + }); + resourceGroupName = name + '-' + environment; + timeStamp = new Date().getTime().toString(); + client = new arm_resources_1.ResourceManagementClient(this.creds, this.subId); + return [4 /*yield*/, this.createResourceGroup(client, location, resourceGroupName)]; + case 7: + rpres = _b.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: rpres, + }); + deploymentTemplateParam = this.getDeploymentTemplateParam( + appId, + appPassword, + location, + name, + createLuisAuthoringResource, + createLuisResource, + createAppInsights, + createCosmosDb, + createStorage + ); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: deploymentTemplateParam, + }); + return [ + 4 /*yield*/, + this.validateDeployment( + client, + this.templatePath, + location, + resourceGroupName, + timeStamp, + deploymentTemplateParam + ), + ]; + case 8: + validation = _b.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: validation, + }); + // Handle validation errors + if (validation.error) { + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: '! Template is not valid with provided parameters. Review the log for more information.', + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: '! Error: ' + validation.error.message, + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + "+ To delete this resource group, run 'az group delete -g " + resourceGroupName + " --no-wait'", + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR_DETAILS, + message: validation.error.details, + }); + throw new Error('! Error: ' + validation.error.message); + } + return [ + 4 /*yield*/, + this.createDeployment( + client, + this.templatePath, + location, + resourceGroupName, + timeStamp, + deploymentTemplateParam + ), + ]; + case 9: + deployment = _b.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: deployment, + }); + // Handle errors + if (deployment._response.status != 200) { + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: '! Template is not valid with provided parameters. Review the log for more information.', + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: '! Error: ' + validation.error, + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + "+ To delete this resource group, run 'az group delete -g " + resourceGroupName + " --no-wait'", + }); + throw new Error('! Error: ' + validation.error); + } + if (!createAppInsights) return [3 /*break*/, 15]; + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Linking Application Insights settings to Bot Service ...', + }); + appinsightsClient = new arm_appinsights_1.ApplicationInsightsManagementClient(this.creds, this.subId); + return [4 /*yield*/, appinsightsClient.components.get(resourceGroupName, resourceGroupName)]; + case 10: + appComponents = _b.sent(); + appinsightsId = appComponents.appId; + appinsightsInstrumentationKey = appComponents.instrumentationKey; + apiKeyOptions = { + name: resourceGroupName + '-provision-' + timeStamp, + linkedReadProperties: [ + '/subscriptions/' + + this.subId + + '/resourceGroups/' + + resourceGroupName + + '/providers/microsoft.insights/components/' + + resourceGroupName + + '/api', + '/subscriptions/' + + this.subId + + '/resourceGroups/' + + resourceGroupName + + '/providers/microsoft.insights/components/' + + resourceGroupName + + '/agentconfig', + ], + linkedWriteProperties: [ + '/subscriptions/' + + this.subId + + '/resourceGroups/' + + resourceGroupName + + '/providers/microsoft.insights/components/' + + resourceGroupName + + '/annotations', + ], + }; + return [4 /*yield*/, appinsightsClient.aPIKeys.create(resourceGroupName, resourceGroupName, apiKeyOptions)]; + case 11: + appinsightsApiKeyResponse = _b.sent(); + appinsightsApiKey = appinsightsApiKeyResponse.apiKey; + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> AppInsights AppId: ' + appinsightsId + ' ...', + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> AppInsights InstrumentationKey: ' + appinsightsInstrumentationKey + ' ...', + }); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> AppInsights ApiKey: ' + appinsightsApiKey + ' ...', + }); + if (!(appinsightsId && appinsightsInstrumentationKey && appinsightsApiKey)) return [3 /*break*/, 15]; + botServiceClient = new arm_botservice_1.AzureBotService(this.creds, this.subId); + return [4 /*yield*/, botServiceClient.bots.get(resourceGroupName, name)]; + case 12: + botCreated = _b.sent(); + if (!botCreated.properties) return [3 /*break*/, 14]; + botCreated.properties.developerAppInsightKey = appinsightsInstrumentationKey; + botCreated.properties.developerAppInsightsApiKey = appinsightsApiKey; + botCreated.properties.developerAppInsightsApplicationId = appinsightsId; + return [4 /*yield*/, botServiceClient.bots.update(resourceGroupName, name, botCreated)]; + case 13: + botUpdateResult = _b.sent(); + if (botUpdateResult._response.status != 200) { + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + '! Something went wrong while trying to link Application Insights settings to Bot Service Result: ' + + JSON.stringify(botUpdateResult), + }); + throw new Error('Linking Application Insights Failed.'); + } + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: '> Linking Application Insights settings to Bot Service Success!', + }); + return [3 /*break*/, 15]; + case 14: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_WARNING, + message: "! The Bot doesn't have a keys properties to update.", + }); + _b.label = 15; + case 15: + return [ + 4 /*yield*/, + this.updateDeploymentJsonFile(client, resourceGroupName, timeStamp, appId, appPassword), + ]; + case 16: + updateResult = _b.sent(); + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_INFO, + message: updateResult, + }); + if (!!updateResult) return [3 /*break*/, 18]; + return [4 /*yield*/, client.deploymentOperations.list(resourceGroupName, timeStamp)]; + case 17: + operations = _b.sent(); + if (operations) { + failedOperations = operations.filter(function (value) { + var _a; + return ( + ((_a = value === null || value === void 0 ? void 0 : value.properties) === null || _a === void 0 + ? void 0 + : _a.statusMessage.error) !== null + ); + }); + if (failedOperations) { + failedOperations.forEach(function (operation) { + var _a, _b, _c, _d, _e, _f, _g; + switch ( + (_a = operation === null || operation === void 0 ? void 0 : operation.properties) === null || + _a === void 0 + ? void 0 + : _a.statusMessage.error.code + ) { + case 'MissingRegistrationForLocation': + _this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + '! Deployment failed for resource of type ' + + ((_c = + (_b = operation === null || operation === void 0 ? void 0 : operation.properties) === + null || _b === void 0 + ? void 0 + : _b.targetResource) === null || _c === void 0 + ? void 0 + : _c.resourceType) + + '. This resource is not avaliable in the location provided.', + }); + break; + default: + _this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + '! Deployment failed for resource of type ' + + ((_e = + (_d = operation === null || operation === void 0 ? void 0 : operation.properties) === + null || _d === void 0 + ? void 0 + : _d.targetResource) === null || _e === void 0 + ? void 0 + : _e.resourceType) + + '.', + }); + _this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + '! Code: ' + + ((_f = operation === null || operation === void 0 ? void 0 : operation.properties) === null || + _f === void 0 + ? void 0 + : _f.statusMessage.error.code) + + '.', + }); + _this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: + '! Message: ' + + ((_g = operation === null || operation === void 0 ? void 0 : operation.properties) === null || + _g === void 0 + ? void 0 + : _g.statusMessage.error.message) + + '.', + }); + break; + } + }); + } + } else { + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_ERROR, + message: '! Deployment failed. Please refer to the log file for more information.', + }); + } + _b.label = 18; + case 18: + this.logger({ + status: botProjectLoggerType_1.BotProjectDeployLoggerType.PROVISION_SUCCESS, + message: "+ To delete this resource group, run 'az group delete -g " + resourceGroupName + " --no-wait'", + }); + return [2 /*return*/, updateResult]; + } + }); + }); + }; + /** + * createAndDeploy + * provision the Azure resources AND deploy a bot to those resources + */ + BotProjectDeploy.prototype.createAndDeploy = function ( + name, + location, + environment, + appPassword, + luisAuthoringKey, + luisAuthoringRegion + ) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + return [4 /*yield*/, this.create(name, location, environment, appPassword)]; + case 1: + _a.sent(); + return [4 /*yield*/, this.deploy(name, environment, luisAuthoringKey, luisAuthoringRegion)]; + case 2: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }; + return BotProjectDeploy; +})(); +exports.BotProjectDeploy = BotProjectDeploy; +//# sourceMappingURL=botProjectDeploy.js.map diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js.map b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js.map new file mode 100644 index 0000000000..4ec7e3a51b --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeploy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"botProjectDeploy.js","sourceRoot":"","sources":["../src/botProjectDeploy.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts new file mode 100644 index 0000000000..36ae3defe4 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts @@ -0,0 +1,18 @@ +export interface BotProjectDeployConfig { + subId: string; + creds?: any; + accessToken: string; + projPath: string; + logger: (string: any) => any; + deploymentSettingsPath?: string; + deployFilePath?: string; + zipPath?: string; + publishFolder?: string; + settingsPath?: string; + templatePath?: string; + dotnetProjectPath?: string; + generatedFolder?: string; + remoteBotPath?: string; + [key: string]: any; +} +//# sourceMappingURL=botProjectDeployConfig.d.ts.map diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts.map b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts.map new file mode 100644 index 0000000000..2d3c67287f --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"botProjectDeployConfig.d.ts","sourceRoot":"","sources":["../src/botProjectDeployConfig.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IAErC,KAAK,EAAE,MAAM,CAAC;IAGd,KAAK,CAAC,EAAE,GAAG,CAAC;IAGZ,WAAW,EAAE,MAAM,CAAC;IAGpB,QAAQ,EAAE,MAAM,CAAC;IAGjB,MAAM,EAAE,CAAC,MAAM,KAAA,KAAK,GAAG,CAAC;IAGxB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAGhC,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js new file mode 100644 index 0000000000..74b8985e9b --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js @@ -0,0 +1,5 @@ +'use strict'; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +Object.defineProperty(exports, '__esModule', { value: true }); +//# sourceMappingURL=botProjectDeployConfig.js.map diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js.map b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js.map new file mode 100644 index 0000000000..9effcf7a5d --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectDeployConfig.js.map @@ -0,0 +1 @@ +{"version":3,"file":"botProjectDeployConfig.js","sourceRoot":"","sources":["../src/botProjectDeployConfig.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts new file mode 100644 index 0000000000..51db3c6ca8 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts @@ -0,0 +1,12 @@ +export declare enum BotProjectDeployLoggerType { + PROVISION_INFO = 'PROVISION_INFO', + PROVISION_ERROR = 'PROVISION_ERROR', + PROVISION_WARNING = 'PROVISION_WARNING', + PROVISION_SUCCESS = 'PROVISION_SUCCESS', + PROVISION_ERROR_DETAILS = 'PROVISION_ERROR_DETAILS', + DEPLOY_INFO = 'DEPLOY_INFO', + DEPLOY_ERROR = 'DEPLOY_ERROR', + DEPLOY_WARNING = 'DEPLOY_WARNING', + DEPLOY_SUCCESS = 'DEPLOY_SUCCESS', +} +//# sourceMappingURL=botProjectLoggerType.d.ts.map diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts.map b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts.map new file mode 100644 index 0000000000..166d9118c1 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"botProjectLoggerType.d.ts","sourceRoot":"","sources":["../src/botProjectLoggerType.ts"],"names":[],"mappings":"AAGA,oBAAY,0BAA0B;IAEpC,cAAc,mBAAmB;IACjC,eAAe,oBAAoB;IACnC,iBAAiB,sBAAsB;IACvC,iBAAiB,sBAAsB;IACvC,uBAAuB,4BAA4B;IAGnD,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;CAClC"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js new file mode 100644 index 0000000000..906cadf2fb --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js @@ -0,0 +1,20 @@ +'use strict'; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +Object.defineProperty(exports, '__esModule', { value: true }); +exports.BotProjectDeployLoggerType = void 0; +var BotProjectDeployLoggerType; +(function (BotProjectDeployLoggerType) { + // Logger Type for Provision + BotProjectDeployLoggerType['PROVISION_INFO'] = 'PROVISION_INFO'; + BotProjectDeployLoggerType['PROVISION_ERROR'] = 'PROVISION_ERROR'; + BotProjectDeployLoggerType['PROVISION_WARNING'] = 'PROVISION_WARNING'; + BotProjectDeployLoggerType['PROVISION_SUCCESS'] = 'PROVISION_SUCCESS'; + BotProjectDeployLoggerType['PROVISION_ERROR_DETAILS'] = 'PROVISION_ERROR_DETAILS'; + // Logger Type for Deploy + BotProjectDeployLoggerType['DEPLOY_INFO'] = 'DEPLOY_INFO'; + BotProjectDeployLoggerType['DEPLOY_ERROR'] = 'DEPLOY_ERROR'; + BotProjectDeployLoggerType['DEPLOY_WARNING'] = 'DEPLOY_WARNING'; + BotProjectDeployLoggerType['DEPLOY_SUCCESS'] = 'DEPLOY_SUCCESS'; +})((BotProjectDeployLoggerType = exports.BotProjectDeployLoggerType || (exports.BotProjectDeployLoggerType = {}))); +//# sourceMappingURL=botProjectLoggerType.js.map diff --git a/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js.map b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js.map new file mode 100644 index 0000000000..46f8903ee9 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/botProjectLoggerType.js.map @@ -0,0 +1 @@ +{"version":3,"file":"botProjectLoggerType.js","sourceRoot":"","sources":["../src/botProjectLoggerType.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAElC,IAAY,0BAaX;AAbD,WAAY,0BAA0B;IACpC,4BAA4B;IAC5B,+DAAiC,CAAA;IACjC,iEAAmC,CAAA;IACnC,qEAAuC,CAAA;IACvC,qEAAuC,CAAA;IACvC,iFAAmD,CAAA;IAEnD,yBAAyB;IACzB,yDAA2B,CAAA;IAC3B,2DAA6B,CAAA;IAC7B,+DAAiC,CAAA;IACjC,+DAAiC,CAAA;AACnC,CAAC,EAbW,0BAA0B,GAA1B,kCAA0B,KAA1B,kCAA0B,QAarC"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/src/index.ts b/Composer/packages/lib/bot-deploy/lib/index.d.ts similarity index 50% rename from Composer/packages/lib/bot-deploy/src/index.ts rename to Composer/packages/lib/bot-deploy/lib/index.d.ts index 2837f239ce..dddfc7f382 100644 --- a/Composer/packages/lib/bot-deploy/src/index.ts +++ b/Composer/packages/lib/bot-deploy/lib/index.d.ts @@ -1,7 +1,4 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - export * from './botProjectDeploy'; export * from './botProjectDeployConfig'; export * from './botProjectLoggerType'; -export * from './botProjectRuntimeType'; +//# sourceMappingURL=index.d.ts.map diff --git a/Composer/packages/lib/bot-deploy/lib/index.d.ts.map b/Composer/packages/lib/bot-deploy/lib/index.d.ts.map new file mode 100644 index 0000000000..8530f5cc1d --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/lib/index.js b/Composer/packages/lib/bot-deploy/lib/index.js new file mode 100644 index 0000000000..212888471c --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/index.js @@ -0,0 +1,29 @@ +'use strict'; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +var __createBinding = + (this && this.__createBinding) || + (Object.create + ? function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { + enumerable: true, + get: function () { + return m[k]; + }, + }); + } + : function (o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + }); +var __exportStar = + (this && this.__exportStar) || + function (m, exports) { + for (var p in m) if (p !== 'default' && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); + }; +Object.defineProperty(exports, '__esModule', { value: true }); +__exportStar(require('./botProjectDeploy'), exports); +__exportStar(require('./botProjectDeployConfig'), exports); +__exportStar(require('./botProjectLoggerType'), exports); +//# sourceMappingURL=index.js.map diff --git a/Composer/packages/lib/bot-deploy/lib/index.js.map b/Composer/packages/lib/bot-deploy/lib/index.js.map new file mode 100644 index 0000000000..0c7e7cb2e0 --- /dev/null +++ b/Composer/packages/lib/bot-deploy/lib/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;;;;;;;;;;AAElC,qDAAmC;AACnC,2DAAyC;AACzC,yDAAuC"} \ No newline at end of file diff --git a/Composer/packages/lib/bot-deploy/package.json b/Composer/packages/lib/bot-deploy/package.json deleted file mode 100644 index b34dc3f025..0000000000 --- a/Composer/packages/lib/bot-deploy/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "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-preview.141651", - "@microsoft/bf-luis-cli": "^4.10.0-preview.141651", - "@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/packages/lib/bot-deploy/tsconfig.json b/Composer/packages/lib/bot-deploy/tsconfig.json deleted file mode 100644 index 7da2b5f30b..0000000000 --- a/Composer/packages/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/packages/lib/indexers/__tests__/validations/expressionValidation.test.ts b/Composer/packages/lib/indexers/__tests__/validations/expressionValidation.test.ts index b064d76fc4..2caef95c2f 100644 --- a/Composer/packages/lib/indexers/__tests__/validations/expressionValidation.test.ts +++ b/Composer/packages/lib/indexers/__tests__/validations/expressionValidation.test.ts @@ -13,6 +13,9 @@ describe('search lg custom function', () => { expect(result.length).toEqual(2); expect(result[0]).toEqual('foo.bar'); expect(result[1]).toEqual('foo.cool'); + const lgFilesWithoutOptions = [{ id: 'test.en-us' }]; + const result1 = searchLgCustomFunction(lgFilesWithoutOptions as LgFile[]); + expect(result1.length).toEqual(0); }); it('should return custom functions with namespace', () => { diff --git a/Composer/packages/lib/indexers/src/validations/expressionValidation/index.ts b/Composer/packages/lib/indexers/src/validations/expressionValidation/index.ts index 3ba6eeabda..aee180ce76 100644 --- a/Composer/packages/lib/indexers/src/validations/expressionValidation/index.ts +++ b/Composer/packages/lib/indexers/src/validations/expressionValidation/index.ts @@ -15,16 +15,17 @@ const ExportsKey = '@exports'; export const searchLgCustomFunction = (lgFiles: LgFile[]): string[] => { const customFunctions = lgFiles.reduce((result: string[], lgFile) => { const { options } = lgFile; - const exports = extractOptionByKey(ExportsKey, options); - let namespace = extractOptionByKey(NamespaceKey, options); - if (!namespace) namespace = lgFile.id; //if namespace doesn't exist, use file name - const funcList = exports.split(','); - funcList.forEach((func) => { - if (func) { - result.push(`${namespace}.${func.trim()}`); - } - }); - + if (options?.length) { + const exports = extractOptionByKey(ExportsKey, options); + let namespace = extractOptionByKey(NamespaceKey, options); + if (!namespace) namespace = lgFile.id; //if namespace doesn't exist, use file name + const funcList = exports.split(','); + funcList.forEach((func) => { + if (func) { + result.push(`${namespace}.${func.trim()}`); + } + }); + } return result; }, []); return customFunctions; diff --git a/Composer/packages/lib/package.json b/Composer/packages/lib/package.json index 8102f63a5f..fbe53b233b 100644 --- a/Composer/packages/lib/package.json +++ b/Composer/packages/lib/package.json @@ -11,8 +11,7 @@ "build:shared": "cd shared && yarn build", "build:indexers": "cd indexers && yarn build", "build:uishared": "cd ui-shared && yarn build", - "build:bot-deploy": "cd bot-deploy && yarn build", - "build:all": "yarn build:shared && yarn build:indexers && yarn build:code-editor && yarn build:uishared && yarn build:bot-deploy" + "build:all": "yarn build:shared && yarn build:indexers && yarn build:code-editor && yarn build:uishared" }, "author": "", "license": "ISC" diff --git a/Composer/packages/lib/shared/src/types/indexers.ts b/Composer/packages/lib/shared/src/types/indexers.ts index be850e6843..2232466237 100644 --- a/Composer/packages/lib/shared/src/types/indexers.ts +++ b/Composer/packages/lib/shared/src/types/indexers.ts @@ -107,7 +107,7 @@ export interface LgFile { content: string; diagnostics: Diagnostic[]; templates: LgTemplate[]; - options: string[]; + options?: string[]; } export interface Skill { diff --git a/Composer/packages/server/__tests__/controllers/project.test.ts b/Composer/packages/server/__tests__/controllers/project.test.ts index 336880075b..19facabae8 100644 --- a/Composer/packages/server/__tests__/controllers/project.test.ts +++ b/Composer/packages/server/__tests__/controllers/project.test.ts @@ -84,7 +84,7 @@ describe('get bot project', () => { await ProjectController.getProjectById(mockReq, mockRes); expect(mockRes.status).toHaveBeenCalledWith(404); expect(mockRes.json).toHaveBeenCalledWith({ - message: 'project not found in cache', + message: 'project undefined not found in cache', }); }); @@ -121,7 +121,7 @@ describe('open bot operation', () => { await ProjectController.openProject(mockReq, mockRes); expect(mockRes.status).toHaveBeenCalledWith(400); expect(mockRes.json).toHaveBeenCalledWith({ - message: 'file not exist wrong/path', + message: 'file wrong/path does not exist', }); }); diff --git a/Composer/packages/server/__tests__/services/project.test.ts b/Composer/packages/server/__tests__/services/project.test.ts index d2771a4cd6..088212e577 100644 --- a/Composer/packages/server/__tests__/services/project.test.ts +++ b/Composer/packages/server/__tests__/services/project.test.ts @@ -61,7 +61,10 @@ afterAll(() => { describe('test BotProjectService', () => { it('openProject', async () => { const projectId = await BotProjectService.openProject(location1); - await expect(BotProjectService.getProjectById('123')).rejects.toThrowError('project not found in cache'); + const otherId = '12345.678'; + await expect(BotProjectService.getProjectById(otherId)).rejects.toThrowError( + `project ${otherId} not found in cache` + ); expect((await BotProjectService.getProjectById(projectId)).dir).toBe(projPath); }); diff --git a/Composer/packages/server/src/controllers/publisher.ts b/Composer/packages/server/src/controllers/publisher.ts index ff6a849af8..698b4d44c6 100644 --- a/Composer/packages/server/src/controllers/publisher.ts +++ b/Composer/packages/server/src/controllers/publisher.ts @@ -54,12 +54,15 @@ export const PublishController = { const profile = profiles.length ? profiles[0] : undefined; const method = profile ? profile.type : undefined; + const runtime = pluginLoader.getRuntimeByProject(currentProject); + const pathToRuntime = runtime.path; + if (profile && 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), + templatePath: pathToRuntime, ...JSON.parse(profile.configuration), }; diff --git a/Composer/packages/server/src/models/settings/defaultSettingManager.ts b/Composer/packages/server/src/models/settings/defaultSettingManager.ts index d6f4be2d8f..9ad61de633 100644 --- a/Composer/packages/server/src/models/settings/defaultSettingManager.ts +++ b/Composer/packages/server/src/models/settings/defaultSettingManager.ts @@ -4,7 +4,6 @@ import set from 'lodash/set'; import { SensitiveProperties } from '@bfc/shared'; import { UserIdentity } from '@bfc/plugin-loader'; -import { pluginLoader } from '@bfc/plugin-loader'; import { Path } from '../../utility/path'; import log from '../../logger'; @@ -61,7 +60,6 @@ export class DefaultSettingManager extends FileSettingManager { }, runtime: { customRuntime: false, - name: pluginLoader.extensions.runtimeTemplates[0]?.name, path: '', command: '', }, diff --git a/Composer/packages/server/src/services/project.ts b/Composer/packages/server/src/services/project.ts index 1439777a07..3a81e05629 100644 --- a/Composer/packages/server/src/services/project.ts +++ b/Composer/packages/server/src/services/project.ts @@ -152,7 +152,7 @@ export class BotProjectService { // TODO: this should be refactored or moved into the BotProject constructor so that it can use user auth amongst other things if (!(await StorageService.checkBlob(locationRef.storageId, locationRef.path, user))) { BotProjectService.deleteRecentProject(locationRef.path); - throw new Error(`file not exist ${locationRef.path}`); + throw new Error(`file ${locationRef.path} does not exist`); } for (const key in BotProjectService.projectLocationMap) { @@ -209,15 +209,16 @@ export class BotProjectService { public static getProjectById = async (projectId: string, user?: UserIdentity): Promise => { BotProjectService.initialize(); - if (!BotProjectService.projectLocationMap?.[projectId]) { - throw new Error('project not found in cache'); + const path = BotProjectService.projectLocationMap[projectId]; + + if (path == null) { + throw new Error(`project ${projectId} not found in cache`); } else { - const path = BotProjectService.projectLocationMap[projectId]; // check to make sure the project is still there! if (!(await StorageService.checkBlob('default', path, user))) { BotProjectService.deleteRecentProject(path); BotProjectService.removeProjectIdFromCache(projectId); - throw new Error(`file not exist ${path}`); + throw new Error(`file ${path} does not exist`); } const project = new BotProject({ storageId: 'default', path: path }, user); await project.init(); diff --git a/Composer/packages/tools/language-servers/language-generation/src/lgParser.ts b/Composer/packages/tools/language-servers/language-generation/src/lgParser.ts index 9a2621802d..07a597bd6b 100644 --- a/Composer/packages/tools/language-servers/language-generation/src/lgParser.ts +++ b/Composer/packages/tools/language-servers/language-generation/src/lgParser.ts @@ -4,28 +4,51 @@ import { fork, ChildProcess } from 'child_process'; import path from 'path'; +import { Templates, Diagnostic } from 'botbuilder-lg'; +import { importResolverGenerator } from '@bfc/shared'; import { ResolverResource } from '@bfc/shared'; import uniqueId from 'lodash/uniqueId'; const isTest = process.env?.NODE_ENV === 'test'; - export interface WorkerMsg { id: string; error?: any; payload?: any; } -// Wrapper class -export class LgParser { +function createDiagnostic(diagnostic: Diagnostic) { + const { code, range, severity, source, message } = diagnostic; + const { start, end } = range; + return { + code, + range: { + start: { line: start.line, character: start.character }, + end: { line: end.line, character: end.character }, + }, + severity, + source, + message, + }; +} + +class LgParserWithoutWorker { + public async parseText(content: string, id: string, resources: ResolverResource[]) { + const resolver = importResolverGenerator(resources, '.lg'); + const { allTemplates, allDiagnostics } = Templates.parseText(content, id, resolver); + const templates = allTemplates.map((item) => ({ name: item.name, parameters: item.parameters, body: item.body })); + const diagnostics = allDiagnostics.map((item) => createDiagnostic(item)); + return { templates, diagnostics }; + } +} + +class LgParserWithWorker { private worker: ChildProcess; private resolves = {}; private rejects = {}; constructor() { - const fileName = isTest ? 'lgWorker.ts' : 'lgWorker.js'; - const execArgv = isTest ? ['-r', 'ts-node/register'] : []; - const workerScriptPath = path.join(__dirname, fileName); - this.worker = fork(workerScriptPath, [], { execArgv }); + const workerScriptPath = path.join(__dirname, 'lgWorker.js'); + this.worker = fork(workerScriptPath, []); this.worker.on('message', this.handleMsg.bind(this)); } @@ -55,3 +78,8 @@ export class LgParser { delete this.rejects[id]; } } + +// Do not use worker when running test. +const LgParser = isTest ? LgParserWithoutWorker : LgParserWithWorker; + +export { LgParser }; 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 aa72b21106..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/libs/bot-deploy": "../../packages/lib/bot-deploy", - "@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 7470fdd315..0000000000 --- a/Composer/plugins/azureFunctionsPublish/src/index.ts +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import path from 'path'; - -import { BotProjectDeploy } from '@bfc/libs/bot-deploy'; -import { v4 as uuid } from 'uuid'; -import md5 from 'md5'; -import { copy, rmdir, emptyDir, readJson, pathExists, writeJson, mkdirSync, writeFileSync } from 'fs-extra'; - -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, 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.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, 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, 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/azureFunctionsPublish/yarn.lock b/Composer/plugins/azureFunctionsPublish/yarn.lock deleted file mode 100644 index 80b8458d3d..0000000000 --- a/Composer/plugins/azureFunctionsPublish/yarn.lock +++ /dev/null @@ -1,2438 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@azure/arm-appinsights@^2.1.0": - version "2.1.0" - 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": - version "1.0.0" - 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": - version "1.0.0" - 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": - version "3.0.0" - 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": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@azure/arm-resources/-/arm-resources-2.1.0.tgz#bb7a3faca0c717656bef93c6f81ff6a9d1d8fa8b" - integrity sha512-WpBQt3QwfulWAgss7r6apfKswc6SS8Z005AhQalx618757dX+0kTiizL5XipDZFWq/nlCN2fFv9ba1m4v5x2tg== - dependencies: - "@azure/ms-rest-azure-js" "^2.0.1" - "@azure/ms-rest-js" "^2.0.4" - tslib "^1.10.0" - -"@azure/arm-subscriptions@^2.0.0": - version "2.0.0" - 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" - tslib "^1.10.0" - -"@azure/cognitiveservices-luis-authoring@4.0.0-preview.1": - version "4.0.0-preview.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/cognitiveservices-luis-authoring/-/@azure/cognitiveservices-luis-authoring-4.0.0-preview.1.tgz#79de764893dc997d95713bb6a0487d887dc78f40" - integrity sha1-ed52SJPcmX2VcTu2oEh9iH3Hj0A= - dependencies: - "@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://botbuilder.myget.org/F/botframework-cli/npm/@azure/cognitiveservices-luis-authoring/-/@azure/cognitiveservices-luis-authoring-4.0.0-preview.3.tgz#68cef01a9efca77c4c5cd4be67b9e0888433af60" - integrity sha1-aM7wGp78p3xMXNS+Z7ngiIQzr2A= - 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://botbuilder.myget.org/F/botframework-cli/npm/@azure/cognitiveservices-luis-runtime/-/@azure/cognitiveservices-luis-runtime-5.0.0.tgz#5a1cbff1f78b25b7ab33d9f675f79eff217188c9" - integrity sha1-Why/8feLJberM9n2dfee/yFxiMk= - dependencies: - "@azure/ms-rest-js" "^2.0.3" - tslib "^1.10.0" - -"@azure/graph@^5.0.1": - version "5.0.1" - 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" - tslib "^1.10.0" - -"@azure/ms-rest-azure-env@^1.1.0": - version "1.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-azure-env/-/@azure/ms-rest-azure-env-1.1.2.tgz#8505873afd4a1227ec040894a64fdd736b4a101f" - integrity sha1-hQWHOv1KEifsBAiUpk/dc2tKEB8= - -"@azure/ms-rest-azure-env@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz#45809f89763a480924e21d3c620cd40866771625" - integrity sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw== - -"@azure/ms-rest-azure-js@2.0.1", "@azure/ms-rest-azure-js@^2.0.0", "@azure/ms-rest-azure-js@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-js/-/ms-rest-azure-js-2.0.1.tgz#fa1b38f039b3ee48a9e086a88c8a5b5b7776491c" - integrity sha512-5e+A710O7gRFISoV4KI/ZyLQbKmjXxQZ1L8Z/sx7jSUQqmswjTnN4yyIZxs5JzfLVkobU0rXxbi5/LVzaI8QXQ== - dependencies: - "@azure/ms-rest-js" "^2.0.4" - tslib "^1.10.0" - -"@azure/ms-rest-azure-js@^1.1.0", "@azure/ms-rest-azure-js@^1.3.2": - version "1.3.8" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-azure-js/-/@azure/ms-rest-azure-js-1.3.8.tgz#96b518223d3baa2496b2981bc07288b3d887486e" - integrity sha1-lrUYIj07qiSWspgbwHKIs9iHSG4= - dependencies: - "@azure/ms-rest-js" "^1.8.10" - tslib "^1.9.3" - -"@azure/ms-rest-browserauth@^0.1.4": - version "0.1.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-browserauth/-/@azure/ms-rest-browserauth-0.1.5.tgz#eb73dc9f6ae8c3f4df187e3e3aaf23f2ee940018" - integrity sha1-63Pcn2row/TfGH4+Oq8j8u6UABg= - dependencies: - "@azure/ms-rest-azure-env" "^1.1.0" - "@azure/ms-rest-js" "^1.8.1" - adal-angular "^1.0.17" - tslib "^1.9.3" - -"@azure/ms-rest-js@^1.1.0", "@azure/ms-rest-js@^1.8.1", "@azure/ms-rest-js@^1.8.10": - version "1.8.15" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-js/-/@azure/ms-rest-js-1.8.15.tgz#4267b6b8c00d85301791fe0cf347e0455a807338" - integrity sha1-Qme2uMANhTAXkf4M80fgRVqAczg= - dependencies: - "@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" - -"@azure/ms-rest-js@^2.0.3", "@azure/ms-rest-js@^2.0.4": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-2.0.7.tgz#3165bb7068387bf36c4c43db85d3662c916fd581" - integrity sha512-rQpNxDhyOIyS4E+4sUCBMvjrtbNwB32wH06cC2SFoQM4TR29bIKaTlIC1tMe0K07w9c5tNk/2uUHs6/ld/Z3+A== - dependencies: - "@types/node-fetch" "^2.3.7" - "@types/tunnel" "0.0.1" - abort-controller "^3.0.0" - form-data "^2.5.0" - node-fetch "^2.6.0" - tough-cookie "^3.0.1" - tslib "^1.10.0" - tunnel "0.0.6" - uuid "^3.3.2" - xml2js "^0.4.19" - -"@azure/ms-rest-nodeauth@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.0.3.tgz#e485b9c960da718d0476115e9f0ec550ccbba561" - integrity sha512-/KAgVV68vkOdrx6O3T6qO7thCep4nPbWzkpNIPFN3P6uzEzDIk6BCGgkzabnmkb2kXaf4+IGHs0UMoXSfN/IgQ== - dependencies: - "@azure/ms-rest-azure-env" "^2.0.0" - "@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://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-nodeauth/-/@azure/ms-rest-nodeauth-3.0.5.tgz#f277ec6e323178fd13c05ca82321ba99c767d4bc" - integrity sha1-8nfsbjIxeP0TwFyoIyG6mcdn1Lw= - dependencies: - "@azure/ms-rest-azure-env" "^2.0.0" - "@azure/ms-rest-js" "^2.0.4" - adal-node "^0.1.28" - -"@bfc/libs/bot-deploy@../../packages/lib/bot-deploy": - version "1.0.0" - 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-preview.141651" - "@microsoft/bf-luis-cli" "^4.10.0-preview.141651" - "@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" - -"@bfc/plugin-loader@../../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-preview.141651": - version "4.10.0-preview.141651" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-cli-command/-/@microsoft/bf-cli-command-4.10.0-preview.141651.tgz#680875f716285fb8658da8098a0ee524b07c5765" - integrity sha1-aAh19xYoX7hljagJig7lJLB8V2U= - dependencies: - "@oclif/command" "~1.5.19" - "@oclif/config" "~1.13.3" - "@oclif/errors" "~1.2.2" - applicationinsights "^1.0.8" - chalk "2.4.1" - cli-ux "~4.9.3" - debug "^4.1.1" - fs-extra "^7.0.1" - tslib "~1.10.0" - -"@microsoft/bf-lu@4.10.0-preview.141651", "@microsoft/bf-lu@^4.10.0-preview.141651": - version "4.10.0-preview.141651" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-lu/-/@microsoft/bf-lu-4.10.0-preview.141651.tgz#29ed2af803d23ee760354913f5b814873bc1285c" - integrity sha1-Ke0q+APSPudgNUkT9bgUhzvBKFw= - dependencies: - "@azure/cognitiveservices-luis-authoring" "4.0.0-preview.1" - "@azure/ms-rest-azure-js" "2.0.1" - "@oclif/command" "~1.5.19" - "@oclif/errors" "~1.2.2" - "@types/node-fetch" "~2.5.5" - antlr4 "^4.7.2" - chalk "2.4.1" - console-stream "^0.1.1" - deep-equal "^1.0.1" - delay "^4.3.0" - fs-extra "^8.1.0" - get-stdin "^6.0.0" - globby "^10.0.1" - intercept-stdout "^0.1.2" - lodash "^4.17.15" - node-fetch "~2.6.0" - semver "^5.5.1" - tslib "^1.10.0" - -"@microsoft/bf-luis-cli@^4.10.0-preview.141651": - version "4.10.0-preview.141651" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-luis-cli/-/@microsoft/bf-luis-cli-4.10.0-preview.141651.tgz#29ef283f23d9b59841faff4872cb6900b91ec2e8" - integrity sha1-Ke8oPyPZtZhB+v9IcstpALkewug= - dependencies: - "@azure/cognitiveservices-luis-authoring" "4.0.0-preview.1" - "@azure/cognitiveservices-luis-runtime" "5.0.0" - "@azure/ms-rest-azure-js" "2.0.1" - "@microsoft/bf-cli-command" "4.10.0-preview.141651" - "@microsoft/bf-lu" "4.10.0-preview.141651" - "@oclif/command" "~1.5.19" - "@oclif/config" "~1.13.3" - "@oclif/errors" "~1.2.2" - "@types/node-fetch" "~2.5.5" - "@types/sinon" "^7.5.0" - cli-ux "~5.3.3" - fs-extra "^8.1.0" - lodash "^4.17.15" - node-fetch "~2.6.0" - tslib "^1.10.0" - username "^4.1.0" - -"@nodelib/fs.scandir@2.1.3": - version "2.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@nodelib/fs.scandir/-/@nodelib/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" - integrity sha1-Olgr21OATGum0UZXnEblITDPSjs= - 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://botbuilder.myget.org/F/botframework-cli/npm/@nodelib/fs.stat/-/@nodelib/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" - integrity sha1-NNxfTKu8cg9OYPdadH5+zWwXW9M= - -"@nodelib/fs.walk@^1.2.3": - version "1.2.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@nodelib/fs.walk/-/@nodelib/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" - integrity sha1-ARuSAqcKY2bkNspcBlhEUoqwSXY= - dependencies: - "@nodelib/fs.scandir" "2.1.3" - fastq "^1.6.0" - -"@oclif/command@^1.5.1", "@oclif/command@^1.5.13", "@oclif/command@^1.5.20": - version "1.6.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/command/-/@oclif/command-1.6.1.tgz#774e860f283f32a728377da1c2a90beb8aadf9f5" - integrity sha1-d06GDyg/MqcoN32hwqkL64qt+fU= - dependencies: - "@oclif/config" "^1.15.1" - "@oclif/errors" "^1.2.2" - "@oclif/parser" "^3.8.3" - "@oclif/plugin-help" "^3" - debug "^4.1.1" - semver "^5.6.0" - -"@oclif/command@~1.5.19": - version "1.5.20" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/command/-/@oclif/command-1.5.20.tgz#bb0693586d7d66a457c49b719e394c02ff0169a7" - integrity sha1-uwaTWG19ZqRXxJtxnjlMAv8Baac= - dependencies: - "@oclif/config" "^1" - "@oclif/errors" "^1.2.2" - "@oclif/parser" "^3.8.3" - "@oclif/plugin-help" "^2" - debug "^4.1.1" - semver "^5.6.0" - -"@oclif/config@^1", "@oclif/config@^1.15.1": - version "1.15.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/config/-/@oclif/config-1.15.1.tgz#39950c70811ab82d75bb3cdb33679ed0a4c21c57" - integrity sha1-OZUMcIEauC11uzzbM2ee0KTCHFc= - dependencies: - "@oclif/errors" "^1.0.0" - "@oclif/parser" "^3.8.0" - debug "^4.1.1" - tslib "^1.9.3" - -"@oclif/config@~1.13.3": - version "1.13.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/config/-/@oclif/config-1.13.3.tgz#1b13e18d0e4242ddbd9cbd100f0eec819aa2bf8c" - integrity sha1-GxPhjQ5CQt29nL0QDw7sgZqiv4w= - dependencies: - "@oclif/parser" "^3.8.0" - debug "^4.1.1" - tslib "^1.9.3" - -"@oclif/errors@^1.0.0", "@oclif/errors@^1.2.1", "@oclif/errors@^1.2.2": - version "1.3.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/errors/-/@oclif/errors-1.3.2.tgz#ac2ec91ba892c1981008e6173e37deded866358c" - integrity sha1-rC7JG6iSwZgQCOYXPjfe3thmNYw= - dependencies: - clean-stack "^3.0.0" - fs-extra "^9.0.1" - indent-string "^4.0.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -"@oclif/errors@~1.2.2": - version "1.2.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/errors/-/@oclif/errors-1.2.2.tgz#9d8f269b15f13d70aa93316fed7bebc24688edc2" - integrity sha1-nY8mmxXxPXCqkzFv7XvrwkaI7cI= - dependencies: - clean-stack "^1.3.0" - fs-extra "^7.0.0" - indent-string "^3.2.0" - strip-ansi "^5.0.0" - wrap-ansi "^4.0.0" - -"@oclif/linewrap@^1.0.0": - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/linewrap/-/@oclif/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" - integrity sha1-rty2S0edTbe+JBljhIl7UACQHZE= - -"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.3": - version "3.8.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/parser/-/@oclif/parser-3.8.5.tgz#c5161766a1efca7343e1f25d769efbefe09f639b" - integrity sha1-xRYXZqHvynND4fJddp777+CfY5s= - dependencies: - "@oclif/errors" "^1.2.2" - "@oclif/linewrap" "^1.0.0" - chalk "^2.4.2" - tslib "^1.9.3" - -"@oclif/plugin-help@^2": - version "2.2.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/plugin-help/-/@oclif/plugin-help-2.2.3.tgz#b993041e92047f0e1762668aab04d6738ac06767" - integrity sha1-uZMEHpIEfw4XYmaKqwTWc4rAZ2c= - dependencies: - "@oclif/command" "^1.5.13" - chalk "^2.4.1" - indent-string "^4.0.0" - lodash.template "^4.4.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - widest-line "^2.0.1" - wrap-ansi "^4.0.0" - -"@oclif/plugin-help@^3": - version "3.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/plugin-help/-/@oclif/plugin-help-3.1.0.tgz#507ff8e9cabe734672b12d1ec0b79812d18c58a8" - integrity sha1-UH/46cq+c0ZysS0ewLeYEtGMWKg= - dependencies: - "@oclif/command" "^1.5.20" - "@oclif/config" "^1.15.1" - chalk "^2.4.1" - indent-string "^4.0.0" - lodash.template "^4.4.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - widest-line "^2.0.1" - wrap-ansi "^4.0.0" - -"@oclif/screen@^1.0.3": - version "1.0.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/screen/-/@oclif/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493" - integrity sha1-t0D2hgnfroqnHDpsqxXYFkB7pJM= - -"@types/archiver@3.1.0", "@types/archiver@^3.1.0": - version "3.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/archiver/-/@types/archiver-3.1.0.tgz#0d5bd922ba5cf06e137cd6793db7942439b1805e" - integrity sha1-DVvZIrpc8G4TfNZ5PbeUJDmxgF4= - dependencies: - "@types/glob" "*" - -"@types/bluebird@*": - version "3.5.32" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/bluebird/-/@types/bluebird-3.5.32.tgz#381e7b59e39f010d20bbf7e044e48f5caf1ab620" - integrity sha1-OB57WeOfAQ0gu/fgROSPXK8atiA= - -"@types/caseless@*": - version "0.12.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/caseless/-/@types/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" - integrity sha1-9l09Y4ngHutFi9VNyPUrlalGO8g= - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/color-name/-/@types/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA= - -"@types/fs-extra@8.1.0": - version "8.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/fs-extra/-/@types/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d" - integrity sha1-ERSDS1PDkUgGzQOzMEs3s70iGk0= - dependencies: - "@types/node" "*" - -"@types/fs-extra@^8.1.0": - version "8.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/fs-extra/-/@types/fs-extra-8.1.1.tgz#1e49f22d09aa46e19b51c0b013cb63d0d923a068" - integrity sha1-HknyLQmqRuGbUcCwE8tj0NkjoGg= - dependencies: - "@types/node" "*" - -"@types/glob@*", "@types/glob@^7.1.1": - version "7.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/glob/-/@types/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987" - integrity sha1-BsomUhNTpUXZSgrcdPOKWdIyyYc= - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/minimatch@*": - version "3.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/minimatch/-/@types/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0= - -"@types/node-fetch@^2.3.7", "@types/node-fetch@~2.5.5": - version "2.5.7" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/node-fetch/-/@types/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" - integrity sha1-IKKv/6iCqwTUTKeGRJonb59rvzw= - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*": - version "14.0.14" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/node/-/@types/node-14.0.14.tgz#24a0b5959f16ac141aeb0c5b3cd7a15b7c64cbce" - integrity sha1-JKC1lZ8WrBQa6wxbPNehW3xky84= - -"@types/node@^8.0.47": - version "8.10.61" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/node/-/@types/node-8.10.61.tgz#d299136ce54bcaf1abaa4a487f9e4bedf6b0d393" - integrity sha1-0pkTbOVLyvGrqkpIf55L7faw05M= - -"@types/request-promise@4.1.45": - version "4.1.45" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/request-promise/-/@types/request-promise-4.1.45.tgz#7fcdd39fd920674ab7bfb44197270f225fb4e585" - integrity sha1-f83Tn9kgZ0q3v7RBlycPIl+05YU= - dependencies: - "@types/bluebird" "*" - "@types/request" "*" - -"@types/request-promise@^4.1.45": - version "4.1.46" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/request-promise/-/@types/request-promise-4.1.46.tgz#37df6efae984316dfbfbbe8fcda37f3ba52822f2" - integrity sha1-N99u+umEMW37+76PzaN/O6UoIvI= - dependencies: - "@types/bluebird" "*" - "@types/request" "*" - -"@types/request@*", "@types/request@^2.48.4": - version "2.48.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/request/-/@types/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" - integrity sha1-AZuFNrQCBp9tEb7hssA+fyMpN6A= - dependencies: - "@types/caseless" "*" - "@types/node" "*" - "@types/tough-cookie" "*" - form-data "^2.5.0" - -"@types/request@2.48.4": - version "2.48.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/request/-/@types/request-2.48.4.tgz#df3d43d7b9ed3550feaa1286c6eabf0738e6cf7e" - integrity sha1-3z1D17ntNVD+qhKGxuq/Bzjmz34= - dependencies: - "@types/caseless" "*" - "@types/node" "*" - "@types/tough-cookie" "*" - form-data "^2.5.0" - -"@types/sinon@^7.5.0": - version "7.5.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/sinon/-/@types/sinon-7.5.2.tgz#5e2f1d120f07b9cda07e5dedd4f3bf8888fccdb9" - integrity sha1-Xi8dEg8Huc2gfl3t1PO/iIj8zbk= - -"@types/tough-cookie@*": - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/tough-cookie/-/@types/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" - integrity sha1-/vGQTkZotuXs7mDFLMageP+maX0= - -"@types/tunnel@0.0.0": - version "0.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/tunnel/-/@types/tunnel-0.0.0.tgz#c2a42943ee63c90652a5557b8c4e56cda77f944e" - integrity sha1-wqQpQ+5jyQZSpVV7jE5Wzad/lE4= - dependencies: - "@types/node" "*" - -"@types/tunnel@0.0.1": - version "0.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/tunnel/-/@types/tunnel-0.0.1.tgz#0d72774768b73df26f25df9184273a42da72b19c" - integrity sha1-DXJ3R2i3PfJvJd+RhCc6QtpysZw= - dependencies: - "@types/node" "*" - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha1-6vVNU7YrrkE46AnKIlyEOabvs5I= - dependencies: - event-target-shim "^5.0.0" - -adal-angular@^1.0.17: - version "1.0.17" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/adal-angular/-/adal-angular-1.0.17.tgz#6e936e0e41f91d3b2a88e7ffca9c2f6f6f562cc4" - integrity sha1-bpNuDkH5HTsqiOf/ypwvb29WLMQ= - -adal-node@0.2.1: - version "0.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/adal-node/-/adal-node-0.2.1.tgz#19e401bd579977448c1a77ce0e5b4c9accdc334e" - integrity sha1-GeQBvVeZd0SMGnfODltMmszcM04= - dependencies: - "@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" - -adal-node@^0.1.28: - version "0.1.28" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/adal-node/-/adal-node-0.1.28.tgz#468c4bb3ebbd96b1270669f4b9cba4e0065ea485" - integrity sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU= - dependencies: - "@types/node" "^8.0.47" - async ">=0.6.0" - date-utils "*" - jws "3.x.x" - request ">= 2.52.0" - underscore ">= 1.3.1" - uuid "^3.1.0" - xmldom ">= 0.1.x" - xpath.js "~1.1.0" - -ajv@^6.5.5: - version "6.12.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" - integrity sha1-xinF7O0XuvMUQ3kY0tqIyZ1ZWM0= - dependencies: - 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@^3.1.0: - version "3.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha1-h4C5j/nb9WOBUtHx/lwde0RCl2s= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc= - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0: - version "4.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha1-kK51xCTQCNJiTFvynq0xd+v881k= - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= - -antlr4@^4.7.2: - version "4.8.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/antlr4/-/antlr4-4.8.0.tgz#f938ec171be7fc2855cd3a533e87647185b32b6a" - integrity sha1-+TjsFxvn/ChVzTpTPodkcYWzK2o= - -applicationinsights@^1.0.8: - version "1.8.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/applicationinsights/-/applicationinsights-1.8.0.tgz#c4c54f7ab420cf97fc07eab2e6e037b5f2158eae" - integrity sha1-xMVPerQgz5f8B+qy5uA3tfIVjq4= - dependencies: - cls-hooked "^4.2.2" - continuation-local-storage "^3.2.1" - diagnostic-channel "0.3.1" - diagnostic-channel-publishers "0.4.0" - -archiver-utils@^2.1.0: - version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" - integrity sha1-6KRg6UtpPD49oYKgmMpihbqSSeI= - 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://botbuilder.myget.org/F/botframework-cli/npm/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0" - integrity sha1-nbeBnU2vYK7BD+hrFsuSWM7WbqA= - 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://botbuilder.myget.org/F/botframework-cli/npm/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha1-t5hCCtvrHego2ErNii4j0+/oXo0= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha1-jSR136tVO7M+d7VOWeiAu4ziMTY= - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -async-hook-jl@^1.7.6: - version "1.7.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68" - integrity sha1-T9JcL4ZNuvJ5xhDXO/l7GyhZXmg= - dependencies: - stack-chain "^1.3.7" - -async-listener@^0.6.0: - version "0.6.10" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc" - integrity sha1-p8l6vlcLpgLXgic8DeYKUePhfLw= - dependencies: - semver "^5.3.0" - shimmer "^1.1.0" - -async@>=0.6.0: - version "3.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha1-s6JoXF67ZB094C0WEALGD8n4VyA= - -async@^2.6.3: - version "2.6.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8= - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha1-YCzUtG6EStTv/JKoARo8RuAjjcI= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" - integrity sha1-oXs6jqgRBg501H0wYSJACtRJeuI= - -axios@^0.19.0: - version "0.19.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" - integrity sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc= - dependencies: - follow-redirects "1.5.10" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha1-WOzoy3XdB+ce0IxzarxfrE2/jfE= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bl@^4.0.1: - version "4.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" - integrity sha1-UrcekIhRXQYG2d2cx6pI3B+Y5zo= - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -bluebird@^3.5.0: - version "3.7.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha1-nyKcFb4nJFT/qXOs4NvueaGww28= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1: - version "3.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha1-NFThpGLujVmeI23zNs2epPiv4Qc= - dependencies: - fill-range "^7.0.1" - -buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: - version "0.2.13" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - -buffer@^5.1.0, buffer@^5.5.0: - version "5.6.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" - integrity sha1-oxdJ3H2B2E2wir+Te2uMQDP2J4Y= - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - -cardinal@^2.1.1: - version "2.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505" - integrity sha1-fMEFXYItISlU0HsIXeolHMe8VQU= - dependencies: - ansicolors "~0.3.2" - redeyed "~2.1.0" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@2.4.1: - version "2.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha1-GMSasWoDe26wFSzIPjRxM4IVtm4= - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -charenc@~0.0.1: - version "0.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= - -clean-stack@^1.3.0: - version "1.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" - integrity sha1-noIVAa6XmYbEax1m0tQy2y/UrjE= - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha1-7oRy27Ep5yezHooQpCfe6d/kAIs= - -clean-stack@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/clean-stack/-/clean-stack-3.0.0.tgz#a7c249369fcf0f33c7888c20ea3f3dc79620211f" - integrity sha1-p8JJNp/PDzPHiIwg6j89x5YgIR8= - dependencies: - escape-string-regexp "4.0.0" - -cli-ux@~4.9.3: - version "4.9.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/cli-ux/-/cli-ux-4.9.3.tgz#4c3e070c1ea23eef010bbdb041192e0661be84ce" - integrity sha1-TD4HDB6iPu8BC72wQRkuBmG+hM4= - dependencies: - "@oclif/errors" "^1.2.2" - "@oclif/linewrap" "^1.0.0" - "@oclif/screen" "^1.0.3" - ansi-escapes "^3.1.0" - ansi-styles "^3.2.1" - cardinal "^2.1.1" - chalk "^2.4.1" - clean-stack "^2.0.0" - extract-stack "^1.0.0" - fs-extra "^7.0.0" - hyperlinker "^1.0.0" - indent-string "^3.2.0" - is-wsl "^1.1.0" - lodash "^4.17.11" - password-prompt "^1.0.7" - semver "^5.6.0" - strip-ansi "^5.0.0" - supports-color "^5.5.0" - supports-hyperlinks "^1.0.1" - treeify "^1.1.0" - tslib "^1.9.3" - -cli-ux@~5.3.3: - version "5.3.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/cli-ux/-/cli-ux-5.3.3.tgz#6459e180da29f2850473b9bf2f1ae097e5257d31" - integrity sha1-ZFnhgNop8oUEc7m/Lxrgl+UlfTE= - dependencies: - "@oclif/command" "^1.5.1" - "@oclif/errors" "^1.2.1" - "@oclif/linewrap" "^1.0.0" - "@oclif/screen" "^1.0.3" - ansi-escapes "^3.1.0" - ansi-styles "^3.2.1" - cardinal "^2.1.1" - chalk "^2.4.1" - clean-stack "^2.0.0" - extract-stack "^1.0.0" - fs-extra "^7.0.1" - hyperlinker "^1.0.0" - indent-string "^3.2.0" - is-wsl "^1.1.0" - lodash "^4.17.11" - natural-orderby "^2.0.1" - password-prompt "^1.1.2" - semver "^5.6.0" - string-width "^3.1.0" - strip-ansi "^5.1.0" - supports-color "^5.5.0" - supports-hyperlinks "^1.0.1" - treeify "^1.1.0" - tslib "^1.9.3" - -cls-hooked@^4.2.2: - version "4.2.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" - integrity sha1-rS6aQJJoDNr/6y01UdoOIl6uGQg= - dependencies: - async-hook-jl "^1.7.6" - emitter-listener "^1.0.1" - semver "^5.4.1" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= - dependencies: - delayed-stream "~1.0.0" - -compress-commons@^2.1.1: - version "2.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/compress-commons/-/compress-commons-2.1.1.tgz#9410d9a534cf8435e3fbbb7c6ce48de2dc2f0610" - integrity sha1-lBDZpTTPhDXj+7t8bOSN4twvBhA= - 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://botbuilder.myget.org/F/botframework-cli/npm/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -console-stream@^0.1.1: - version "0.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44" - integrity sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ= - -continuation-local-storage@^3.2.1: - version "3.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb" - integrity sha1-EfYT906RT+mzTJKtLSj+auHbf/s= - dependencies: - async-listener "^0.6.0" - emitter-listener "^1.1.1" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/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://botbuilder.myget.org/F/botframework-cli/npm/crc32-stream/-/crc32-stream-3.0.1.tgz#cae6eeed003b0e44d739d279de5ae63b171b4e85" - integrity sha1-yubu7QA7DkTXOdJ53lrmOxcbToU= - dependencies: - crc "^3.4.4" - readable-stream "^3.4.0" - -crc@^3.4.4: - version "3.8.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" - integrity sha1-rWAmnCyFb4wpnixMwN5FVpFAVsY= - dependencies: - buffer "^5.1.0" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q= - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypt@~0.0.1: - version "0.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -date-utils@*: - version "1.2.21" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64" - integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q= - -debug@=3.1.0: - version "3.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE= - dependencies: - ms "2.0.0" - -debug@^4.1.1: - version "4.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E= - dependencies: - ms "^2.1.1" - -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o= - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= - dependencies: - object-keys "^1.0.12" - -delay@^4.3.0: - version "4.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/delay/-/delay-4.3.0.tgz#efeebfb8f545579cb396b3a722443ec96d14c50e" - integrity sha1-7+6/uPVFV5yzlrOnIkQ+yW0UxQ4= - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -diagnostic-channel-publishers@0.4.0: - version "0.4.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.4.0.tgz#254e3bab1dc9021db8aba3efbaefeabf10b84a77" - integrity sha1-JU47qx3JAh24q6Pvuu/qvxC4Snc= - -diagnostic-channel@0.3.1: - version "0.3.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/diagnostic-channel/-/diagnostic-channel-0.3.1.tgz#7faa143e107f861be3046539eb4908faab3f53fd" - integrity sha1-f6oUPhB/hhvjBGU560kI+qs/U/0= - dependencies: - semver "^5.3.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha1-Vtv3PZkqSpO6FYT0U0Bj/S5BcX8= - dependencies: - path-type "^4.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha1-rg8PothQRe8UqBfao86azQSJ5b8= - dependencies: - safe-buffer "^5.0.1" - -emitter-listener@^1.0.1, emitter-listener@^1.1.1: - version "1.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8" - integrity sha1-VrFA6PaZI3Wz18ssqxzHQy2WMug= - dependencies: - shimmer "^1.2.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY= - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha1-WuZKX0UFe682JuwU2gyl5LJDHrA= - dependencies: - once "^1.4.0" - -es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha1-kUIHFweFeyysx7iey2cDFsPi1So= - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo= - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ= - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -esprima@~4.0.0: - version "4.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha1-E7BM2z5sXRnfkatph6hpVhmwqnE= - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha1-XU0+vflYPWOlMzzi3rdICrKwV4k= - -execa@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg= - dependencies: - 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" - -extend@~3.0.2: - version "3.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= - -extract-stack@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/extract-stack/-/extract-stack-1.0.0.tgz#b97acaf9441eea2332529624b732fc5a1c8165fa" - integrity sha1-uXrK+UQe6iMyUpYktzL8WhyBZfo= - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU= - -fast-glob@^3.0.3, fast-glob@^3.1.1: - version "3.2.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha1-0grvv5lXk4Pn88xmUpFYybmFVNM= - 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" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= - -fastq@^1.6.0: - version "1.8.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" - integrity sha1-VQ4fn1m7xl/hhctqm02VNXEH9IE= - dependencies: - reusify "^1.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha1-GRmmp8df44ssfHflGYU12prN2kA= - dependencies: - to-regex-range "^5.0.1" - -follow-redirects@1.5.10: - version "1.5.10" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio= - dependencies: - debug "=3.1.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@^2.3.2, form-data@^2.5.0: - version "2.5.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha1-8svsV7XlniNxbhKP5E1OXdI4lfQ= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -form-data@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - integrity sha1-MbfjnIXxNVtxOe4MZHzw3n+DxoI= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha1-3M5SwF9kTymManq5Nr1yTO/786Y= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha1-a+Dem+mYzhavivwkSXue6bfM2a0= - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha1-TxicRKoSO4lfcigE9V6iPq3DSOk= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA= - 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://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" - integrity sha1-kQ2gBiQ3ukw5/t2GPxZ1zP78ufw= - 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://botbuilder.myget.org/F/botframework-cli/npm/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= - -get-stdin@^6.0.0: - version "6.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" - integrity sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs= - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha1-wbJVV189wh1Zv8ec09K0axw6VLU= - dependencies: - pump "^3.0.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^5.1.0: - version "5.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha1-tsHvQXxOVmPqSY8cRa+saRa7wik= - dependencies: - is-glob "^4.0.1" - -glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY= - 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@^10.0.1: - version "10.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - integrity sha1-J3WT50WsqkZGw6tBEonsR6A5JUM= - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.0.0: - version "11.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" - integrity sha1-mivxB6Bo8//qvEmtcCx57ejP01c= - 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.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha1-Ila94U02MpWMRl68ltxGfKB6Kfs= - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha1-HvievT5JllV2de7ZiTEQ3DUPoIA= - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha1-n1IUdYpEGWxAbZvXbOv4HsLdMeg= - -has@^1.0.3: - version "1.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= - dependencies: - function-bind "^1.1.1" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -hyperlinker@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e" - integrity sha1-I9yeOKIGsgjuSbwtbI70cCffDA4= - -ieee754@^1.1.4: - version "1.1.13" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q= - -ignore@^5.1.1, ignore@^5.1.4: - version "5.1.8" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha1-8VCotQo0KJsz4i9YiavU2AFvDlc= - -indent-string@^3.2.0: - version "3.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/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://botbuilder.myget.org/F/botframework-cli/npm/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= - -intercept-stdout@^0.1.2: - version "0.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/intercept-stdout/-/intercept-stdout-0.1.2.tgz#126abf1fae6c509a428a98c61a631559042ae9fd" - integrity sha1-Emq/H65sUJpCipjGGmMVWQQq6f0= - dependencies: - lodash.toarray "^3.0.0" - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM= - -is-buffer@~1.1.1: - version "1.1.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha1-76ouqdqg16suoTqXsritUf776L4= - -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" - integrity sha1-gzNlYLVKOONeOi33r9BFTWkUaLs= - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha1-vac28s2P0G0yhE53Q7+nSUw7/X4= - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= - -is-glob@^4.0.1: - version "4.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss= - -is-regex@^1.0.4, is-regex@^1.1.0: - version "1.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" - integrity sha1-7OOOOJ5JDfDcIcrqK9WW+Yf3Z/8= - dependencies: - has-symbols "^1.0.1" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc= - dependencies: - has-symbols "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@~1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha1-afaofZUTq4u4/mO9sJecRI5oRmA= - -json-schema@0.2.3: - version "0.2.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" - integrity sha1-mJZsuiFDeMjIS4LghZB7QL9hQXk= - dependencies: - universalify "^1.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -jwa@^1.4.1: - version "1.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha1-dDwymFy56YZVUw1TZBtmyGRbA5o= - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@3.x.x: - version "3.2.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha1-ABCZ82OUaMlBQADpmZX6UvtHgwQ= - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - -lazystream@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= - dependencies: - readable-stream "^2.0.5" - -lodash._arraycopy@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" - integrity sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE= - -lodash._basevalues@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" - integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/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://botbuilder.myget.org/F/botframework-cli/npm/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lodash.template@^4.4.0: - version "4.5.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha1-+XYZXPPzR9DV9SSDVp/oAxzM6Ks= - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha1-5IExDwSdPPbUfpEq0JMTsVTw+zM= - dependencies: - lodash._reinterpolate "^3.0.0" - -lodash.toarray@^3.0.0: - version "3.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.toarray/-/lodash.toarray-3.0.2.tgz#2b204f0fa4f51c285c6f00c81d1cea5a23041179" - integrity sha1-KyBPD6T1HChcbwDIHRzqWiMEEXk= - dependencies: - lodash._arraycopy "^3.0.0" - lodash._basevalues "^3.0.0" - lodash.keys "^3.0.0" - -lodash.union@^4.6.0: - version "4.6.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15: - version "4.17.15" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg= - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha1-fVg6cwZDTAVf5HSw9FB45uG0uSo= - dependencies: - p-defer "^1.0.0" - -md5@2.2.1: - version "2.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" - integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= - dependencies: - charenc "~0.0.1" - crypt "~0.0.1" - is-buffer "~1.1.1" - -mem@^4.0.0: - version "4.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha1-Rhr0l7xK4JYIzbLmDu+2m/90QXg= - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -merge2@^1.2.3, merge2@^1.3.0: - version "1.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4= - -micromatch@^4.0.2: - version "4.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha1-T8sJmb+fvC/L3SEvbWKbmlbDklk= - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I= - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8= - dependencies: - mime-db "1.44.0" - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM= - dependencies: - brace-expansion "^1.1.7" - -minimist@1.2.5: - version "1.2.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI= - -ms@2.0.0: - version "2.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= - -natural-orderby@^2.0.1: - version "2.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/natural-orderby/-/natural-orderby-2.0.3.tgz#8623bc518ba162f8ff1cdb8941d74deb0fdcc016" - integrity sha1-hiO8UYuhYvj/HNuJQddN6w/cwBY= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y= - -node-fetch@^2.6.0, node-fetch@~2.6.0: - version "2.6.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" - integrity sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0= - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU= - -object-inspect@^1.7.0: - version "1.8.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha1-34B+Xs9TpgnMa/6T6sPMe+WzqdA= - -object-is@^1.0.1: - version "1.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" - integrity sha1-xdLof/nhGfeLegiEQVGeLuwVc7Y= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha1-HEfyct8nfzsdrwYWd9nILiMixg4= - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha1-lovxEA15Vrs8oIbwBvhGs7xACNo= - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha1-kYzrrqJIpiz3/6uOO8qMX4gvxC4= - -passport-strategy@1.x.x: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= - -passport@^0.4.1: - version "0.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" - integrity sha1-lBRGohy5L8aI2XoIYcOM6fc48nA= - 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://botbuilder.myget.org/F/botframework-cli/npm/password-prompt/-/password-prompt-1.1.2.tgz#85b2f93896c5bd9e9f2d6ff0627fa5af3dc00923" - integrity sha1-hbL5OJbFvZ6fLW/wYn+lrz3ACSM= - dependencies: - ansi-escapes "^3.1.0" - cross-spawn "^6.0.5" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-to-regexp@^6.1.0: - version "6.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-to-regexp/-/path-to-regexp-6.1.0.tgz#0b18f88b7a0ce0bfae6a25990c909ab86f512427" - integrity sha1-Cxj4i3oM4L+uaiWZDJCauG9RJCc= - -path-type@^4.0.0: - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs= - -pause@0.0.1: - version "0.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha1-IfMz6ba46v8CRo9RRupAbTRfTa0= - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I= - -psl@^1.1.28: - version "1.8.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ= - -pump@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ= - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha1-tYsBCsQMIsVldhbI0sLALHv0eew= - -qs@~6.5.2: - version "6.5.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha1-yzroBuh0BERYTvFUzo7pjUA/PjY= - -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.3.6: - version "2.3.7" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c= - 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://botbuilder.myget.org/F/botframework-cli/npm/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha1-M3u9o63AcGvT4CRCaihtS0sskZg= - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -redeyed@~2.1.0: - version "2.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b" - integrity sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs= - dependencies: - esprima "~4.0.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha1-erqJs8E6ZFCdq888qNn7ub31y3U= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha1-6aPAgbUTgN/qZ3M2Bh/qh5qCnuk= - dependencies: - lodash "^4.17.15" - -request-promise@^4.2.5: - version "4.2.5" - 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: - version "2.88.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM= - dependencies: - 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" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY= - -run-parallel@^1.1.9: - version "1.1.9" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" - integrity sha1-yd06fPn0ssS2JE4XOm7YZuYd1nk= - -safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY= - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0= - -safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= - -sax@>=0.6.0: - version "1.2.4" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha1-KBYjTiN4vdxOU1T6tcqold9xANk= - -semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shimmer@^1.1.0, shimmer@^1.2.0: - version "1.2.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" - integrity sha1-YQhZ994ye1h+/r9QH7QxF/mv8zc= - -signal-exit@^3.0.0: - version "3.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw= - -slash@^3.0.0: - version "3.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha1-+2YcC+8ps520B2nuOfpwCT1vaHc= - dependencies: - 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-chain@^1.3.7: - version "1.3.7" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" - integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU= - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -string-width@^2.1.1: - version "2.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4= - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha1-InZ74htirxCBV0MG9prFG2IgOWE= - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0: - version "4.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha1-lSGCxGzHssMT0VluYjmSvRY7crU= - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha1-hYEqa4R6wAInD1gIFGBkyZX7aRM= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha1-FK9tnzSwU/fPyJty+PLuFLkDmlQ= - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4= - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4= - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI= - dependencies: - ansi-regex "^5.0.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -supports-color@^5.0.0, supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= - dependencies: - has-flag "^3.0.0" - -supports-hyperlinks@^1.0.1: - version "1.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" - integrity sha1-cdrt82zBBgrFEAw1G7PaSMKcDvc= - dependencies: - has-flag "^2.0.0" - supports-color "^5.0.0" - -tar-stream@^2.1.0: - version "2.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" - integrity sha1-bV7xp+V4OpX/cLabl0VaWWjcEyU= - 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://botbuilder.myget.org/F/botframework-cli/npm/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ= - dependencies: - is-number "^7.0.0" - -tough-cookie@^2.3.3, tough-cookie@^2.4.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha1-zZ+yoKodWhK0c72fuW+j3P9lreI= - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha1-nfT1fnOcJpMKAYGEiH9K233Kc7I= - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - -treeify@^1.1.0: - version "1.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" - integrity sha1-TjHGpGOszQlDh58wZnxP2v9BG7g= - -tslib@^1.10.0, tslib@^1.9.2, tslib@^1.9.3: - version "1.13.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha1-yIHhPMcBWJTtkUhi0nZDb6mkcEM= - -tslib@~1.10.0: - version "1.10.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo= - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tunnel@0.0.6: - version "0.0.6" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw= - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -"underscore@>= 1.3.1": - version "1.10.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" - integrity sha1-c9aqNmjzGI5K2w8ZQ70Sz9fvqq8= - -universalify@^0.1.0: - version "0.1.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY= - -universalify@^1.0.0: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" - integrity sha1-thodoXPoQ1sv48Z9Kbmt+FlL0W0= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha1-lMVA4f93KVbiKZUHwBCupsiDjrA= - dependencies: - punycode "^2.1.0" - -username@^4.1.0: - version "4.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/username/-/username-4.1.0.tgz#640f2ae13d17c51e7fb1d3517ad7c17fcd5d1670" - integrity sha1-ZA8q4T0XxR5/sdNRetfBf81dFnA= - dependencies: - execa "^1.0.0" - mem "^4.0.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@7.0.3: - version "7.0.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha1-xcnyyM8l3Ao3LE3xRBxB9b0MaAs= - -uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2: - version "3.4.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= - -verror@1.10.0: - version "1.10.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which@^1.2.9: - version "1.3.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo= - dependencies: - isexe "^2.0.0" - -widest-line@^2.0.1: - version "2.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha1-dDh2RzDsfvQ4HOTfgvuYpTFCo/w= - dependencies: - string-width "^2.1.1" - -wrap-ansi@^4.0.0: - version "4.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/wrap-ansi/-/wrap-ansi-4.0.0.tgz#b3570d7c70156159a2d42be5cc942e957f7b1131" - integrity sha1-s1cNfHAVYVmi1CvlzJQulX97ETE= - dependencies: - ansi-styles "^3.2.0" - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM= - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xml2js@^0.4.19: - version "0.4.23" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha1-oMaVFnUkIesqx1juTUzPWIQ+rGY= - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha1-vpuuHIoEbnazESdyY0fQrXACvrM= - -"xmldom@>= 0.1.x": - version "0.3.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/xmldom/-/xmldom-0.3.0.tgz#e625457f4300b5df9c2e1ecb776147ece47f3e5a" - integrity sha1-5iVFf0MAtd+cLh7Ld2FH7OR/Plo= - -xpath.js@~1.1.0: - version "1.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/xpath.js/-/xpath.js-1.1.0.tgz#3816a44ed4bb352091083d002a383dd5104a5ff1" - integrity sha1-OBakTtS7NSCRCD0AKjg91RBKX/E= - -zip-stream@^2.1.2: - version "2.1.3" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/zip-stream/-/zip-stream-2.1.3.tgz#26cc4bdb93641a8590dd07112e1f77af1758865b" - integrity sha1-JsxL25NkGoWQ3QcRLh93rxdYhls= - dependencies: - archiver-utils "^2.1.0" - compress-commons "^2.1.1" - readable-stream "^3.4.0" 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 8254955599..ee34ac5ec6 100644 --- a/Composer/plugins/azurePublish/package.json +++ b/Composer/plugins/azurePublish/package.json @@ -1,5 +1,5 @@ { - "name": "azurePublish", + "name": "plugin-azure-publish", "version": "1.0.0", "description": "Publish bot to an Azure Web App (Preview)", "main": "lib/index.js", @@ -9,14 +9,26 @@ }, "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/libs/bot-deploy": "../../packages/lib/bot-deploy", - "@bfc/plugin-loader": "../../packages/extensions/plugin-loader", + "@microsoft/bf-lu": "4.10.0-preview.141651", + "@microsoft/bf-luis-cli": "4.10.0-preview.141651", "@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", "adal-node": "0.2.1", "md5": "2.2.1", "minimist": "1.2.5", diff --git a/Composer/packages/lib/bot-deploy/src/botProjectDeployConfig.ts b/Composer/plugins/azurePublish/src/botProjectDeployConfig.ts similarity index 100% rename from Composer/packages/lib/bot-deploy/src/botProjectDeployConfig.ts rename to Composer/plugins/azurePublish/src/botProjectDeployConfig.ts diff --git a/Composer/packages/lib/bot-deploy/src/botProjectLoggerType.ts b/Composer/plugins/azurePublish/src/botProjectLoggerType.ts similarity index 100% rename from Composer/packages/lib/bot-deploy/src/botProjectLoggerType.ts rename to Composer/plugins/azurePublish/src/botProjectLoggerType.ts diff --git a/Composer/packages/lib/bot-deploy/src/botProjectRuntimeType.ts b/Composer/plugins/azurePublish/src/botProjectRuntimeType.ts similarity index 100% rename from Composer/packages/lib/bot-deploy/src/botProjectRuntimeType.ts rename to Composer/plugins/azurePublish/src/botProjectRuntimeType.ts diff --git a/Composer/plugins/azurePublish/src/deploy.ts b/Composer/plugins/azurePublish/src/deploy.ts new file mode 100644 index 0000000000..cbe0d8b45e --- /dev/null +++ b/Composer/plugins/azurePublish/src/deploy.ts @@ -0,0 +1,184 @@ +// 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.region; + const luisEndpointKey = settings.luis.endpointKey; + const luisEndpoint = settings.luis.endpoint; + const luisAuthoringEndpoint = settings.luis.authoringEndpoint; + + 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, + luisEndpoint, + luisAuthoringEndpoint, + luisEndpointKey, + luisAuthoringKey, + luisAuthoringRegion, + 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'], + }) + .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 88fbbbdfb3..e428558419 100644 --- a/Composer/plugins/azurePublish/src/index.ts +++ b/Composer/plugins/azurePublish/src/index.ts @@ -3,24 +3,25 @@ import path from 'path'; -import { BotProjectDeploy, BotProjectRuntimeType } from '@bfc/libs/bot-deploy'; import { v4 as uuid } from 'uuid'; import md5 from 'md5'; import { copy, rmdir, emptyDir, readJson, pathExists, writeJson, mkdirSync, writeFileSync } from 'fs-extra'; +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; @@ -34,283 +35,322 @@ interface PublishConfig { [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; + + constructor(mode?: 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'; } - // 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'); + + // path where manifest files will be written + private getManifestDstDir = (key: string, template: string) => + path.resolve(this.getProjectFolder(key, template), 'wwwroot'); + + /*******************************************************************************************************************************/ + /* 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, 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.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 botFiles + * @param settings + * @param srcTemplate + * @param resourcekey + */ + private init = async (botFiles: any, srcTemplate: string, resourcekey: string) => { + const botFolder = this.getBotFolder(resourcekey, this.mode); + const runtimeFolder = this.getRuntimeFolder(resourcekey); + const manifestPath = this.getManifestDstDir(resourcekey, this.mode); + + // clean up from any previous deploys + await this.cleanup(resourcekey); + + // create the temporary folder to contain this project + mkdirSync(runtimeFolder, { recursive: true }); - await this.init(botFiles, fullSettings, runtimeCodePath, resourcekey); + // create the ComposerDialogs/ folder + mkdirSync(botFolder, { recursive: true }); - 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.' - ); + // save bot files and manifest files into wwwroot/ + 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 }); + } + writeFileSync(filePath, file.content); } - const customizeConfiguration: CreateAndDeployResources = { + // 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); + } + + /** + * 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: any, + settings: any, + runtime: any, + botId: string, + profileName: string, + jobId: string, + resourcekey: string, + customizeConfiguration: CreateAndDeployResources + ) => { + const { subscriptionID, + accessToken, 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, + } = 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) => { + console.log(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) { + 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); + } + // 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); } - ); + } + }; - 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'), - runtimeType: - project?.settings?.runtime?.name === 'JS' ? BotProjectRuntimeType.NODE : BotProjectRuntimeType.CSHARP, - }); + /*******************************************************************************************************************************/ + /* 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] = []; + } + 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; + } + } + }; + + /************************************************************************************************** + * plugin methods + *************************************************************************************************/ + publish = async (config: PublishConfig, project, metadata, user) => { + const { + // these are provided by Composer + fullSettings, // all the bot's settings - includes sensitive values not included in projet.settings + templatePath, // templatePath point to the dotnet code todo: SHOULD BE DEPRECATED in favor of pulling this from the runtime template + 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; + + // point to the declarative assets (possibly in remote storage) + const botFiles = project.files; + + // get the bot id from the project + const botId = project.id; + + // generate an id to track this deploy + const jobId = uuid(); + + // get the appropriate runtime template which contains methods to build and configure the runtime + const runtime = composer.getRuntimeByProject(project); + + // 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 + // TODO: this templatePath should come from the runtime instead of this magic parameter + let runtimeCodePath = templatePath; + if ( + project.settings && + project.settings.runtime && + project.settings.runtime.customRuntime === true && + project.settings.runtime.path + ) { + runtimeCodePath = project.settings.runtime.path; + } + + // Initialize the output logs... this.logMessages = ['Publish starting...']; + // Add first "in process" log message const response = { status: 202, result: { @@ -323,64 +363,101 @@ 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); + // Prepare the temporary project + // this writes all the settings to the root settings/appsettings.json file + await this.init(botFiles, runtimeCodePath, resourcekey); + + // 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, + hostname, + luisResource, + language, + }; + this.performDeploymentAction( + project, + mergedSettings, + runtime, + botId, + profileName, + jobId, + resourcekey, + customizeConfiguration + ); + } 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]; + + this.updateHistory(botId, profileName, { status: response.status, ...response.result }); + 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, 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, 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, user) => { - const profileName = config.profileName; - const botId = project.id; - return await this.getHistory(botId, profileName); - }; -} + history = async (config: PublishConfig, project, 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'); -export default async (composer: any): Promise => { await composer.addPublishMethod(azurePublish, schema, instructions); + await composer.addPublishMethod( + azureFunctionsPublish, + schema, + instructions, + 'plugin-azure-functions-publish', + 'Publish bot to Azure Functions (Preview)' + ); }; diff --git a/Composer/plugins/azurePublish/src/luis.ts b/Composer/plugins/azurePublish/src/luis.ts new file mode 100644 index 0000000000..7a910c1b1c --- /dev/null +++ b/Composer/plugins/azurePublish/src/luis.ts @@ -0,0 +1,247 @@ +// 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 { BotProjectDeployLoggerType } from './botProjectLoggerType'; + +const { promisify } = require('util'); + +const luBuild = require('@microsoft/bf-lu/lib/parser/lubuild/builder.js'); +const readdir = 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, + luisEndpoint: string, + luisAuthoringEndpoint: string, + luisEndpointKey: string, + luisAuthoringKey?: string, + luisAuthoringRegion?: string, + luisResource?: string + ) { + 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 || '', + 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, + 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); + } + + // Create the base LUIS config object + // const luisConfig: any = { + // endpoint: luisEndpoint, + // endpointKey: luisEndpointKey, + // authoringRegion: luisAuthoringRegion, + // authoringKey: luisAuthoringRegion, + // }; + + // // Copy the app IDs into the base config + // Object.assign(luisConfig, luisAppIds); + + // // Update deploymentSettings with the luis config + // // TODO: This should be handled by the runtime plugin - writing to appsettings.deployment.json + // // But in this case the change here is being written into the build folder, not "original" version + // const settings: any = await fs.readJson(deploymentSettingsPath); + // settings.luis = luisConfig; + // await fs.writeJson(deploymentSettingsPath, settings, { + // spaces: 4, + // }); + + // 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 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 ${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..41fd4a8c40 --- /dev/null +++ b/Composer/plugins/azurePublish/src/mergeDeep.ts @@ -0,0 +1,39 @@ +// 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); +} + +/** + * Deep merge two objects. + * @param target + * @param ...sources + */ +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/packages/lib/bot-deploy/src/botProjectDeploy.ts b/Composer/plugins/azurePublish/src/provision.ts similarity index 59% rename from Composer/packages/lib/bot-deploy/src/botProjectDeploy.ts rename to Composer/plugins/azurePublish/src/provision.ts index de331f9c3c..8b61d52898 100644 --- a/Composer/packages/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,30 +20,14 @@ import * as rp from 'request-promise'; import { BotProjectDeployConfig } from './botProjectDeployConfig'; import { BotProjectDeployLoggerType } from './botProjectLoggerType'; -import { BotProjectRuntimeType } from './botProjectRuntimeType'; -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 runtimeType: BotProjectRuntimeType; private logger: (string) => any; // Will be assigned by create or deploy @@ -57,42 +40,44 @@ 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 ?? config.runtimeType === BotProjectRuntimeType.CSHARP - ? path.join(this.projPath, 'bin', 'Release', 'netcoreapp3.1') - : this.projPath; - // 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'); - - // path to the built, ready to deploy declarative assets - this.remoteBotPath = config.remoteBotPath ?? path.join(this.publishFolder, 'ComposerDialogs'); + /*******************************************************************************************************************************/ + /* This section has to do with creating new Azure resources + /*******************************************************************************************************************************/ - // path to the ready to deploy generated folder - this.generatedFolder = config.generatedFolder ?? path.join(this.remoteBotPath, 'generated'); + /** + * 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); - // Set the default value to CSHARP - this.runtimeType = config.runtimeType ?? BotProjectRuntimeType.CSHARP; + const result = {}; + Object.assign(result, outputObj, applicationResult); + return result; + } else { + return null; + } } private getErrorMesssage(err) { @@ -122,34 +107,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) { @@ -292,371 +249,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 - .glob('**/*', { - cwd: source, - dot: true, - ignore: ['code.zip'], - }) - .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, - 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 { - // For Node Runtime, don't need to publish the assets, For Csharp runtime, need to compile and publish the assets to a folder - if (this.runtimeType === BotProjectRuntimeType.CSHARP) { - // 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/?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; + 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)}`); } } @@ -951,20 +567,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/yarn.lock b/Composer/plugins/azurePublish/yarn.lock index f1c3108ff5..8e5ebd13ae 100644 --- a/Composer/plugins/azurePublish/yarn.lock +++ b/Composer/plugins/azurePublish/yarn.lock @@ -2,55 +2,55 @@ # yarn lockfile v1 -"@azure/arm-appinsights@^2.1.0": +"@azure/arm-appinsights@2.1.0": version "2.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-appinsights/-/@azure/arm-appinsights-2.1.0.tgz#a14238e5fa1e0ae949d6f65d49020459116f16fd" - integrity sha1-oUI45foeCulJ1vZdSQIEWRFvFv0= + resolved "https://registry.npmjs.org/@azure/arm-appinsights/-/arm-appinsights-2.1.0.tgz#a14238e5fa1e0ae949d6f65d49020459116f16fd" + integrity sha512-wfJgzoz/ZdLpT9TsKtpjWWsKmqQ7BkseEmKrm6gPcrQeINjzpgqex29suhS+Jmq1f4i2ZEofQKA1YHhBknrcsA== 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://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= + resolved "https://registry.npmjs.org/@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== 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://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-botservice/-/@azure/arm-botservice-1.0.0.tgz#439140b234831895dd3c9fdec524fef5fc94c5e3" - integrity sha1-Q5FAsjSDGJXdPJ/exST+9fyUxeM= + resolved "https://registry.npmjs.org/@azure/arm-botservice/-/arm-botservice-1.0.0.tgz#439140b234831895dd3c9fdec524fef5fc94c5e3" + integrity sha512-0+Er+05npiOerhG6FAyFY17bglwHQA5+AmeLIlD+/skAcPI3pvcRfepFTI2XW7CoBWeakY8Ki5w89PPkLFNqjQ== 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://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-deploymentmanager/-/@azure/arm-deploymentmanager-3.0.0.tgz#793ae174d043d2118d520eaec67f0986c319f7a3" - integrity sha1-eTrhdNBD0hGNUg6uxn8JhsMZ96M= + resolved "https://registry.npmjs.org/@azure/arm-deploymentmanager/-/arm-deploymentmanager-3.0.0.tgz#793ae174d043d2118d520eaec67f0986c319f7a3" + integrity sha512-9gv9hUCfAg52Dqxw7W2+B1ytBNitIBEoxd8C1OJnlBH84j5L2S8yLfZsqsyAKbeQE8zkbvVFnrdgO1CS8HUj7g== 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" + resolved "https://registry.npmjs.org/@azure/arm-resources/-/arm-resources-2.1.0.tgz#bb7a3faca0c717656bef93c6f81ff6a9d1d8fa8b" integrity sha512-WpBQt3QwfulWAgss7r6apfKswc6SS8Z005AhQalx618757dX+0kTiizL5XipDZFWq/nlCN2fFv9ba1m4v5x2tg== dependencies: "@azure/ms-rest-azure-js" "^2.0.1" "@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://botbuilder.myget.org/F/botframework-cli/npm/@azure/arm-subscriptions/-/@azure/arm-subscriptions-2.0.0.tgz#4202740b7f65a9d0f16f7903579a615f5de45a92" - integrity sha1-QgJ0C39lqdDxb3kDV5phX13kWpI= + resolved "https://registry.npmjs.org/@azure/arm-subscriptions/-/arm-subscriptions-2.0.0.tgz#4202740b7f65a9d0f16f7903579a615f5de45a92" + integrity sha512-+ys2glK5YgwZ9KhwWblfAQIPABtiB5OdKEpPOpcvr7B5ygYTwZuSUNObX9MRu/MyiRo1zDlUvlxHltBphq/bLQ== 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://botbuilder.myget.org/F/botframework-cli/npm/@azure/cognitiveservices-luis-authoring/-/@azure/cognitiveservices-luis-authoring-4.0.0-preview.3.tgz#68cef01a9efca77c4c5cd4be67b9e0888433af60" - integrity sha1-aM7wGp78p3xMXNS+Z7ngiIQzr2A= - 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://botbuilder.myget.org/F/botframework-cli/npm/@azure/cognitiveservices-luis-runtime/-/@azure/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://botbuilder.myget.org/F/botframework-cli/npm/@azure/graph/-/@azure/graph-5.0.1.tgz#93b89872ad63d40956ddb664d9bcca46cf958179" - integrity sha1-k7iYcq1j1AlW3bZk2bzKRs+VgXk= + resolved "https://registry.npmjs.org/@azure/graph/-/graph-5.0.1.tgz#93b89872ad63d40956ddb664d9bcca46cf958179" + integrity sha512-MMge4Uzl0hK/72h4cGESjX3D5jSwV9Ylwp4HiXp0LdF//vFhYLzsnVRfD1cfkMl5nGlbaqOR3mej4QWAeppjig== 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://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-browserauth/-/@azure/ms-rest-browserauth-0.1.5.tgz#eb73dc9f6ae8c3f4df187e3e3aaf23f2ee940018" - integrity sha1-63Pcn2row/TfGH4+Oq8j8u6UABg= +"@azure/ms-rest-browserauth@0.1.4": + version "0.1.4" + resolved "https://registry.npmjs.org/@azure/ms-rest-browserauth/-/ms-rest-browserauth-0.1.4.tgz#a2b9434c7de08fd3e742b4bfd75427deef1dbab1" + integrity sha512-yV7B+dQzvuHwWpS2KJuu+wU56CdPIUBCJQVG8iidCPXp1zCqGSH5HcbmxHzESMSieDrMeybtPeLx/PNA6Y7YYA== dependencies: "@azure/ms-rest-azure-env" "^1.1.0" "@azure/ms-rest-js" "^1.8.1" @@ -157,54 +149,13 @@ "@azure/ms-rest-nodeauth@3.0.3": version "3.0.3" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.0.3.tgz#e485b9c960da718d0476115e9f0ec550ccbba561" + resolved "https://registry.npmjs.org/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.0.3.tgz#e485b9c960da718d0476115e9f0ec550ccbba561" integrity sha512-/KAgVV68vkOdrx6O3T6qO7thCep4nPbWzkpNIPFN3P6uzEzDIk6BCGgkzabnmkb2kXaf4+IGHs0UMoXSfN/IgQ== dependencies: "@azure/ms-rest-azure-env" "^2.0.0" "@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://botbuilder.myget.org/F/botframework-cli/npm/@azure/ms-rest-nodeauth/-/@azure/ms-rest-nodeauth-3.0.5.tgz#f277ec6e323178fd13c05ca82321ba99c767d4bc" - integrity sha1-8nfsbjIxeP0TwFyoIyG6mcdn1Lw= - dependencies: - "@azure/ms-rest-azure-env" "^2.0.0" - "@azure/ms-rest-js" "^2.0.4" - adal-node "^0.1.28" - -"@bfc/libs/bot-deploy@../../packages/lib/bot-deploy": - version "1.0.0" - 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-preview.141651" - "@microsoft/bf-luis-cli" "^4.10.0-preview.141651" - "@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" - -"@bfc/plugin-loader@../../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-preview.141651": version "4.10.0-preview.141651" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-cli-command/-/@microsoft/bf-cli-command-4.10.0-preview.141651.tgz#680875f716285fb8658da8098a0ee524b07c5765" @@ -220,7 +171,7 @@ fs-extra "^7.0.1" tslib "~1.10.0" -"@microsoft/bf-lu@4.10.0-preview.141651", "@microsoft/bf-lu@^4.10.0-preview.141651": +"@microsoft/bf-lu@4.10.0-preview.141651": version "4.10.0-preview.141651" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-lu/-/@microsoft/bf-lu-4.10.0-preview.141651.tgz#29ed2af803d23ee760354913f5b814873bc1285c" integrity sha1-Ke0q+APSPudgNUkT9bgUhzvBKFw= @@ -244,7 +195,7 @@ semver "^5.5.1" tslib "^1.10.0" -"@microsoft/bf-luis-cli@^4.10.0-preview.141651": +"@microsoft/bf-luis-cli@4.10.0-preview.141651": version "4.10.0-preview.141651" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@microsoft/bf-luis-cli/-/@microsoft/bf-luis-cli-4.10.0-preview.141651.tgz#29ef283f23d9b59841faff4872cb6900b91ec2e8" integrity sha1-Ke8oPyPZtZhB+v9IcstpALkewug= @@ -401,10 +352,10 @@ resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@oclif/screen/-/@oclif/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493" integrity sha1-t0D2hgnfroqnHDpsqxXYFkB7pJM= -"@types/archiver@3.1.0", "@types/archiver@^3.1.0": +"@types/archiver@3.1.0": version "3.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/archiver/-/@types/archiver-3.1.0.tgz#0d5bd922ba5cf06e137cd6793db7942439b1805e" - integrity sha1-DVvZIrpc8G4TfNZ5PbeUJDmxgF4= + resolved "https://registry.npmjs.org/@types/archiver/-/archiver-3.1.0.tgz#0d5bd922ba5cf06e137cd6793db7942439b1805e" + integrity sha512-nTvHwgWONL+iXG+9CX+gnQ/tTOV+qucAjwpXqeUn4OCRMxP42T29FFP/7XaOo0EqqO3TlENhObeZEe7RUJAriw== dependencies: "@types/glob" "*" @@ -425,18 +376,11 @@ "@types/fs-extra@8.1.0": version "8.1.0" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d" integrity sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg== dependencies: "@types/node" "*" -"@types/fs-extra@^8.1.0": - version "8.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/fs-extra/-/@types/fs-extra-8.1.1.tgz#1e49f22d09aa46e19b51c0b013cb63d0d923a068" - integrity sha1-HknyLQmqRuGbUcCwE8tj0NkjoGg= - 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" @@ -470,21 +414,13 @@ "@types/request-promise@4.1.45": version "4.1.45" - resolved "https://registry.yarnpkg.com/@types/request-promise/-/request-promise-4.1.45.tgz#7fcdd39fd920674ab7bfb44197270f225fb4e585" + resolved "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.45.tgz#7fcdd39fd920674ab7bfb44197270f225fb4e585" integrity sha512-KFagTY/a7CzAj86DkhaAtqP0ViYTNam+CfEokSwtPFUIuq9Qrq+Rq2X4nuaB6OJmM2s0xWeiS085Ro7vR0tt9Q== dependencies: "@types/bluebird" "*" "@types/request" "*" -"@types/request-promise@^4.1.45": - version "4.1.46" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/@types/request-promise/-/@types/request-promise-4.1.46.tgz#37df6efae984316dfbfbbe8fcda37f3ba52822f2" - integrity sha1-N99u+umEMW37+76PzaN/O6UoIvI= - 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== @@ -496,7 +432,7 @@ "@types/request@2.48.4": version "2.48.4" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.4.tgz#df3d43d7b9ed3550feaa1286c6eabf0738e6cf7e" + resolved "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz#df3d43d7b9ed3550feaa1286c6eabf0738e6cf7e" integrity sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw== dependencies: "@types/caseless" "*" @@ -542,7 +478,7 @@ adal-angular@^1.0.17: adal-node@0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.2.1.tgz#19e401bd579977448c1a77ce0e5b4c9accdc334e" + resolved "https://registry.npmjs.org/adal-node/-/adal-node-0.2.1.tgz#19e401bd579977448c1a77ce0e5b4c9accdc334e" integrity sha512-C/oasZuTy0NIqh5wPWjG/09XaG+zS7elC8upf1ZVExt9lSRncme4Ejbx8CKYk+wsGgj609y84txtRAXQVvqApg== dependencies: "@types/node" "^8.0.47" @@ -651,10 +587,10 @@ archiver-utils@^2.1.0: normalize-path "^3.0.0" readable-stream "^2.0.0" -archiver@^3.1.1: +archiver@3.1.1: version "3.1.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0" - integrity sha1-nbeBnU2vYK7BD+hrFsuSWM7WbqA= + resolved "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0" + integrity sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg== dependencies: archiver-utils "^2.1.0" async "^2.6.3" @@ -1210,7 +1146,7 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.0.3, fast-glob@^3.1.1: +fast-glob@^3.0.3: version "3.2.4" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" integrity sha1-0grvv5lXk4Pn88xmUpFYybmFVNM= @@ -1285,6 +1221,15 @@ fs-constants@^1.0.0: resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha1-a+Dem+mYzhavivwkSXue6bfM2a0= +fs-extra@8.1.0, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA= + 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://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -1294,15 +1239,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://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha1-SdQ8RaiM2Wd2aMt74bRu/bjS4cA= - 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://botbuilder.myget.org/F/botframework-cli/npm/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" @@ -1375,18 +1311,6 @@ globby@^10.0.1: merge2 "^1.2.3" slash "^3.0.0" -globby@^11.0.0: - version "11.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" - integrity sha1-mivxB6Bo8//qvEmtcCx57ejP01c= - 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.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.4" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" @@ -1446,7 +1370,7 @@ ieee754@^1.1.4: resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q= -ignore@^5.1.1, ignore@^5.1.4: +ignore@^5.1.1: version "5.1.8" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha1-8VCotQo0KJsz4i9YiavU2AFvDlc= @@ -1749,7 +1673,7 @@ map-age-cleaner@^0.1.1: md5@2.2.1: version "2.2.1" - resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + resolved "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= dependencies: charenc "~0.0.1" @@ -1804,7 +1728,7 @@ minimatch@^3.0.4: minimist@1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== ms@2.0.0: @@ -1899,19 +1823,6 @@ p-is-promise@^2.0.0: resolved "https://botbuilder.myget.org/F/botframework-cli/npm/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha1-kYzrrqJIpiz3/6uOO8qMX4gvxC4= -passport-strategy@1.x.x: - version "1.0.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= - -passport@^0.4.1: - version "0.4.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" - integrity sha1-lBRGohy5L8aI2XoIYcOM6fc48nA= - 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://botbuilder.myget.org/F/botframework-cli/npm/password-prompt/-/password-prompt-1.1.2.tgz#85b2f93896c5bd9e9f2d6ff0627fa5af3dc00923" @@ -1930,21 +1841,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-to-regexp@^6.1.0: - version "6.1.0" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-to-regexp/-/path-to-regexp-6.1.0.tgz#0b18f88b7a0ce0bfae6a25990c909ab86f512427" - integrity sha1-Cxj4i3oM4L+uaiWZDJCauG9RJCc= - path-type@^4.0.0: version "4.0.0" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs= -pause@0.0.1: - version "0.0.1" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/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" @@ -2027,17 +1928,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://botbuilder.myget.org/F/botframework-cli/npm/request-promise/-/request-promise-4.2.5.tgz#186222c59ae512f3497dfe4d75a9c8461bd0053c" - integrity sha1-GGIixZrlEvNJff5NdanIRhvQBTw= + resolved "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz#186222c59ae512f3497dfe4d75a9c8461bd0053c" + integrity sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg== 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== @@ -2351,7 +2252,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: uuid@7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + resolved "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2: diff --git a/Composer/plugins/localPublish/.eslintrc.js b/Composer/plugins/localPublish/.eslintrc.js index bcfa12e31d..8cbe448349 100644 --- a/Composer/plugins/localPublish/.eslintrc.js +++ b/Composer/plugins/localPublish/.eslintrc.js @@ -1,10 +1,10 @@ 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, + }, + rules: { + 'security/detect-non-literal-fs-filename': 'off', + }, }; 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 6a53c29280..a925e308e4 100644 --- a/Composer/plugins/localPublish/src/index.ts +++ b/Composer/plugins/localPublish/src/index.ts @@ -11,10 +11,7 @@ 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'; +// import { ComposerPluginRegistration, PublishResponse, PublishPlugin } from '@bfc/plugin-loader'; const stat = promisify(fs.stat); const readDir = promisify(fs.readdir); @@ -25,8 +22,12 @@ 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; @@ -37,18 +38,31 @@ interface PublishConfig { 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; + }; + // config include botId and version, project is content(ComposerDialogs) - publish = async (config: PublishConfig, project, metadata, user): Promise => { + publish = async (config: PublishConfig, project, metadata, user): Promise => { const { templatePath, fullSettings } = config; this.templatePath = templatePath; const botId = project.id; @@ -56,12 +70,16 @@ class LocalPublisher implements PublishPlugin { this.composer.log('Starting publish'); + // set the running bot status + this.setBotStatus(botId, { status: 202, result: { message: 'Reloading...' } }); + // if enableCustomRuntime is not true, initialize the runtime code in a tmp folder // and export the content into that folder as well. const runtimeType = project.settings.runtime?.name || 'C#'; if (!project.settings.runtime || project.settings.runtime.customRuntime !== true) { this.composer.log('Using managed runtime'); - await this.initBot(botId, runtimeType); + + await this.initBot(project); await this.saveContent(botId, version, project.dataDir, user); await this.saveSkillManifests(this.getBotRuntimeDir(botId), project.dataDir, runtimeType); } else if (project.settings.runtime.path && project.settings.runtime.command) { @@ -76,20 +94,18 @@ class LocalPublisher implements PublishPlugin { }; } + // start or restart the bot process + // do NOT await this, as it can take a long time try { - // start or restart the bot process - const url = await this.setBot(botId, version, fullSettings, project.dataDir, runtimeType); - + this.setBot(botId, version, fullSettings, project); 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: { @@ -101,15 +117,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, @@ -168,27 +196,28 @@ class LocalPublisher implements PublishPlugin { } }; - private initBot = async (botId: string, runtimeType: 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 }); + try { + // create bot dir + await mkDir(botDir, { recursive: true }); + await mkDir(runtimeDir, { recursive: true }); - // copy runtime template in folder - await this.copyDir(this.templatePath, runtimeDir); + // create ComposerDialogs and history folder + mkDir(this.getBotAssetsDir(botId), { recursive: true }); + mkDir(this.getHistoryDir(botId), { recursive: true }); - 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' }); + // copy runtime template in folder + this.composer.log('COPY FROM ', this.templatePath, ' to ', runtimeDir); + await this.copyDir(this.templatePath, runtimeDir); + const runtime = this.composer.getRuntimeByProject(project); + await runtime.build(runtimeDir, project); } catch (error) { // delete the folder to make sure build again. await removeDirAndFiles(botDir); @@ -198,17 +227,18 @@ class LocalPublisher implements PublishPlugin { // stop bot this.stopBot(botId); //get previous settings - const settings = JSON.parse( - await readFile(path.resolve(this.getBotDir(botId), 'settings/appsettings.json'), { - encoding: 'utf-8', - }) - ); - if (settings.runtime?.name !== runtimeType) { - // in order to change runtime type - await removeDirAndFiles(this.getBotRuntimeDir(botId)); - // copy runtime template in folder - await this.copyDir(this.templatePath, this.getBotRuntimeDir(botId)); - } + // TODO: Re-enable this for changing type of runtime + // const settings = JSON.parse( + // await readFile(path.resolve(this.getBotDir(botId), 'settings/appsettings.json'), { + // encoding: 'utf-8', + // }) + // ); + // if (settings.runtime?.name !== runtimeType) { + // // in order to change runtime type + // await removeDirAndFiles(this.getBotRuntimeDir(botId)); + // // copy runtime template in folder + // await this.copyDir(this.templatePath, this.getBotRuntimeDir(botId)); + // } } }; @@ -234,41 +264,46 @@ class LocalPublisher implements PublishPlugin { }; // start bot in current version - private setBot = async (botId: string, version: string, settings: any, project: any = undefined, runtimeType) => { + 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, runtimeType); - 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, runtimeType: string): Promise => { + 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?.customRuntime === true ? settings.runtime.command.split(/\s+/) - : runtimeType === 'C#' - ? ['dotnet', 'run', '--project', 'azurewebapp'] - : ['node', 'azurewebapp/lib/index.js']; //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 @@ -295,9 +330,15 @@ class LocalPublisher implements PublishPlugin { } catch (err) { return reject(err); } - LocalPublisher.runningBots[botId] = { process: process, port: port }; + this.setBotStatus(botId, { + process: process, + port: port, + status: 200, + result: { message: 'Runtime started' }, + }); const processLog = this.composer.log.extend(process.pid); - this.addListeners(process, processLog, resolve, reject); + this.addListeners(process, botId, processLog); // resolve, reject); + resolve(); }); }; @@ -316,16 +357,14 @@ class LocalPublisher implements PublishPlugin { 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 && @@ -335,13 +374,14 @@ class LocalPublisher implements PublishPlugin { child.on('exit', (code) => { if (code !== 0) { - reject(erroutput); + 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 } }); + // reject(`Could not launch bot runtime process: ${err.message}`); }); child.on('message', (msg) => { @@ -439,60 +479,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: 'csharp-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}`); - }, - }); - - composer.addRuntimeTemplate({ - key: 'javescript-azurewebapp', - name: 'JS', - startCommand: 'node azurewebapp/lib/index.js', - eject: async (project: any, localDisk: IFileStorage) => { - const sourcePath = path.resolve(__dirname, '../../../../../runtime/node'); - const destPath = path.join(project.dir, 'runtime'); - // const schemaSrcPath = path.join(sourcePath, 'azurewebapp/Schemas'); - // const schemaDstPath = path.join(project.dir, 'schemas'); - if (!(await project.fileStorage.exists(destPath))) { - // used to read bot project template from source (bundled in plugin) - await copyDir(sourcePath, localDisk, destPath, project.fileStorage); - // await copyDir(schemaSrcPath, localDisk, schemaDstPath, project.fileStorage); - return destPath; - } else { - 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 index 48689cf54d..d191cd90f0 100644 --- a/Composer/plugins/localPublish/yarn.lock +++ b/Composer/plugins/localPublish/yarn.lock @@ -1,590 +1,540 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@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" - -"@nodelib/fs.scandir@2.1.3": - version "2.1.3" - resolved "https://registry.npmjs.org/@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.npmjs.org/@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.npmjs.org/@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.14" - resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz#2cf312bcc9f8875df835b0f6040bd89be0a727a9" - integrity sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g== - -archiver-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.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= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.npmjs.org/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.npmjs.org/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.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" - -braces@^3.0.1: - version "3.0.2" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -glob-parent@^5.1.0: - version "5.1.1" - resolved "https://registry.npmjs.org/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.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" - -globby@11.0.0: - version "11.0.0" - resolved "https://registry.npmjs.org/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@^11.0.0: - version "11.0.1" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -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, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - 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= - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -lazystream@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= - -lodash@^4.17.14: - version "4.17.15" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/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.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== - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/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.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -passport-strategy@1.x.x: - version "1.0.0" - resolved "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= - -passport@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" - integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== - dependencies: - passport-strategy "1.x.x" - pause "0.0.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-to-regexp@^6.1.0: - version "6.1.0" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= - -picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -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-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -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" - -run-parallel@^1.1.9: - version "1.1.9" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/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.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -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.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-7.0.1.tgz#95ed6ff3d8c881cbf85f0f05cc3915ef994818ef" - integrity sha512-yqjRXZzSJm9Dbl84H2VDHpM3zMjzSJQ+hn6C4zqd5ilW+7P4ZmLEEqwho9LjP+tGuZlF4xrHQXT0h9QZUS/pWA== - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -zip-stream@^2.1.2: - version "2.1.3" - resolved "https://registry.npmjs.org/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" +# 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/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..8508b6b448 --- /dev/null +++ b/Composer/plugins/runtimes/package.json @@ -0,0 +1,22 @@ +{ + "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": { + "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/copyDir.ts b/Composer/plugins/runtimes/src/copyDir.ts similarity index 100% rename from Composer/plugins/localPublish/src/copyDir.ts rename to Composer/plugins/runtimes/src/copyDir.ts diff --git a/Composer/plugins/runtimes/src/index.ts b/Composer/plugins/runtimes/src/index.ts new file mode 100644 index 0000000000..18e67ed8e0 --- /dev/null +++ b/Composer/plugins/runtimes/src/index.ts @@ -0,0 +1,186 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +import path from 'path'; +import { promisify } from 'util'; + +import rimraf from 'rimraf'; +import * as fs from 'fs-extra'; + +import { copyDir } from './copyDir'; +import { IFileStorage } from './interface'; + +const exec = promisify(require('child_process').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) => { + // TODO: copy source into temporary folder + // copyDir(path.resolve(__dirname, '../../../../../runtime/dotnet'), runtimePath); + + // do stuff + 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 { initOut, initErr } = await exec('dotnet user-secrets init --project azurewebapp', { + cwd: runtimePath, + }); + if (initErr) { + throw new Error(initErr); + } + composer.log('Run dotnet build...'); + const { buildOut, buildErr } = await exec('dotnet build', { cwd: runtimePath }); + if (buildErr) { + throw new Error(buildErr); + } + composer.log('FINISHED BUILDING!'); + }, + run: async (project: any, localDisk: IFileStorage) => { + // do stuff + 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 === 'plugin-azure-publish') { + csproj = 'Microsoft.BotFramework.Composer.WebApp.csproj'; + } else if (profile.type === 'plugin-azure-functions-publish') { + 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 (!fs.pathExistsSync(deployFilePath)) { + const data = `[config]\nproject = ${csproj}`; + + fs.writeFileSync(deployFilePath, data); + } + + // do the dotnet publish + try { + const { stdout, stderr } = await exec( + `dotnet publish "${dotnetProjectPath}" -c release -o "${publishFolder}" -v q`, + { + cwd: runtimePath, + } + ); + composer.log('OUTPUT FROM BUILD', stdout); + if (stderr) { + console.error('ERR FROM BUILD: ', stderr); + } + } catch (err) { + console.error('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'); + // Set the bot and root fields to `ComposerDialogs` - this points the runtime to the appropriate deployed location + // todo: are both necessary? + Object.assign(settings, { bot: 'ComposerDialogs', root: 'ComposerDialogs' }); + if (!(await fs.pathExists(path.dirname(settingsPath)))) { + fs.mkdirSync(path.dirname(settingsPath), { recursive: true }); + } + fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2)); + + // return the location of the build artifiacts + return publishFolder; + }, + 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}`); + }, + }); + + composer.addRuntimeTemplate({ + key: 'node-azurewebapp', + name: 'JS', + startCommand: 'node azurewebapp/lib/index.js', + path: path.resolve(__dirname, '../../../../runtime/node'), + build: async (runtimePath: string, _project: any) => { + // do stuff + composer.log('BUILD THIS JS PROJECT'); + const { installOut, installErr } = exec('npm install', { cwd: path.join(runtimePath, '/core'), stdio: 'pipe' }); + const { install2Out, install2Err } = exec('npm install', { + cwd: path.join(runtimePath, '/azurewebapp'), + }); + 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 { installOut, installErr } = exec('npm install', { cwd: path.join(runtimePath, '/core'), stdio: 'pipe' }); + const { install2Out, install2Err } = exec('npm install', { + cwd: path.join(runtimePath, '/azurewebapp'), + }); + + // write settings to disk in the appropriate location + const settingsPath = path.join(runtimePath, 'ComposerDialogs', 'settings', 'appsettings.json'); + // Set the bot and root fields to `ComposerDialogs` - this points the runtime to the appropriate deployed location + // todo: are both necessary? + Object.assign(settings, { bot: 'ComposerDialogs', root: 'ComposerDialogs' }); + if (!(await fs.pathExists(path.dirname(settingsPath)))) { + fs.mkdirSync(path.dirname(settingsPath), { recursive: true }); + } + fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2)); + + composer.log('BUILD COMPLETE'); + return ''; + }, + eject: async (project: any, localDisk: IFileStorage) => { + const sourcePath = path.resolve(__dirname, '../../../../runtime/node'); + const destPath = path.join(project.dir, 'runtime'); + // const schemaSrcPath = path.join(sourcePath, 'azurewebapp/Schemas'); + // const schemaDstPath = path.join(project.dir, 'schemas'); + if (!(await project.fileStorage.exists(destPath))) { + // used to read bot project template from source (bundled in plugin) + await copyDir(sourcePath, localDisk, destPath, project.fileStorage); + // await copyDir(schemaSrcPath, localDisk, schemaDstPath, project.fileStorage); + return destPath; + } else { + throw new Error(`Runtime already exists at ${destPath}`); + } + }, + }); +}; 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..d191cd90f0 --- /dev/null +++ b/Composer/plugins/runtimes/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/yarn.lock b/Composer/yarn.lock index b655045905..613e1dff3f 100644 --- a/Composer/yarn.lock +++ b/Composer/yarn.lock @@ -5375,6 +5375,16 @@ bfj@6.1.1: hoopy "^0.1.2" tryer "^1.0.0" +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + big-integer@^1.6.48: version "1.6.48" resolved "https://botbuilder.myget.org/F/botbuilder-v4-js-daily/npm/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" @@ -6094,6 +6104,11 @@ check-types@^7.3.0: resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg== +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== + chokidar@^2.0.3: version "2.1.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.2.tgz#9c23ea40b01638439e0513864d362aeacc5ad058" @@ -6500,7 +6515,7 @@ commander@4.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== -commander@^2.20.0, commander@~2.20.3: +commander@^2.18.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -8361,6 +8376,11 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + ejs@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228" @@ -8455,7 +8475,7 @@ elegant-spinner@^1.0.1: resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= -elliptic@^6.0.0, elliptic@^6.5.3: +elliptic@^6.0.0: version "6.5.3" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" integrity sha1-y1nrLv2vc6C9eMzXAVpirW4Pk9Y= @@ -9064,7 +9084,7 @@ express-session@^1.17.0: safe-buffer "5.2.0" uid-safe "~2.1.5" -express@^4.15.2, express@^4.17.1: +express@^4.15.2, express@^4.16.3, express@^4.17.1: version "4.17.1" resolved "https://botbuilder.myget.org/F/botbuilder-declarative/npm/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ= @@ -9372,7 +9392,7 @@ filelist@^1.0.1: dependencies: minimatch "^3.0.4" -filesize@3.6.1: +filesize@3.6.1, filesize@^3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== @@ -10221,7 +10241,7 @@ gzip-size@5.0.0: duplexer "^0.1.1" pify "^3.0.0" -gzip-size@^5.1.1: +gzip-size@^5.0.0, gzip-size@^5.1.1: version "5.1.1" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" integrity sha1-y5vuaS+HwGErIyhAqHOQTkwTUnQ= @@ -10412,7 +10432,7 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hoopy@^0.1.2: +hoopy@^0.1.2, hoopy@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== @@ -10996,6 +11016,11 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-buffer@^1.0.2, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + is-buffer@^2.0.0, is-buffer@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" @@ -11233,7 +11258,7 @@ is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= -is-plain-object@^2.0.1, is-plain-object@^2.0.4: +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== @@ -12151,7 +12176,33 @@ killable@^1.0.1: resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== -kind-of@^2.0.1, kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0, kind-of@^4.0.0, kind-of@^5.0.0, kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" + integrity sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU= + dependencies: + is-buffer "^1.0.2" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0= @@ -12576,7 +12627,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.15, "lodash@>=3.5 <5", lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5: +lodash@4.17.15, "lodash@>=3.5 <5", lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5: version "4.17.15" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg= @@ -13017,6 +13068,11 @@ minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + minimist@1.2.5, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -13097,7 +13153,14 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.2, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1: +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1: version "0.5.5" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8= @@ -13751,6 +13814,11 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + opn@5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" @@ -16474,7 +16542,17 @@ serialize-error@^5.0.0: dependencies: type-fest "^0.8.0" -serialize-javascript@^1.7.0, serialize-javascript@^2.1.2, serialize-javascript@^3.1.0: +serialize-javascript@^1.7.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb" + integrity sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A== + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serialize-javascript@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-3.1.0.tgz#8bf3a9170712664ef2561b44b691eafe399214ea" integrity sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg== @@ -16519,12 +16597,25 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-value@^0.4.3, set-value@^2.0.0, set-value@^3.0.2: - version "3.0.2" - resolved "https://botbuilder.myget.org/F/botframework-cli/npm/set-value/-/set-value-3.0.2.tgz#74e8ecd023c33d0f77199d415409a40f21e61b90" - integrity sha1-dOjs0CPDPQ93GZ1BVAmkDyHmG5A= +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: - is-plain-object "^2.0.4" + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" @@ -16920,7 +17011,7 @@ split-on-first@^1.0.0: resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== -split-string@^3.0.2: +split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== @@ -17786,7 +17877,7 @@ truncate-utf8-bytes@^1.0.0: dependencies: utf8-byte-length "^1.0.1" -tryer@^1.0.0: +tryer@^1.0.0, tryer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== @@ -18565,6 +18656,25 @@ webidl-conversions@^6.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== +webpack-bundle-analyzer@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz#ce6b3f908daf069fd1f7266f692cbb3bded9ba16" + integrity sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.15" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + webpack-cli@^3.3.11: version "3.3.11" resolved "https://botbuilder.myget.org/F/botframework-cli/npm/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" @@ -19034,7 +19144,7 @@ ws@^5.0.0: dependencies: async-limiter "~1.0.0" -ws@^6.2.1: +ws@^6.0.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== diff --git a/runtime/node/azurewebapp/src/index.ts b/runtime/node/azurewebapp/src/index.ts index 8c7d6b85cb..9dc0804bcb 100644 --- a/runtime/node/azurewebapp/src/index.ts +++ b/runtime/node/azurewebapp/src/index.ts @@ -20,14 +20,16 @@ import { ComposerBot } from "../../core/src/index"; // Create HTTP server. const server = restify.createServer(); const argv = require("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 || 3978; server.listen( - process.env.port || process.env.PORT || argv.port || 3978, + port, (): void => { console.log( `\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator` ); console.log( - `\nTo talk to your bot, open echobot.bot file in the Emulator.` + `\nTo talk to your bot, open http://localhost:${port}/api/messages in the Emulator.` ); } );