Skip to content

Commit

Permalink
Merge branch 'main' into julong/publish-code-clean
Browse files Browse the repository at this point in the history
* main:
  fix: add more missing formatMessage calls (microsoft#4144)
  feat: electron splash screen (microsoft#4119)
  feat: Add QnA files to dispatch model in skill manifest (microsoft#3985)
  fix: check whether operation is under current project folder (microsoft#4078)
  update localization and add missing "example" string (microsoft#4138)
  fix: defense invocation of `value.match()` (microsoft#4110)
  fix: checkReturnType in ExpressionValidation throws unexpected error (microsoft#4112)
  chore(deps): Bump tree-kill from 1.2.1 to 1.2.2 in /Composer (microsoft#4035)
  build: fix docker builds in ACR (microsoft#3986)
  fix: security: downgrade node-forge to 0.9.0 (microsoft#4133)
  chore: update archiver to fix security warning (microsoft#4116)
  • Loading branch information
alanlong9278 committed Sep 16, 2020
2 parents 73bfea1 + 5668e0b commit 3a51407
Show file tree
Hide file tree
Showing 36 changed files with 850 additions and 2,376 deletions.
7 changes: 6 additions & 1 deletion Composer/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
**/package-lock.json
**/dist
**/build
**/es
**/server/data.json
**/server/tmp.zip
# not ignore all lib folder because packages/lib, so probably we should rename that to libs
packages/lib/*/lib

Dockerfile
.dockerignore

# ignore local bots
plugins/localPublish/hostedBots/*

# ignore test
coverage
9 changes: 6 additions & 3 deletions Composer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@

FROM node:12-alpine as build

ARG YARN_ARGS

WORKDIR /src/Composer
COPY . .
# run yarn install as a distinct layer
RUN yarn install --frozen-lock-file --verbose
RUN yarn install --frozen-lock-file $YARN_ARGS
ENV NODE_OPTIONS "--max-old-space-size=4096"
ENV NODE_ENV "production"
RUN yarn build:prod --verbose
RUN yarn build:prod $YARN_ARGS



FROM node:12-alpine as composerbasic
ARG YARN_ARGS

WORKDIR /app/Composer
COPY --from=build /src/Composer/yarn.lock .
Expand All @@ -37,7 +40,7 @@ COPY --from=build /src/Composer/packages/ui-plugins ./packages/ui-plugins
COPY --from=build /src/Composer/plugins ./plugins

ENV NODE_ENV "production"
RUN yarn --production --frozen-lockfile --force --verbose && yarn cache clean
RUN yarn --production --frozen-lockfile --force $YARN_ARGS && yarn cache clean
WORKDIR /app/Composer

FROM composerbasic
Expand Down
2 changes: 1 addition & 1 deletion Composer/cypress/integration/NotificationPage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ context('Notification Page', () => {
cy.withinEditor('PropertyEditor', () => {
cy.findByText('Condition').should('exist');
cy.findByTestId('expression-type-dropdown-Condition').focus().should('contain.text', 'expression');
cy.get('#root\\.condition').click().type('foo = bar', { delay: 200 });
cy.get('#root\\.condition').click().type('=foo = bar', { delay: 200 });
cy.findByTestId('FieldErrorMessage').should('exist');
});

Expand Down
2 changes: 1 addition & 1 deletion Composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"elliptic": "^6.5.3",
"@babel/parser": "^7.11.3",
"bl": "^2.2.1",
"node-forge": "^0.10.0"
"node-forge": "0.9.0"
},
"engines": {
"node": ">=12"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { FieldProps } from '@bfc/extension-client';
import startCase from 'lodash/startCase';
import formatMessage from 'format-message';

export function getUiLabel(props: FieldProps): string | false | undefined {
const { uiOptions, schema, name, value, label } = props;
Expand Down Expand Up @@ -46,7 +47,7 @@ export function getUiPlaceholder(props: FieldProps): string | undefined {
} else if (placeholder) {
fieldUIPlaceholder = placeholder;
} else if (schema && Array.isArray(schema.examples) && schema.examples.length > 0) {
fieldUIPlaceholder = `ex. ${schema.examples.join(', ')}`;
fieldUIPlaceholder = formatMessage('ex. { example }', { example: schema.examples.join(', ') });
}

if (fieldUIPlaceholder && schema.pattern) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,34 +187,47 @@ describe('generateDispatchModels', () => {
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu' } }];
const selectedTriggers = [];
const luFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const qnaFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual({});
});

it("should return empty object if the schema doesn't include dispatchModels", () => {
const schema = { properties: {} };
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu' } }];
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu.qna' } }];
const selectedTriggers = [{ $kind: SDKKinds.OnIntent, intent: 'testIntent' }];
const luFiles: any = [{ id: 'test.en-us' }, { id: 'test.fr-FR' }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const luFiles: any = [
{ id: 'test.en-us', empty: false },
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual({});
});

it('should return empty object if the recognizer type is not luis', () => {
const schema = { properties: {} };
const dialogs: any = [{ id: 'test', content: {} }];
const selectedTriggers = [{ $kind: SDKKinds.OnIntent, intent: 'testIntent' }];
const luFiles: any = [{ id: 'test.en-us' }, { id: 'test.fr-FR' }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const luFiles: any = [
{ id: 'test.en-us', empty: false },
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles = [];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual({});
});

it('should return dispatch models', () => {
const schema = { properties: { dispatchModels: {} } };
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu' }, isRoot: true }];
const dialogs: any = [{ id: 'test', content: { recognizer: 'test.lu.qna' }, isRoot: true }];
const selectedTriggers = [{ $kind: SDKKinds.OnIntent, intent: 'testIntent' }];
const luFiles: any = [{ id: 'test.en-us' }, { id: 'test.fr-FR' }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles);
const luFiles: any = [
{ id: 'test.en-us', empty: false },
{ id: 'test.fr-FR', empty: false },
];
const qnaFiles: any = [{ id: 'test.es-es', empty: false }];
const result = generateDispatchModels(schema, dialogs, selectedTriggers, luFiles, qnaFiles);
expect(result).toEqual(
expect.objectContaining({
dispatchModels: {
Expand All @@ -223,15 +236,23 @@ describe('generateDispatchModels', () => {
{
name: 'test',
contentType: 'application/lu',
url: `<test.en-us url>`,
url: `<test.en-us.lu url>`,
description: '<description>',
},
],
'fr-FR': [
{
name: 'test',
contentType: 'application/lu',
url: `<test.fr-FR url>`,
url: `<test.fr-FR.lu url>`,
description: '<description>',
},
],
'es-es': [
{
name: 'test',
contentType: 'application/qna',
url: `<test.es-es.qna url>`,
description: '<description>',
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import get from 'lodash/get';
import { DialogInfo, DialogSchemaFile, ITrigger, SDKKinds, SkillManifest, LuFile } from '@bfc/shared';
import { DialogInfo, DialogSchemaFile, ITrigger, SDKKinds, SkillManifest, LuFile, QnAFile } from '@bfc/shared';
import { JSONSchema7 } from '@bfc/extension-client';

import { Activities, Activity, activityHandlerMap, ActivityTypes, DispatchModels } from './constants';
Expand All @@ -17,6 +17,7 @@ export const generateSkillManifest = (
dialogs: DialogInfo[],
dialogSchemas: DialogSchemaFile[],
luFiles: LuFile[],
qnaFiles: QnAFile[],
selectedTriggers: ITrigger[],
selectedDialogs: Partial<DialogInfo>[]
) => {
Expand All @@ -41,7 +42,7 @@ export const generateSkillManifest = (
}, []);

const activities = generateActivities(dialogSchemas, triggers, resolvedDialogs);
const dispatchModels = generateDispatchModels(schema, dialogs, triggers, luFiles);
const dispatchModels = generateDispatchModels(schema, dialogs, triggers, luFiles, qnaFiles);
const definitions = getDefinitions(dialogSchemas, resolvedDialogs);

return {
Expand Down Expand Up @@ -104,7 +105,8 @@ export const generateDispatchModels = (
schema: JSONSchema7,
dialogs: DialogInfo[],
selectedTriggers: any[],
luFiles: LuFile[]
luFiles: LuFile[],
qnaFiles: QnAFile[]
): { dispatchModels?: DispatchModels } => {
const intents = selectedTriggers.filter(({ $kind }) => $kind === SDKKinds.OnIntent).map(({ intent }) => intent);
const { id: rootId } = dialogs.find((dialog) => dialog?.isRoot) || {};
Expand All @@ -114,16 +116,46 @@ export const generateDispatchModels = (
return luId === rootId;
});

if (!intents.length || !schema.properties?.dispatchModels) {
const rootQnAFiles = qnaFiles.filter(({ id: qnaFileId }) => {
const [qnaId] = qnaFileId.split('.');
return qnaId === rootId;
});

if (!schema.properties?.dispatchModels) {
return {};
}

const languages = rootLuFiles.reduce((acc, { id }) => {
const luLanguages = intents.length
? rootLuFiles.reduce((acc, { empty, id }) => {
const [name, locale] = id.split('.');
const { content = {} } = dialogs.find(({ id }) => id === name) || {};
const { recognizer = '' } = content;

if (!recognizer.includes('.lu') || empty) {
return acc;
}

return {
...acc,
[locale]: [
...(acc[locale] ?? []),
{
name,
contentType: 'application/lu',
url: `<${id}.lu url>`,
description: '<description>',
},
],
};
}, {})
: {};

const languages = rootQnAFiles.reduce((acc, { empty, id }) => {
const [name, locale] = id.split('.');
const { content = {} } = dialogs.find(({ id }) => id === name) || {};
const { recognizer = '' } = content;

if (!''.endsWith.call(recognizer, '.lu')) {
if (!recognizer.includes('.qna') || empty) {
return acc;
}

Expand All @@ -133,19 +165,21 @@ export const generateDispatchModels = (
...(acc[locale] ?? []),
{
name,
contentType: 'application/lu',
url: `<${id} url>`,
contentType: 'application/qna',
url: `<${id}.qna url>`,
description: '<description>',
},
],
};
}, {});
}, luLanguages);

const dispatchModels = {
...(Object.keys(languages).length ? { languages } : {}),
...(intents.length ? { intents } : {}),
};

return {
dispatchModels: {
...(Object.keys(languages).length ? { languages } : {}),
...(intents.length ? { intents } : {}),
},
...(Object.keys(dispatchModels).length ? { dispatchModels } : {}),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
dispatcherState,
luFilesState,
skillManifestsState,
qnaFilesState,
} from '../../../recoilModel';

import { editorSteps, ManifestEditorSteps, order } from './constants';
Expand All @@ -34,6 +35,7 @@ const ExportSkillModal: React.FC<ExportSkillModalProps> = ({ onSubmit, onDismiss
const dialogs = useRecoilValue(dialogsState);
const dialogSchemas = useRecoilValue(dialogSchemasState);
const luFiles = useRecoilValue(luFilesState);
const qnaFiles = useRecoilValue(qnaFilesState);
const skillManifests = useRecoilValue(skillManifestsState);
const { updateSkillManifest } = useRecoilValue(dispatcherState);

Expand All @@ -59,6 +61,7 @@ const ExportSkillModal: React.FC<ExportSkillModalProps> = ({ onSubmit, onDismiss
dialogs,
dialogSchemas,
luFiles,
qnaFiles,
selectedTriggers,
selectedDialogs
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
"asarUnpack": [
"build/assets",
"build/templates",
"resources/composerIcon_1024x1024.png"
"resources/composerIcon_1024x1024.png",
"resources/ms_logo.svg"
],
"files": [
"build",
"resources/composerIcon_1024x1024.png"
"resources/composerIcon_1024x1024.png",
"resources/ms_logo.svg"
],
"extraResources": [
{
Expand Down
2 changes: 1 addition & 1 deletion Composer/packages/electron-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"test:watch": "jest --watch"
},
"devDependencies": {
"@types/archiver": "^3.0.0",
"@types/archiver": "^3.1.0",
"@types/body-parser": "^1.17.0",
"@types/compression": "^1.0.1",
"@types/cookie-parser": "^1.4.1",
Expand Down
39 changes: 39 additions & 0 deletions Composer/packages/electron-server/resources/ms_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 3a51407

Please sign in to comment.