diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0ad65c962e..c640447209 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,4 +6,6 @@ /Composer/ @cwhitten @boydc2014 @a-b-r-o-w-n @beyackle @srinaath @tonyanziano @geoffcoxmsft @hatpick +/Composer/packages/adaptive-flow @yeze322 @cwhitten @boydc2014 @a-b-r-o-w-n + /docs/ @cwhitten @boydc2014 @benbrown @geoffcoxmsft diff --git a/.github/actions/conventional-pr/package-lock.json b/.github/actions/conventional-pr/package-lock.json index 62d84762b7..09d6d3ec4e 100644 --- a/.github/actions/conventional-pr/package-lock.json +++ b/.github/actions/conventional-pr/package-lock.json @@ -235,9 +235,9 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "npm-run-path": { "version": "2.0.2", diff --git a/Composer/.dockerignore b/Composer/.dockerignore index 19245eab5f..d942adbebd 100644 --- a/Composer/.dockerignore +++ b/Composer/.dockerignore @@ -7,7 +7,6 @@ **/server/tmp.zip # not ignore all lib folder because packages/lib, so probably we should rename that to libs packages/lib/*/lib -packages/extensions/*/lib Dockerfile .dockerignore diff --git a/Composer/.gitignore b/Composer/.gitignore index 1603d74bba..756c18e624 100644 --- a/Composer/.gitignore +++ b/Composer/.gitignore @@ -6,3 +6,10 @@ cypress/results cypress/videos TestBots/ + +l10ntemp/ + +packages/server/schemas/*.schema +packages/server/schemas/*.uischema +!packages/server/schemas/sdk.schema +!packages/server/schemas/sdk.uischema diff --git a/Composer/Dockerfile b/Composer/Dockerfile index 4f6067ba23..cd3532955d 100644 --- a/Composer/Dockerfile +++ b/Composer/Dockerfile @@ -25,7 +25,11 @@ WORKDIR /app/Composer COPY --from=build /src/Composer/yarn.lock . COPY --from=build /src/Composer/package.json . COPY --from=build /src/Composer/packages/client ./packages/client -COPY --from=build /src/Composer/packages/extensions ./packages/extensions +COPY --from=build /src/Composer/packages/adaptive-flow ./packages/adaptive-flow +COPY --from=build /src/Composer/packages/adaptive-form ./packages/adaptive-form +COPY --from=build /src/Composer/packages/extension ./packages/extension +COPY --from=build /src/Composer/packages/extension-client ./packages/extension-client +COPY --from=build /src/Composer/packages/intellisense ./packages/intellisense COPY --from=build /src/Composer/packages/server ./packages/server COPY --from=build /src/Composer/packages/lib ./packages/lib COPY --from=build /src/Composer/packages/tools ./packages/tools diff --git a/Composer/README.md b/Composer/README.md index c7142f2575..f2b9bc0bc4 100644 --- a/Composer/README.md +++ b/Composer/README.md @@ -30,166 +30,3 @@ If you run into the issue of `There appears to be trouble with your network conn ## Documentation The documentation for Composer [can be found here](/toc.md). - -## Extension Framework -Composer is built on top of an extension framework, which allows anyone to provide an extension as the editor of certain type of bot assets. - -All editors, 1st party or 3rd party, are loaded in the same way by the extension framework. - -Non-editor extensions are not supported at this time, though the mechanisms for providing extensions will scale outside the dialog editor's. - -### What's an extension? what's in it -Each extension is a standalone React component package ([why React component](#why-react-component)) under Composer's `/packages/extensions` folder, which implements the extension `interface`. - -Composer is managed via yarn workspaces, producing such a folder layout. -``` -|- Composer - |- package.json // define the workspaces - |- packages - |- client // composer main app - |- server // composer api server - |- extensions - |- package.json // put all extension as one package - |- adaptive-form // dialog property editor - |- lib - |- shared // shared code -``` - -All extensions under `/extensions` folder will be eventually packed into one `extensions` package, then the `client` package will depends on this `extensions` package. - -### Extension Interface -The extension interface defines the way how an extension comminutes to the host. - -In React world, interface means the props passed into a component. An extension will be passed ino 3 props: -- data:any. which is the data to be edited by this editor. -- onChange: (newData) => void. which is the callback enables an editor to save the edited data. -- [shellApi](#shell-api). which is a set of apis providing other capabilities than data in\out. - -The rendering code of an extension will be sth like this: -``` - import SomeEditor from 'someplace' - - -``` - -#### data in\out story - -With this interface, it's pretty clear how data is in\out extension. Data is passed in through `data` prop, and been saved with `onChange` prop. - -#### shell api - -Shell api is a set of apis that provides other important functionalities that empower an extension to provide a more powerful and smooth editing experience. including - -* OpenSubEditor - ``` - openSubEditor(location:string, data:any, onChange:(newData:any) => void) - ``` - This is the most important api that support a [multiple editors](#multiple-editors) scenario, which allows an editor to delegate some editing task to another editor, and listen the changes. - - Note that, this api doesn't allow you to specify the type or the name of the sub editor. You only get to specify a data, the shell will use a centralized way to manage how editors are registered and picked up. See registration section in the below for more details. - - We may suppport other forms of openSubEditor later, but we expect this is the mosted used one. - -* ObjectGraph - - TBD, this will be an api that enable each extension have the knowledge of a global object graph. -* Alert -* ReadFile -* Prompt - -### Why React component - -There are many options to choose when picking an abstraction for an extension. Different level abstractions have different impacts on many aspects, like developing, testing, debuging and running the extension. - -A low-level abstraction like HTML page will give us perfect isolation, great flexibilty (use whatever language you want to build that), but usually result in a relatively high amount of effort to develop a robust api between host and extension because it's using the low-level messaging primitives, and also not good for performance because of the extreme isolation. - -A high-level abstraction like React component, will cost a little bit on isolation, but gain the best support from a mature and powerful framework, in every cycle of the development of extensions. It will help most of boosting the productivity, simplifying the architecure, and gain the best performance. - -Based on our scenario, we will use React as a start point, and host the extension in an `