botframework-webchat 4.14.1 → 4.15.2-main.20220413.af6e8a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.yml +5 -109
- package/.prettierrc.yml +1 -1
- package/README.md +1 -1
- package/lib/AddFullBundle.d.ts.map +1 -1
- package/lib/AddFullBundle.js +1 -2
- package/lib/FullComposer.d.ts.map +1 -1
- package/lib/FullComposer.js +3 -3
- package/lib/FullReactWebChat.js +2 -2
- package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardAttachment.js +3 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardBuilder.js +10 -3
- package/lib/adaptiveCards/Attachment/AdaptiveCardContent.js +2 -2
- package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.d.ts +3 -2
- package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/AdaptiveCardRenderer.js +138 -74
- package/lib/adaptiveCards/Attachment/AnimationCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/AnimationCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/AnimationCardContent.js +3 -1
- package/lib/adaptiveCards/Attachment/AudioCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/AudioCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/AudioCardContent.js +3 -1
- package/lib/adaptiveCards/Attachment/HeroCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/HeroCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/HeroCardContent.js +4 -2
- package/lib/adaptiveCards/Attachment/OAuthCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/OAuthCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/OAuthCardContent.js +3 -1
- package/lib/adaptiveCards/Attachment/ReceiptCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/ReceiptCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/ReceiptCardContent.js +3 -1
- package/lib/adaptiveCards/Attachment/SignInCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/SignInCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/SignInCardContent.js +1 -1
- package/lib/adaptiveCards/Attachment/ThumbnailCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/ThumbnailCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/ThumbnailCardContent.js +3 -1
- package/lib/adaptiveCards/Attachment/VideoCardContent.d.ts +1 -1
- package/lib/adaptiveCards/Attachment/VideoCardContent.d.ts.map +1 -1
- package/lib/adaptiveCards/Attachment/VideoCardContent.js +5 -3
- package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.d.ts +3 -0
- package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.d.ts.map +1 -1
- package/lib/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.js +8 -1
- package/lib/adaptiveCards/Styles/adaptiveCardHostConfig.js +2 -2
- package/lib/adaptiveCards/Styles/createAdaptiveCardsStyleSet.js +2 -2
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.d.ts.map +1 -1
- package/lib/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.js +26 -29
- package/lib/adaptiveCards/normalizeStyleOptions.js +2 -2
- package/lib/addVersion.js +2 -2
- package/lib/createDirectLineSpeechAdapters.d.ts +1 -1
- package/lib/createDirectLineSpeechAdapters.d.ts.map +1 -1
- package/lib/createDirectLineSpeechAdapters.js +1 -1
- package/lib/createFullStyleSet.d.ts +325 -56
- package/lib/createFullStyleSet.d.ts.map +1 -1
- package/lib/createFullStyleSet.js +2 -2
- package/lib/fullBundleDefaultStyleOptions.js +2 -2
- package/lib/index-es5.d.ts +1 -21
- package/lib/index-es5.d.ts.map +1 -1
- package/lib/index-es5.js +4 -44
- package/lib/index-minimal.js +22 -20
- package/lib/index.d.ts +30 -8
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -8
- package/lib/polyfill.d.ts +23 -0
- package/lib/polyfill.d.ts.map +1 -0
- package/lib/polyfill.js +46 -0
- package/lib/renderMarkdown.d.ts.map +1 -1
- package/lib/renderMarkdown.js +34 -6
- package/lib/speech/CustomAudioInputStream.d.ts.map +1 -1
- package/lib/speech/CustomAudioInputStream.js +40 -15
- package/lib/speech/bytesPerSample.d.ts.map +1 -1
- package/lib/speech/bytesPerSample.js +3 -1
- package/lib/speech/createAudioConfig.d.ts.map +1 -1
- package/lib/speech/createAudioConfig.js +9 -3
- package/lib/speech/createMicrophoneAudioConfigAndAudioContext.d.ts.map +1 -1
- package/lib/speech/createMicrophoneAudioConfigAndAudioContext.js +3 -1
- package/lib/speech/getUserMedia.d.ts.map +1 -1
- package/lib/speech/getUserMedia.js +5 -2
- package/package.json +43 -43
- package/src/AddFullBundle.tsx +0 -1
- package/src/FullComposer.tsx +2 -0
- package/src/adaptiveCards/Attachment/AdaptiveCardAttachment.tsx +3 -1
- package/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts +8 -3
- package/src/adaptiveCards/Attachment/AdaptiveCardRenderer.tsx +183 -89
- package/src/adaptiveCards/Attachment/AnimationCardContent.tsx +3 -1
- package/src/adaptiveCards/Attachment/AudioCardContent.tsx +3 -1
- package/src/adaptiveCards/Attachment/HeroCardContent.tsx +4 -2
- package/src/adaptiveCards/Attachment/OAuthCardContent.tsx +3 -1
- package/src/adaptiveCards/Attachment/ReceiptCardContent.tsx +28 -48
- package/src/adaptiveCards/Attachment/SignInCardContent.tsx +1 -1
- package/src/adaptiveCards/Attachment/ThumbnailCardContent.tsx +3 -1
- package/src/adaptiveCards/Attachment/VideoCardContent.tsx +5 -3
- package/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.ts +8 -0
- package/src/adaptiveCards/createAdaptiveCardsAttachmentMiddleware.tsx +0 -1
- package/src/createCognitiveServicesSpeechServicesPonyfillFactory.spec.js +2 -3
- package/src/createDirectLineSpeechAdapters.ts +1 -1
- package/src/index-es5.ts +3 -26
- package/src/polyfill.ts +29 -0
- package/src/renderMarkdown.ts +40 -4
- package/src/speech/CustomAudioInputStream.ts +38 -7
- package/src/speech/bytesPerSample.ts +2 -0
- package/src/speech/createAudioConfig.spec.js +1 -1
- package/src/speech/createAudioConfig.ts +7 -0
- package/src/speech/createMicrophoneAudioConfigAndAudioContext.ts +2 -0
- package/src/speech/getUserMedia.ts +4 -1
- package/.eslintignore +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint no-magic-numbers: ["error", { "ignore": [0, 1, 10, 15, 25, 50, 75] }] */
|
|
2
2
|
|
|
3
|
-
import { DirectLineReceiptCard } from 'botframework-webchat-core';
|
|
4
3
|
import { hooks } from 'botframework-webchat-component';
|
|
5
4
|
import PropTypes from 'prop-types';
|
|
6
5
|
import React, { FC, useMemo } from 'react';
|
|
6
|
+
import type { DirectLineReceiptCard } from 'botframework-webchat-core';
|
|
7
7
|
|
|
8
8
|
import AdaptiveCardBuilder from './AdaptiveCardBuilder';
|
|
9
9
|
import AdaptiveCardRenderer from './AdaptiveCardRenderer';
|
|
@@ -55,54 +55,32 @@ const ReceiptCardContent: FC<ReceiptCardContentProps> = ({ actionPerformedClassN
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
items &&
|
|
58
|
-
items.map(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
image: {
|
|
69
|
-
alt?: string;
|
|
70
|
-
tap?: any;
|
|
71
|
-
url?: string;
|
|
72
|
-
};
|
|
73
|
-
price: string;
|
|
74
|
-
quantity: string;
|
|
75
|
-
subtitle: string;
|
|
76
|
-
tap: any;
|
|
77
|
-
text: string;
|
|
78
|
-
title: string;
|
|
79
|
-
}) => {
|
|
80
|
-
let itemColumns;
|
|
81
|
-
|
|
82
|
-
if (url) {
|
|
83
|
-
const [itemImageColumn, ...columns] = builder.addColumnSet([15, 75, 10]);
|
|
84
|
-
|
|
85
|
-
itemColumns = columns;
|
|
86
|
-
builder.addImage(url, itemImageColumn, imageTap, alt);
|
|
87
|
-
} else {
|
|
88
|
-
itemColumns = builder.addColumnSet([75, 25], undefined, tap && tap);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const [itemTitleColumn, itemPriceColumn] = itemColumns;
|
|
92
|
-
|
|
93
|
-
builder.addTextBlock(
|
|
94
|
-
quantity ? `${title} × ${quantity}` : title,
|
|
95
|
-
{ size: TextSize.Medium, weight: TextWeight.Bolder, wrap: richCardWrapTitle },
|
|
96
|
-
itemTitleColumn
|
|
97
|
-
);
|
|
98
|
-
builder.addTextBlock(subtitle, { size: TextSize.Medium, wrap: richCardWrapTitle }, itemTitleColumn);
|
|
99
|
-
builder.addTextBlock(price, { horizontalAlignment: HorizontalAlignment.Right }, itemPriceColumn);
|
|
100
|
-
|
|
101
|
-
if (text) {
|
|
102
|
-
builder.addTextBlock(text, { size: TextSize.Medium, wrap: richCardWrapTitle }, itemTitleColumn);
|
|
103
|
-
}
|
|
58
|
+
items.map(({ image: { alt, tap: imageTap, url } = {}, price, quantity, subtitle, tap, text, title }) => {
|
|
59
|
+
let itemColumns;
|
|
60
|
+
|
|
61
|
+
if (url) {
|
|
62
|
+
const [itemImageColumn, ...columns] = builder.addColumnSet([15, 75, 10]);
|
|
63
|
+
|
|
64
|
+
itemColumns = columns;
|
|
65
|
+
builder.addImage(url, itemImageColumn, imageTap, alt);
|
|
66
|
+
} else {
|
|
67
|
+
itemColumns = builder.addColumnSet([75, 25], undefined, tap && tap);
|
|
104
68
|
}
|
|
105
|
-
|
|
69
|
+
|
|
70
|
+
const [itemTitleColumn, itemPriceColumn] = itemColumns;
|
|
71
|
+
|
|
72
|
+
builder.addTextBlock(
|
|
73
|
+
quantity ? `${title} × ${quantity}` : title,
|
|
74
|
+
{ size: TextSize.Medium, weight: TextWeight.Bolder, wrap: richCardWrapTitle },
|
|
75
|
+
itemTitleColumn
|
|
76
|
+
);
|
|
77
|
+
builder.addTextBlock(subtitle, { size: TextSize.Medium, wrap: richCardWrapTitle }, itemTitleColumn);
|
|
78
|
+
builder.addTextBlock(price, { horizontalAlignment: HorizontalAlignment.Right }, itemPriceColumn);
|
|
79
|
+
|
|
80
|
+
if (text) {
|
|
81
|
+
builder.addTextBlock(text, { size: TextSize.Medium, wrap: richCardWrapTitle }, itemTitleColumn);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
106
84
|
|
|
107
85
|
if (!nullOrUndefined(vat)) {
|
|
108
86
|
const vatCol = builder.addColumnSet([75, 25]);
|
|
@@ -152,6 +130,8 @@ ReceiptCardContent.defaultProps = {
|
|
|
152
130
|
|
|
153
131
|
ReceiptCardContent.propTypes = {
|
|
154
132
|
actionPerformedClassName: PropTypes.string,
|
|
133
|
+
// PropTypes cannot fully capture TypeScript types.
|
|
134
|
+
// @ts-ignore
|
|
155
135
|
content: PropTypes.shape({
|
|
156
136
|
buttons: PropTypes.array,
|
|
157
137
|
facts: PropTypes.arrayOf(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DirectLineSignInCard } from 'botframework-webchat-core';
|
|
2
1
|
import { hooks } from 'botframework-webchat-component';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import React, { FC } from 'react';
|
|
4
|
+
import type { DirectLineSignInCard } from 'botframework-webchat-core';
|
|
5
5
|
|
|
6
6
|
import CommonCard from './CommonCard';
|
|
7
7
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint no-magic-numbers: ["error", { "ignore": [25, 75] }] */
|
|
2
2
|
|
|
3
|
-
import { DirectLineThumbnailCard } from 'botframework-webchat-core';
|
|
4
3
|
import { hooks } from 'botframework-webchat-component';
|
|
5
4
|
import PropTypes from 'prop-types';
|
|
6
5
|
import React, { FC, useMemo } from 'react';
|
|
6
|
+
import type { DirectLineThumbnailCard } from 'botframework-webchat-core';
|
|
7
7
|
|
|
8
8
|
import AdaptiveCardBuilder from './AdaptiveCardBuilder';
|
|
9
9
|
import AdaptiveCardRenderer from './AdaptiveCardRenderer';
|
|
@@ -68,6 +68,8 @@ ThumbnailCardContent.defaultProps = {
|
|
|
68
68
|
|
|
69
69
|
ThumbnailCardContent.propTypes = {
|
|
70
70
|
actionPerformedClassName: PropTypes.string,
|
|
71
|
+
// PropTypes cannot fully capture TypeScript types.
|
|
72
|
+
// @ts-ignore
|
|
71
73
|
content: PropTypes.shape({
|
|
72
74
|
buttons: PropTypes.array,
|
|
73
75
|
images: PropTypes.arrayOf(
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint react/no-array-index-key: "off" */
|
|
2
2
|
|
|
3
|
-
import { DirectLineVideoCard } from 'botframework-webchat-core';
|
|
4
3
|
import { Components, hooks } from 'botframework-webchat-component';
|
|
5
4
|
import PropTypes from 'prop-types';
|
|
6
5
|
import React, { FC } from 'react';
|
|
6
|
+
import type { DirectLineVideoCard } from 'botframework-webchat-core';
|
|
7
7
|
|
|
8
8
|
import CommonCard from './CommonCard';
|
|
9
9
|
|
|
@@ -46,6 +46,8 @@ VideoCardContent.defaultProps = {
|
|
|
46
46
|
|
|
47
47
|
VideoCardContent.propTypes = {
|
|
48
48
|
actionPerformedClassName: PropTypes.string,
|
|
49
|
+
// PropTypes cannot fully capture TypeScript types.
|
|
50
|
+
// @ts-ignore
|
|
49
51
|
content: PropTypes.shape({
|
|
50
52
|
autoloop: PropTypes.bool,
|
|
51
53
|
autostart: PropTypes.bool,
|
|
@@ -54,10 +56,10 @@ VideoCardContent.propTypes = {
|
|
|
54
56
|
}),
|
|
55
57
|
media: PropTypes.arrayOf(
|
|
56
58
|
PropTypes.shape({
|
|
57
|
-
profile: PropTypes.string
|
|
59
|
+
profile: PropTypes.string,
|
|
58
60
|
url: PropTypes.string.isRequired
|
|
59
61
|
})
|
|
60
|
-
)
|
|
62
|
+
).isRequired
|
|
61
63
|
}).isRequired,
|
|
62
64
|
disabled: PropTypes.bool
|
|
63
65
|
};
|
|
@@ -9,6 +9,14 @@ export default function ({
|
|
|
9
9
|
}: FullBundleStyleOptions) {
|
|
10
10
|
return {
|
|
11
11
|
'&.webchat__adaptive-card-renderer': {
|
|
12
|
+
// Related to #4075.
|
|
13
|
+
// Adaptive Cards assume its host is in "forced border-box" mode.
|
|
14
|
+
// In CSS, the default is "content-box" mode.
|
|
15
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing#values
|
|
16
|
+
'& *': {
|
|
17
|
+
boxSizing: 'border-box'
|
|
18
|
+
},
|
|
19
|
+
|
|
12
20
|
'& .ac-input, & .ac-inlineActionButton, & .ac-quickActionButton': {
|
|
13
21
|
fontFamily: primaryFont
|
|
14
22
|
},
|
|
@@ -16,7 +16,6 @@ export default function createAdaptiveCardsAttachmentMiddleware(): AttachmentMid
|
|
|
16
16
|
// This is not returning a React component, but a render function.
|
|
17
17
|
return () =>
|
|
18
18
|
next =>
|
|
19
|
-
/* eslint-disable-next-line react/display-name */
|
|
20
19
|
(...args) => {
|
|
21
20
|
const [{ attachment }] = args;
|
|
22
21
|
|
|
@@ -19,19 +19,18 @@ beforeEach(() => {
|
|
|
19
19
|
|
|
20
20
|
createPonyfill = require('web-speech-cognitive-services/lib/SpeechServices');
|
|
21
21
|
createCognitiveServicesSpeechServicesPonyfillFactory =
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
22
|
require('./createCognitiveServicesSpeechServicesPonyfillFactory').default;
|
|
24
23
|
|
|
25
24
|
window.AudioContext = class MockAudioContext {
|
|
26
25
|
// eslint-disable-next-line class-methods-use-this
|
|
27
26
|
createMediaStreamSource() {
|
|
28
|
-
// eslint-disable-next-line
|
|
27
|
+
// eslint-disable-next-line no-empty-function
|
|
29
28
|
return { connect: () => {} };
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
// eslint-disable-next-line class-methods-use-this
|
|
33
32
|
createScriptProcessor() {
|
|
34
|
-
// eslint-disable-next-line
|
|
33
|
+
// eslint-disable-next-line no-empty-function
|
|
35
34
|
return { connect: () => {} };
|
|
36
35
|
}
|
|
37
36
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AudioConfig } from 'microsoft-cognitiveservices-speech-sdk';
|
|
2
2
|
import { createAdapters } from 'botframework-directlinespeech-sdk';
|
|
3
|
-
import { DirectLineJSBotConnection } from 'botframework-webchat-core';
|
|
4
3
|
import { WebSpeechPonyfill } from 'botframework-webchat-api';
|
|
4
|
+
import type { DirectLineJSBotConnection } from 'botframework-webchat-core';
|
|
5
5
|
|
|
6
6
|
import CognitiveServicesAudioOutputFormat from './types/CognitiveServicesAudioOutputFormat';
|
|
7
7
|
import CognitiveServicesCredentials from './types/CognitiveServicesCredentials';
|
package/src/index-es5.ts
CHANGED
|
@@ -1,32 +1,9 @@
|
|
|
1
1
|
/* eslint dot-notation: ["error", { "allowPattern": "^WebChat$" }] */
|
|
2
2
|
// window['WebChat'] is required for TypeScript
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import 'core-js/features/array/find-index';
|
|
9
|
-
import 'core-js/features/array/find';
|
|
10
|
-
import 'core-js/features/array/from';
|
|
11
|
-
import 'core-js/features/array/includes';
|
|
12
|
-
import 'core-js/features/array/iterator';
|
|
13
|
-
import 'core-js/features/dom-collections';
|
|
14
|
-
import 'core-js/features/math/sign';
|
|
15
|
-
import 'core-js/features/number/is-finite';
|
|
16
|
-
import 'core-js/features/object/assign';
|
|
17
|
-
import 'core-js/features/object/entries';
|
|
18
|
-
import 'core-js/features/object/from-entries';
|
|
19
|
-
import 'core-js/features/object/is';
|
|
20
|
-
import 'core-js/features/object/values';
|
|
21
|
-
import 'core-js/features/promise';
|
|
22
|
-
import 'core-js/features/promise/finally';
|
|
23
|
-
import 'core-js/features/set';
|
|
24
|
-
import 'core-js/features/string/ends-with';
|
|
25
|
-
import 'core-js/features/string/starts-with';
|
|
26
|
-
import 'core-js/features/symbol';
|
|
27
|
-
|
|
28
|
-
import 'url-search-params-polyfill';
|
|
29
|
-
import 'whatwg-fetch';
|
|
4
|
+
// Importing polyfills required for IE11/ES5.
|
|
5
|
+
import './polyfill';
|
|
6
|
+
|
|
30
7
|
import { version } from './index-minimal';
|
|
31
8
|
import addVersion from './addVersion';
|
|
32
9
|
import defaultCreateDirectLine from './createDirectLine';
|
package/src/polyfill.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Polyfills for IE11 and other ES5 browsers
|
|
2
|
+
// To maintain quality, we prefer polyfills without additives
|
|
3
|
+
// For example, we prefer Promise implementation from "core-js" than "bluebird"
|
|
4
|
+
|
|
5
|
+
// To reduce conflicts with hosting app, we should consider using
|
|
6
|
+
// @babel/plugin-transform-runtime to polyfill in transpiled code directly.
|
|
7
|
+
|
|
8
|
+
import 'core-js/features/array/find-index';
|
|
9
|
+
import 'core-js/features/array/find';
|
|
10
|
+
import 'core-js/features/array/from';
|
|
11
|
+
import 'core-js/features/array/includes';
|
|
12
|
+
import 'core-js/features/array/iterator';
|
|
13
|
+
import 'core-js/features/dom-collections';
|
|
14
|
+
import 'core-js/features/map';
|
|
15
|
+
import 'core-js/features/math/sign';
|
|
16
|
+
import 'core-js/features/number/is-finite';
|
|
17
|
+
import 'core-js/features/object/assign';
|
|
18
|
+
import 'core-js/features/object/entries';
|
|
19
|
+
import 'core-js/features/object/from-entries';
|
|
20
|
+
import 'core-js/features/object/is';
|
|
21
|
+
import 'core-js/features/object/values';
|
|
22
|
+
import 'core-js/features/promise';
|
|
23
|
+
import 'core-js/features/promise/finally';
|
|
24
|
+
import 'core-js/features/set';
|
|
25
|
+
import 'core-js/features/string/ends-with';
|
|
26
|
+
import 'core-js/features/string/starts-with';
|
|
27
|
+
import 'core-js/features/symbol';
|
|
28
|
+
import 'url-search-params-polyfill';
|
|
29
|
+
import 'whatwg-fetch';
|
package/src/renderMarkdown.ts
CHANGED
|
@@ -57,6 +57,18 @@ const TRANSPARENT_GIF = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAA
|
|
|
57
57
|
// This is used for parsing Markdown for external links.
|
|
58
58
|
const internalMarkdownIt = new MarkdownIt();
|
|
59
59
|
|
|
60
|
+
const MARKDOWN_ATTRS_LEFT_DELIMITER = '⟬';
|
|
61
|
+
// Make sure the delimiter is free from any RegExp characters, such as *, ?, etc.
|
|
62
|
+
// IE11 does not support "u" flag and Babel could not remove it. We intentionally omitting the "u" flag here.
|
|
63
|
+
// eslint-disable-next-line security/detect-non-literal-regexp, require-unicode-regexp
|
|
64
|
+
const MARKDOWN_ATTRS_LEFT_DELIMITER_PATTERN = new RegExp(MARKDOWN_ATTRS_LEFT_DELIMITER, 'g');
|
|
65
|
+
|
|
66
|
+
const MARKDOWN_ATTRS_RIGHT_DELIMITER = '⟭';
|
|
67
|
+
// Make sure the delimiter is free from any RegExp characters, such as *, ?, etc.
|
|
68
|
+
// IE11 does not support "u" flag and Babel could not remove it. We intentionally omitting the "u" flag here.
|
|
69
|
+
// eslint-disable-next-line security/detect-non-literal-regexp, require-unicode-regexp
|
|
70
|
+
const MARKDOWN_ATTRS_RIGHT_DELIMITER_PATTERN = new RegExp(MARKDOWN_ATTRS_RIGHT_DELIMITER, 'g');
|
|
71
|
+
|
|
60
72
|
export default function render(
|
|
61
73
|
markdown: string,
|
|
62
74
|
{ markdownRespectCRLF }: { markdownRespectCRLF: boolean },
|
|
@@ -66,16 +78,37 @@ export default function render(
|
|
|
66
78
|
markdown = markdown.replace(/\n\r|\r\n/gu, carriageReturn => (carriageReturn === '\n\r' ? '\r\n' : '\n\r'));
|
|
67
79
|
}
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
// Related to #3165.
|
|
82
|
+
// We only support attributes "aria-label" and should leave other attributes as-is.
|
|
83
|
+
// However, `markdown-it-attrs` remove unrecognized attributes, such as {hello}.
|
|
84
|
+
// Before passing to `markdown-it-attrs`, we will convert known attributes from {aria-label="..."} into ⟬aria-label="..."⟭ (using white tortoise shell brackets).
|
|
85
|
+
// Then, we ask `markdown-it-attrs` to only process the new brackets, so it should only try to process things that we allowlisted.
|
|
86
|
+
// Lastly, we revert tortoise shell brackets back to curly brackets, for unprocessed attributes.
|
|
87
|
+
markdown = markdown
|
|
88
|
+
.replace(/\{\s*aria-label()\s*\}/giu, `${MARKDOWN_ATTRS_LEFT_DELIMITER}aria-label${MARKDOWN_ATTRS_RIGHT_DELIMITER}`)
|
|
89
|
+
.replace(
|
|
90
|
+
/\{\s*aria-label=("[^"]*"|[^\s}]*)\s*\}/giu,
|
|
91
|
+
(_, valueInsideQuotes) =>
|
|
92
|
+
`${MARKDOWN_ATTRS_LEFT_DELIMITER}aria-label=${valueInsideQuotes}${MARKDOWN_ATTRS_RIGHT_DELIMITER}`
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
let html = new MarkdownIt({
|
|
70
96
|
breaks: false,
|
|
71
97
|
html: false,
|
|
72
98
|
linkify: true,
|
|
73
99
|
typographer: true,
|
|
74
100
|
xhtmlOut: true
|
|
75
101
|
})
|
|
76
|
-
.use(markdownItAttrs
|
|
102
|
+
.use(markdownItAttrs, {
|
|
103
|
+
// `markdown-it-attrs` is added for accessibility and allow bot developers to specify `aria-label`.
|
|
104
|
+
// We are allowlisting `aria-label` only as it is allowlisted in `sanitize-html`.
|
|
105
|
+
// Other `aria-*` will be sanitized even we allowlisted here.
|
|
106
|
+
allowedAttributes: ['aria-label'],
|
|
107
|
+
leftDelimiter: MARKDOWN_ATTRS_LEFT_DELIMITER,
|
|
108
|
+
rightDelimiter: MARKDOWN_ATTRS_RIGHT_DELIMITER
|
|
109
|
+
})
|
|
77
110
|
.use(iterator, 'url_new_win', 'link_open', (tokens, index) => {
|
|
78
|
-
const token = tokens[index];
|
|
111
|
+
const token = tokens[+index];
|
|
79
112
|
|
|
80
113
|
token.attrSet('rel', 'noopener noreferrer');
|
|
81
114
|
token.attrSet('target', '_blank');
|
|
@@ -97,8 +130,11 @@ export default function render(
|
|
|
97
130
|
})
|
|
98
131
|
.render(markdown);
|
|
99
132
|
|
|
133
|
+
// Restore attributes not processed by `markdown-it-attrs`.
|
|
134
|
+
// TODO: [P2] #2511 After we fixed our polyfill story, we should use "String.prototype.replaceAll" instead of RegExp for replace all occurrences.
|
|
135
|
+
html = html.replace(MARKDOWN_ATTRS_LEFT_DELIMITER_PATTERN, '{').replace(MARKDOWN_ATTRS_RIGHT_DELIMITER_PATTERN, '}');
|
|
136
|
+
|
|
100
137
|
// The signature from "sanitize-html" module is not correct.
|
|
101
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
102
138
|
// @ts-ignore
|
|
103
139
|
return sanitizeHTML(html, SANITIZE_HTML_OPTIONS);
|
|
104
140
|
}
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type as Type
|
|
23
23
|
} from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.speech/Exports';
|
|
24
24
|
|
|
25
|
+
import { isForbiddenPropertyName } from 'botframework-webchat-core';
|
|
25
26
|
import { v4 } from 'uuid';
|
|
26
27
|
import createDeferred, { DeferredPromise } from 'p-defer-es5';
|
|
27
28
|
|
|
@@ -88,9 +89,20 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
88
89
|
id: options.id || v4().replace(/-/gu, '')
|
|
89
90
|
};
|
|
90
91
|
|
|
92
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
93
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
91
94
|
this[SYMBOL_DEVICE_INFO_DEFERRED] = createDeferred<DeviceInfo>();
|
|
95
|
+
|
|
96
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
97
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
92
98
|
this[SYMBOL_EVENTS] = new EventSource<AudioSourceEvent>();
|
|
99
|
+
|
|
100
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
101
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
93
102
|
this[SYMBOL_FORMAT_DEFERRED] = createDeferred<AudioStreamFormatImpl>();
|
|
103
|
+
|
|
104
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
105
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
94
106
|
this[SYMBOL_OPTIONS] = normalizedOptions;
|
|
95
107
|
}
|
|
96
108
|
|
|
@@ -101,9 +113,10 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
101
113
|
|
|
102
114
|
/** Gets the event source for listening to events. */
|
|
103
115
|
// ESLint: This code will only works in browsers other than IE11. Only works in ES5 is okay.
|
|
104
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
105
116
|
// @ts-ignore Accessors are only available when targeting ECMAScript 5 and higher.ts(1056)
|
|
106
117
|
get events(): EventSource<AudioSourceEvent> {
|
|
118
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
119
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
107
120
|
return this[SYMBOL_EVENTS];
|
|
108
121
|
}
|
|
109
122
|
|
|
@@ -114,16 +127,19 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
114
127
|
// Speech SDK quirks: In normal speech recognition, getter of "format" is called only after "attach".
|
|
115
128
|
// But in Direct Line Speech, it is called before "attach".
|
|
116
129
|
// ESLint: This code will only works in browsers other than IE11. Only works in ES5 is okay.
|
|
117
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
118
130
|
// @ts-ignore Accessors are only available when targeting ECMAScript 5 and higher.ts(1056)
|
|
119
131
|
get format(): Promise<AudioStreamFormatImpl> {
|
|
120
132
|
this.debug('Getting "format".');
|
|
121
133
|
|
|
134
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
135
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
122
136
|
return this[SYMBOL_FORMAT_DEFERRED].promise;
|
|
123
137
|
}
|
|
124
138
|
|
|
125
139
|
/** Gets the ID of this audio stream. */
|
|
126
140
|
id(): string {
|
|
141
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
142
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
127
143
|
return this[SYMBOL_OPTIONS].id;
|
|
128
144
|
}
|
|
129
145
|
|
|
@@ -131,6 +147,8 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
131
147
|
// Speech SDK quirks: In JavaScript, onXxx means "listen to event XXX".
|
|
132
148
|
// Instead, in Speech SDK, it means "emit event XXX".
|
|
133
149
|
protected onEvent(event: AudioSourceEvent): void {
|
|
150
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
151
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
134
152
|
this[SYMBOL_EVENTS].onEvent(event);
|
|
135
153
|
Events.instance.onEvent(event);
|
|
136
154
|
}
|
|
@@ -191,7 +209,6 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
191
209
|
|
|
192
210
|
// Speech SDK quirks: Although "close" is marked as abstract, it is never called in our observations.
|
|
193
211
|
// ESLint: Speech SDK requires this function, but we are not implementing it.
|
|
194
|
-
// eslint-disable-next-line class-methods-use-this
|
|
195
212
|
close(): void {
|
|
196
213
|
this.debug('Callback for "close".');
|
|
197
214
|
|
|
@@ -215,7 +232,8 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
215
232
|
/** Log the message to console if `debug` is set to `true`. */
|
|
216
233
|
private debug(message, ...args) {
|
|
217
234
|
// ESLint: For debugging, will only log when "debug" is set to "true".
|
|
218
|
-
//
|
|
235
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
236
|
+
// eslint-disable-next-line no-console, security/detect-object-injection
|
|
219
237
|
this[SYMBOL_OPTIONS].debug && console.info(`CustomAudioInputStream: ${message}`, ...args);
|
|
220
238
|
}
|
|
221
239
|
|
|
@@ -240,7 +258,13 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
240
258
|
|
|
241
259
|
// Although only getter of "format" is called before "attach" (in Direct Line Speech),
|
|
242
260
|
// we are handling both "deviceInfo" and "format" in similar way for uniformity.
|
|
261
|
+
|
|
262
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
263
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
243
264
|
this[SYMBOL_DEVICE_INFO_DEFERRED].resolve(deviceInfo);
|
|
265
|
+
|
|
266
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
267
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
244
268
|
this[SYMBOL_FORMAT_DEFERRED].resolve(
|
|
245
269
|
new AudioStreamFormatImpl(format.samplesPerSec, format.bitsPerSample, format.channels)
|
|
246
270
|
);
|
|
@@ -300,21 +324,28 @@ abstract class CustomAudioInputStream extends AudioInputStream {
|
|
|
300
324
|
|
|
301
325
|
/** Gets the device information. */
|
|
302
326
|
// ESLint: This code will only works in browsers other than IE11. Only works in ES5 is okay.
|
|
303
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
304
327
|
// @ts-ignore Accessors are only available when targeting ECMAScript 5 and higher.ts(1056)
|
|
305
328
|
get deviceInfo(): Promise<ISpeechConfigAudioDevice> {
|
|
306
329
|
this.debug(`Getting "deviceInfo".`);
|
|
307
330
|
|
|
331
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
332
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
308
333
|
return Promise.all([this[SYMBOL_DEVICE_INFO_DEFERRED].promise, this[SYMBOL_FORMAT_DEFERRED].promise]).then(
|
|
309
334
|
([{ connectivity, manufacturer, model, type }, { bitsPerSample, channels, samplesPerSec }]) => ({
|
|
310
335
|
bitspersample: bitsPerSample,
|
|
311
336
|
channelcount: channels,
|
|
312
337
|
connectivity:
|
|
313
|
-
typeof connectivity === 'string'
|
|
338
|
+
typeof connectivity === 'string' && !isForbiddenPropertyName(connectivity)
|
|
339
|
+
? // Mitigated through denylisting.
|
|
340
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
341
|
+
Connectivity[connectivity]
|
|
342
|
+
: connectivity || Connectivity.Unknown,
|
|
314
343
|
manufacturer: manufacturer || '',
|
|
315
344
|
model: model || '',
|
|
316
345
|
samplerate: samplesPerSec,
|
|
317
|
-
|
|
346
|
+
// Mitigated through denylisting.
|
|
347
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
348
|
+
type: typeof type === 'string' && !isForbiddenPropertyName(type) ? Type[type] : type || Type.Unknown
|
|
318
349
|
})
|
|
319
350
|
);
|
|
320
351
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export default function bytesPerSample(settings: MediaTrackSettings) {
|
|
2
|
+
// `channelCount` is not on @types/web@0.0.54 yet, related to https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1290.
|
|
3
|
+
// @ts-ignore
|
|
2
4
|
// eslint-disable-next-line no-magic-numbers
|
|
3
5
|
return ((settings.sampleSize as number) >> 3) * (settings.channelCount as number) * (settings.sampleRate as number);
|
|
4
6
|
}
|
|
@@ -43,7 +43,12 @@ class CreateAudioConfigAudioInputStream extends CustomAudioInputStream {
|
|
|
43
43
|
|
|
44
44
|
super({ debug });
|
|
45
45
|
|
|
46
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
47
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
46
48
|
this[SYMBOL_ATTACH] = attach;
|
|
49
|
+
|
|
50
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
51
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
47
52
|
this[SYMBOL_TURN_OFF] = turnOff;
|
|
48
53
|
}
|
|
49
54
|
|
|
@@ -55,6 +60,8 @@ class CreateAudioConfigAudioInputStream extends CustomAudioInputStream {
|
|
|
55
60
|
deviceInfo: DeviceInfo;
|
|
56
61
|
format: Format;
|
|
57
62
|
}> {
|
|
63
|
+
// False alarm: indexer is a constant of type Symbol.
|
|
64
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
58
65
|
return this[SYMBOL_ATTACH](audioNodeId);
|
|
59
66
|
}
|
|
60
67
|
|
|
@@ -22,6 +22,8 @@ const PCM_RECORDER_HARDCODED_SETTINGS: MediaTrackSettings = Object.freeze({
|
|
|
22
22
|
|
|
23
23
|
const PCM_RECORDER_HARDCODED_FORMAT: Format = Object.freeze({
|
|
24
24
|
bitsPerSample: PCM_RECORDER_HARDCODED_SETTINGS.sampleSize,
|
|
25
|
+
// `channelCount` is not on @types/web@0.0.54 yet, related to https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1290.
|
|
26
|
+
// @ts-ignore
|
|
25
27
|
channels: PCM_RECORDER_HARDCODED_SETTINGS.channelCount,
|
|
26
28
|
samplesPerSec: PCM_RECORDER_HARDCODED_SETTINGS.sampleRate
|
|
27
29
|
});
|
|
@@ -5,8 +5,11 @@ export default function getUserMedia(constraints: MediaStreamConstraints): Promi
|
|
|
5
5
|
return navigator.mediaDevices.getUserMedia(constraints);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
//
|
|
8
|
+
// We are intentionally using the deprecated `navigator.getUserMedia` to make sure backward compatibility.
|
|
9
|
+
// @ts-ignore
|
|
9
10
|
if (typeof navigator.getUserMedia !== 'undefined') {
|
|
11
|
+
// We are intentionally using the deprecated `navigator.getUserMedia` to make sure backward compatibility.
|
|
12
|
+
// @ts-ignore
|
|
10
13
|
return new Promise((resolve, reject) => navigator.getUserMedia(constraints, resolve, reject));
|
|
11
14
|
}
|
|
12
15
|
|
package/.eslintignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/src/tsconfig.json
|