diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 66438a7fd4..11c8564e67 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -38,5 +38,8 @@ jobs: - name: yarn run: yarn --frozen-lockfile + - name: yarn build + run: yarn build + - name: yarn lint run: yarn lint diff --git a/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.js b/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.js index f35f2a3bf8..34fa721c40 100644 --- a/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.js +++ b/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.js @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -17,10 +17,10 @@ }, "dependencies": { "@microsoft/recognizers-text-data-types-timex-expression": "1.1.4", - "botbuilder": "^4.23.1", - "botbuilder-ai": "^4.23.1", - "botbuilder-dialogs": "^4.23.1", - "botbuilder-testing": "^4.23.1", + "botbuilder": "4.1.6", + "botbuilder-ai": "4.1.6", + "botbuilder-dialogs": "4.1.6", + "botbuilder-testing": "4.1.6", "dotenv": "^8.2.0", "restify": "^11.1.0" }, diff --git a/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.ts b/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.ts index 85690fbade..bc24385700 100644 --- a/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.ts +++ b/generators/generator-botbuilder/generators/app/templates/core/package-with-tests.json.ts @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -38,22 +38,23 @@ }, "dependencies": { "@microsoft/recognizers-text-data-types-timex-expression": "1.1.4", - "botbuilder": "^4.23.1", - "botbuilder-ai": "^4.23.1", - "botbuilder-dialogs": "^4.23.1", - "botbuilder-testing": "^4.23.1", + "botbuilder": "4.1.6", + "botbuilder-ai": "4.1.6", + "botbuilder-dialogs": "4.1.6", + "botbuilder-testing": "4.1.6", "dotenv": "^8.2.0", "replace": "~1.2.0", "restify": "~11.1.0" }, "devDependencies": { "@types/mocha": "^7.0.2", + "@types/node": "^18.19.47", "@types/restify": "8.4.2", "mocha": "^7.1.2", "nodemon": "^2.0.4", "nyc": "^15.0.1", "ts-node": "^8.10.1", "tslint": "^6.1.2", - "typescript": "^4.0.7" + "typescript": "^5.6.3" } } diff --git a/generators/generator-botbuilder/generators/app/templates/core/package.json.js b/generators/generator-botbuilder/generators/app/templates/core/package.json.js index 6b03ed1f59..6b8ae1f9c1 100644 --- a/generators/generator-botbuilder/generators/app/templates/core/package.json.js +++ b/generators/generator-botbuilder/generators/app/templates/core/package.json.js @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -17,9 +17,9 @@ }, "dependencies": { "@microsoft/recognizers-text-data-types-timex-expression": "1.1.4", - "botbuilder": "^4.23.1, - "botbuilder-ai": "^4.23.1", - "botbuilder-dialogs": "^4.23.1", + "botbuilder": "4.1.6", + "botbuilder-ai": "4.1.6", + "botbuilder-dialogs": "4.1.6", "dotenv": "~8.2.0", "restify": "~11.1.0" }, diff --git a/generators/generator-botbuilder/generators/app/templates/core/package.json.ts b/generators/generator-botbuilder/generators/app/templates/core/package.json.ts index 1dfcdb7ecf..9514e6dc6f 100644 --- a/generators/generator-botbuilder/generators/app/templates/core/package.json.ts +++ b/generators/generator-botbuilder/generators/app/templates/core/package.json.ts @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -19,21 +19,22 @@ }, "dependencies": { "@microsoft/recognizers-text-data-types-timex-expression": "1.1.4", - "botbuilder": "^4.23.1", - "botbuilder-ai": "^4.23.1", - "botbuilder-dialogs": "^4.23.1", + "botbuilder": "4.1.6", + "botbuilder-ai": "4.1.6", + "botbuilder-dialogs": "4.1.6", "dotenv": "~8.2.0", "replace": "~1.2.0", "restify": "~11.1.0" }, "devDependencies": { "@types/mocha": "^7.0.2", + "@types/node": "^18.19.47", "@types/restify": "8.4.2", "mocha": "^7.1.2", "nodemon": "^2.0.4", "nyc": "^15.0.1", "ts-node": "^8.10.1", "tslint": "^6.1.2", - "typescript": "^4.0.7" + "typescript": "^5.6.3" } } diff --git a/generators/generator-botbuilder/generators/app/templates/core/tsconfig.json b/generators/generator-botbuilder/generators/app/templates/core/tsconfig.json index fa77e0ac62..7c70e81a34 100644 --- a/generators/generator-botbuilder/generators/app/templates/core/tsconfig.json +++ b/generators/generator-botbuilder/generators/app/templates/core/tsconfig.json @@ -3,13 +3,15 @@ "composite": true, "declaration": true, "target": "es2017", - "module": "commonjs", + "module": "NodeNext", + "moduleResolution": "NodeNext", "outDir": "./lib", "rootDir": "./src", "resolveJsonModule": true, "rootDirs": ["./src", "./resources"], "sourceMap": true, "incremental": true, - "tsBuildInfoFile": "./lib/.tsbuildinfo" + "tsBuildInfoFile": "./lib/.tsbuildinfo", + "esModuleInterop": true } } diff --git a/generators/generator-botbuilder/generators/app/templates/echo/package.json.js b/generators/generator-botbuilder/generators/app/templates/echo/package.json.js index 28b9cfd6b5..775968502c 100644 --- a/generators/generator-botbuilder/generators/app/templates/echo/package.json.js +++ b/generators/generator-botbuilder/generators/app/templates/echo/package.json.js @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -16,7 +16,7 @@ "url": "https://github.com" }, "dependencies": { - "botbuilder": "^4.23.1", + "botbuilder": "4.1.6", "dotenv": "~8.2.0", "restify": "~11.1.0" }, diff --git a/generators/generator-botbuilder/generators/app/templates/echo/package.json.ts b/generators/generator-botbuilder/generators/app/templates/echo/package.json.ts index 010bb3bb55..a585870422 100644 --- a/generators/generator-botbuilder/generators/app/templates/echo/package.json.ts +++ b/generators/generator-botbuilder/generators/app/templates/echo/package.json.ts @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -18,15 +18,16 @@ "url": "https://github.com" }, "dependencies": { - "botbuilder": "~4.23.1", + "botbuilder": "4.1.6", "dotenv": "~8.2.0", "replace": "~1.2.0", "restify": "~11.1.0" }, "devDependencies": { + "@types/node": "^18.19.47", "@types/restify": "8.4.2", "nodemon": "^2.0.4", "tslint": "^6.1.2", - "typescript": "^4.0.7" + "typescript": "^5.6.3" } } diff --git a/generators/generator-botbuilder/generators/app/templates/echo/tsconfig.json b/generators/generator-botbuilder/generators/app/templates/echo/tsconfig.json index c482a9fa3b..e8548514ec 100644 --- a/generators/generator-botbuilder/generators/app/templates/echo/tsconfig.json +++ b/generators/generator-botbuilder/generators/app/templates/echo/tsconfig.json @@ -2,11 +2,13 @@ "compilerOptions": { "declaration": true, "target": "es2017", - "module": "commonjs", + "moduleResolution": "NodeNext", + "module": "NodeNext", "outDir": "./lib", "rootDir": "./src", "sourceMap": true, "incremental": true, - "tsBuildInfoFile": "./lib/.tsbuildinfo" + "tsBuildInfoFile": "./lib/.tsbuildinfo", + "esModuleInterop": true } } diff --git a/generators/generator-botbuilder/generators/app/templates/empty/package.json.js b/generators/generator-botbuilder/generators/app/templates/empty/package.json.js index e639bc8d7c..1789e68fcd 100644 --- a/generators/generator-botbuilder/generators/app/templates/empty/package.json.js +++ b/generators/generator-botbuilder/generators/app/templates/empty/package.json.js @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -16,7 +16,7 @@ "url": "https://github.com" }, "dependencies": { - "botbuilder": "^4.23.1", + "botbuilder": "4.1.6", "restify": "~11.1.0" }, "devDependencies": { diff --git a/generators/generator-botbuilder/generators/app/templates/empty/package.json.ts b/generators/generator-botbuilder/generators/app/templates/empty/package.json.ts index 61ebfb57bb..37fd94e37c 100644 --- a/generators/generator-botbuilder/generators/app/templates/empty/package.json.ts +++ b/generators/generator-botbuilder/generators/app/templates/empty/package.json.ts @@ -1,6 +1,6 @@ { "name": "<%= botname %>", - "version": "1.0.0", + "version": "4.1.6", "description": "<%= botDescription %>", "author": "Generated using Microsoft Bot Builder Yeoman generator v<%= version %>", "license": "MIT", @@ -18,14 +18,15 @@ "url": "https://github.com" }, "dependencies": { - "botbuilder": "^4.23.1", + "botbuilder": "4.1.6", "replace": "~1.2.0", "restify": "~11.1.0" }, "devDependencies": { + "@types/node": "^18.19.47", "@types/restify": "8.4.2", "nodemon": "^2.0.4", "tslint": "^6.1.2", - "typescript": "^4.0.7" + "typescript": "^5.6.3" } } diff --git a/generators/generator-botbuilder/generators/app/templates/empty/tsconfig.json b/generators/generator-botbuilder/generators/app/templates/empty/tsconfig.json index c482a9fa3b..2948716aa0 100644 --- a/generators/generator-botbuilder/generators/app/templates/empty/tsconfig.json +++ b/generators/generator-botbuilder/generators/app/templates/empty/tsconfig.json @@ -2,11 +2,13 @@ "compilerOptions": { "declaration": true, "target": "es2017", - "module": "commonjs", + "module": "NodeNext", + "moduleResolution": "NodeNext", "outDir": "./lib", "rootDir": "./src", "sourceMap": true, "incremental": true, - "tsBuildInfoFile": "./lib/.tsbuildinfo" + "tsBuildInfoFile": "./lib/.tsbuildinfo", + "esModuleInterop": true } } diff --git a/generators/generator-botbuilder/package.json b/generators/generator-botbuilder/package.json index 43ca9fe063..2f98f73c56 100644 --- a/generators/generator-botbuilder/package.json +++ b/generators/generator-botbuilder/package.json @@ -1,6 +1,6 @@ { "name": "generator-botbuilder", - "version": "4.11.0", + "version": "4.1.6", "description": "A yeoman generator for creating bots built with Bot Framework v4", "homepage": "https://github.com/Microsoft/BotBuilder-JS/tree/main/generators/generator-botbuilder", "author": { diff --git a/libraries/botbuilder-ai/eslint.config.cjs b/libraries/botbuilder-ai/eslint.config.cjs deleted file mode 100644 index c56fd90ec6..0000000000 --- a/libraries/botbuilder-ai/eslint.config.cjs +++ /dev/null @@ -1,11 +0,0 @@ -const onlyWarn = require("eslint-plugin-only-warn"); -const sharedConfig = require("../../eslint.config.cjs") - -module.exports = [ - ...sharedConfig, - { - plugins: { - "only-warn": onlyWarn, - }, - } -] diff --git a/libraries/botbuilder-ai/package.json b/libraries/botbuilder-ai/package.json index 89baf54afc..01c382a39f 100644 --- a/libraries/botbuilder-ai/package.json +++ b/libraries/botbuilder-ai/package.json @@ -34,7 +34,6 @@ "botbuilder-dialogs-adaptive-runtime-core": "4.1.6", "botbuilder-dialogs-declarative": "4.1.6", "botframework-connector": "4.1.6", - "eslint-plugin-only-warn": "^1.1.0", "lodash": "^4.17.21", "node-fetch": "^2.7.0", "url-parse": "^1.5.10", @@ -51,7 +50,7 @@ "build:rollup": "yarn clean && yarn build && api-extractor run --verbose --local", "clean": "rimraf _ts3.4 lib tsconfig.tsbuildinfo", "depcheck": "depcheck --config ../../.depcheckrc", - "lint": "eslint .", + "lint": "eslint . --config ../../eslint.config.cjs", "postbuild": "downlevel-dts lib _ts3.4/lib --checksum", "test": "npm-run-all build test:mocha", "test:mocha": "nyc mocha tests", diff --git a/libraries/botbuilder-ai/src/custom.window.ts b/libraries/botbuilder-ai/src/custom.window.ts index 4e48cd248d..de0985b441 100644 --- a/libraries/botbuilder-ai/src/custom.window.ts +++ b/libraries/botbuilder-ai/src/custom.window.ts @@ -7,7 +7,7 @@ */ declare global { - interface Window {} // eslint-disable-line @typescript-eslint/no-empty-interface + interface Window {} // eslint-disable-line @typescript-eslint/no-empty-object-type } export type window = Window; diff --git a/libraries/botbuilder-ai/src/customQuestionAnswering.ts b/libraries/botbuilder-ai/src/customQuestionAnswering.ts index b1a8023139..53a1b08af0 100644 --- a/libraries/botbuilder-ai/src/customQuestionAnswering.ts +++ b/libraries/botbuilder-ai/src/customQuestionAnswering.ts @@ -43,7 +43,7 @@ export interface QnAMakerClient { turnContext: TurnContext, options?: QnAMakerOptions, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise; /** @@ -59,7 +59,7 @@ export interface QnAMakerClient { turnContext: TurnContext, options?: QnAMakerOptions, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise; /** @@ -111,7 +111,7 @@ export interface QnAMakerTelemetryClient { context: TurnContext, options?: QnAMakerOptions, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise; } @@ -142,7 +142,7 @@ export class CustomQuestionAnswering implements QnAMakerClient, QnAMakerTelemetr private readonly endpoint: QnAMakerEndpoint, options: QnAMakerOptions = {}, telemetryClient?: BotTelemetryClient, - logPersonalInformation?: boolean + logPersonalInformation?: boolean, ) { if (!endpoint) { throw new TypeError('QnAMaker requires valid QnAMakerEndpoint.'); @@ -215,7 +215,7 @@ export class CustomQuestionAnswering implements QnAMakerClient, QnAMakerTelemetr context: TurnContext, options?: QnAMakerOptions, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { if (!context) { throw new TypeError('QnAMaker.getAnswers() requires a TurnContext.'); @@ -243,7 +243,7 @@ export class CustomQuestionAnswering implements QnAMakerClient, QnAMakerTelemetr context: TurnContext, options: QnAMakerOptions, telemetryProperties: { [key: string]: string }, - telemetryMetrics: { [key: string]: number } + telemetryMetrics: { [key: string]: number }, ): Promise { if (!context) { throw new TypeError('CustomQuestionAnswering.getAnswersRaw() requires a TurnContext.'); @@ -266,7 +266,7 @@ export class CustomQuestionAnswering implements QnAMakerClient, QnAMakerTelemetr context: TurnContext, options: QnAMakerOptions, telemetryProperties: { [key: string]: string }, - telemetryMetrics: { [key: string]: number } + telemetryMetrics: { [key: string]: number }, ): Promise { const question: string = this.getTrimmedMessageText(context); const userId = context?.activity?.from?.id; @@ -327,13 +327,13 @@ export class CustomQuestionAnswering implements QnAMakerClient, QnAMakerTelemetr qnaResults: QnAMakerResult[], turnContext: TurnContext, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { const [properties, metrics] = await this.fillQnAEvent( qnaResults, turnContext, telemetryProperties, - telemetryMetrics + telemetryMetrics, ); this.telemetryClient.trackEvent({ @@ -357,7 +357,7 @@ export class CustomQuestionAnswering implements QnAMakerClient, QnAMakerTelemetr qnaResults: QnAMakerResult[], turnContext: TurnContext, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise<[Record, Record]> { const properties: Record = { [QnATelemetryConstants.knowledgeBaseIdProperty]: this.endpoint.knowledgeBaseId, diff --git a/libraries/botbuilder-ai/src/globals.ts b/libraries/botbuilder-ai/src/globals.ts index 28009caf19..c82e62318c 100644 --- a/libraries/botbuilder-ai/src/globals.ts +++ b/libraries/botbuilder-ai/src/globals.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/explicit-function-return-type */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /** * @module botbuilder */ @@ -8,7 +6,7 @@ * Licensed under the MIT License. */ -// eslint-disable-next-line @typescript-eslint/no-var-requires +// eslint-disable-next-line @typescript-eslint/no-require-imports const window = require('./custom.window'); /** @@ -18,7 +16,7 @@ const window = require('./custom.window'); */ export function getFetch() { if (global) { - return (global.fetch = require('node-fetch')); + return (global.fetch = require('node-fetch')); // eslint-disable-line @typescript-eslint/no-require-imports } return window?.fetch; diff --git a/libraries/botbuilder-ai/src/instanceData.ts b/libraries/botbuilder-ai/src/instanceData.ts index e39f53987a..68b9d765fa 100644 --- a/libraries/botbuilder-ai/src/instanceData.ts +++ b/libraries/botbuilder-ai/src/instanceData.ts @@ -33,5 +33,5 @@ export interface InstanceData { /** * Any extra properties. */ - [propName: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any + [propName: string]: any; } diff --git a/libraries/botbuilder-ai/src/intentData.ts b/libraries/botbuilder-ai/src/intentData.ts index ce285188c1..48a4b615ee 100644 --- a/libraries/botbuilder-ai/src/intentData.ts +++ b/libraries/botbuilder-ai/src/intentData.ts @@ -18,5 +18,5 @@ export interface IntentData { /** * Any extra properties. */ - [propName: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any + [propName: string]: any; } diff --git a/libraries/botbuilder-ai/src/luisAdaptivePredictionOptions.ts b/libraries/botbuilder-ai/src/luisAdaptivePredictionOptions.ts index 3fefd876aa..4ca608b352 100644 --- a/libraries/botbuilder-ai/src/luisAdaptivePredictionOptions.ts +++ b/libraries/botbuilder-ai/src/luisAdaptivePredictionOptions.ts @@ -63,7 +63,8 @@ export interface LuisAdaptivePredictionOptionsConfiguration { * Converts optional parameters for a LUIS prediction request. */ export class LuisAdaptivePredictionOptionsConverter - implements Converter { + implements Converter +{ /** * Converts the provided options configuration into an object of [LuisAdaptivePredictionOptions](xref:botbuilder-ai.LuisAdaptivePredictionOptions) type. * diff --git a/libraries/botbuilder-ai/src/luisAdaptiveRecognizer.ts b/libraries/botbuilder-ai/src/luisAdaptiveRecognizer.ts index 2350150f8b..08c7a200c1 100644 --- a/libraries/botbuilder-ai/src/luisAdaptiveRecognizer.ts +++ b/libraries/botbuilder-ai/src/luisAdaptiveRecognizer.ts @@ -102,7 +102,7 @@ export class LuisAdaptiveRecognizer extends Recognizer implements LuisAdaptiveRe * The flag to indicate in personal information should be logged in telemetry. */ logPersonalInformation: BoolExpression = new BoolExpression( - '=settings.runtimeSettings.telemetry.logPersonalInformation' + '=settings.runtimeSettings.telemetry.logPersonalInformation', ); /** @@ -140,7 +140,7 @@ export class LuisAdaptiveRecognizer extends Recognizer implements LuisAdaptiveRe dialogContext: DialogContext, activity: Activity, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise { // Validate passed in activity matches turn activity const context = dialogContext.context; @@ -167,7 +167,7 @@ export class LuisAdaptiveRecognizer extends Recognizer implements LuisAdaptiveRe dialogContext, 'LuisResult', this.fillRecognizerResultTelemetryProperties(result, telemetryProperties, dialogContext), - telemetryMetrics + telemetryMetrics, ); return result; @@ -231,7 +231,7 @@ export class LuisAdaptiveRecognizer extends Recognizer implements LuisAdaptiveRe protected fillRecognizerResultTelemetryProperties( recognizerResult: RecognizerResult, telemetryProperties: { [key: string]: string }, - dialogContext: DialogContext + dialogContext: DialogContext, ): { [key: string]: string } { const logPersonalInfo = this.logPersonalInformation.tryGetValue(dialogContext.state); const applicationId = this.applicationId.tryGetValue(dialogContext.state); diff --git a/libraries/botbuilder-ai/src/luisBotComponent.ts b/libraries/botbuilder-ai/src/luisBotComponent.ts index f0a4ec698d..4fe60d490c 100644 --- a/libraries/botbuilder-ai/src/luisBotComponent.ts +++ b/libraries/botbuilder-ai/src/luisBotComponent.ts @@ -25,7 +25,7 @@ export class LuisBotComponent extends BotComponent { }, ]; }, - }) + }), ); } } diff --git a/libraries/botbuilder-ai/src/luisRecognizer.ts b/libraries/botbuilder-ai/src/luisRecognizer.ts index 7f8b7458a7..a40b8afb6e 100644 --- a/libraries/botbuilder-ai/src/luisRecognizer.ts +++ b/libraries/botbuilder-ai/src/luisRecognizer.ts @@ -117,7 +117,7 @@ export interface LuisRecognizerTelemetryClient { recognize( context: TurnContext, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise; } @@ -246,7 +246,7 @@ const UnsafeLuisRecognizerUnion = z.custom, telemetryMetrics?: Record, - options?: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions + options?: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions, ): Promise; /** @@ -451,7 +451,7 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { */ async recognize( utterance: string, - options?: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions + options?: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions, ): Promise; /** @@ -465,7 +465,7 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { | LuisRecognizerOptionsV3 | LuisPredictionOptions, maybeTelemetryMetrics?: Record, - maybeOptions?: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions + maybeOptions?: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions, ): Promise { // This type check, when true, logically implies that the function is being invoked as the two-argument string + optional options overload variant. if (typeof contextOrUtterance === 'string') { @@ -544,7 +544,7 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { recognizerResult: RecognizerResult, turnContext: TurnContext, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { await this.fillTelemetryProperties(recognizerResult, turnContext, telemetryProperties).then((props) => { this.telemetryClient.trackEvent({ @@ -566,7 +566,7 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { protected async fillTelemetryProperties( recognizerResult: RecognizerResult, turnContext: TurnContext, - telemetryProperties?: { [key: string]: string } + telemetryProperties?: { [key: string]: string }, ): Promise<{ [key: string]: string }> { const [firstIntent, secondIntent] = LuisRecognizer.sortedIntents(recognizerResult); @@ -617,7 +617,6 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { // If the `error` received is a azure-cognitiveservices-luis-runtime error, // it may have a `response` property and `response.statusCode`. // If these properties exist, we should populate the error with a correct and informative error message. - // eslint-disable-next-line @typescript-eslint/no-explicit-any const response: Record<'status', number> = (error as any).response; if (response?.status) { @@ -660,7 +659,7 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { // Merges the default options set by the Recognizer contructor with the 'user' options passed into the 'recognize' method private setLuisPredictionOptions( defaultOptions: LuisPredictionOptions, - userOptions: LuisPredictionOptions + userOptions: LuisPredictionOptions, ): LuisPredictionOptions { return Object.assign(defaultOptions, userOptions); } @@ -669,19 +668,19 @@ export class LuisRecognizer implements LuisRecognizerTelemetryClient { private validateLuisApplication(): void { if (!this.application.applicationId) { throw new Error( - `Invalid \`applicationId\` value detected: ${this.application.applicationId}\nPlease make sure your applicationId is a valid LUIS Application Id, e.g. "b31aeaf3-3511-495b-a07f-571fc873214b".` + `Invalid \`applicationId\` value detected: ${this.application.applicationId}\nPlease make sure your applicationId is a valid LUIS Application Id, e.g. "b31aeaf3-3511-495b-a07f-571fc873214b".`, ); } if (!this.application.endpointKey) { throw new Error( - `Invalid \`endpointKey\` value detected: ${this.application.endpointKey}\nPlease make sure your endpointKey is a valid LUIS Endpoint Key, e.g. "048ec46dc58e495482b0c447cfdbd291".` + `Invalid \`endpointKey\` value detected: ${this.application.endpointKey}\nPlease make sure your endpointKey is a valid LUIS Endpoint Key, e.g. "048ec46dc58e495482b0c447cfdbd291".`, ); } } // Builds a LuisRecognizer Strategy depending on the options passed private buildRecognizer( - userOptions: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions + userOptions: LuisRecognizerOptionsV2 | LuisRecognizerOptionsV3 | LuisPredictionOptions, ): LuisRecognizerV3 | LuisRecognizerV2 { if (isLuisRecognizerOptionsV3(userOptions)) { return new LuisRecognizerV3(this.application, userOptions); diff --git a/libraries/botbuilder-ai/src/luisRecognizerOptions.ts b/libraries/botbuilder-ai/src/luisRecognizerOptions.ts index c402b65396..afc7575d27 100644 --- a/libraries/botbuilder-ai/src/luisRecognizerOptions.ts +++ b/libraries/botbuilder-ai/src/luisRecognizerOptions.ts @@ -20,7 +20,10 @@ export abstract class LuisRecognizerInternal { * @param {LuisApplication} application An object conforming to the [LuisApplication](xref:botbuilder-ai.LuisApplication) definition. * @param {LuisRecognizerOptions} _options Optional. Options object used to control predictions. Should conform to the [LuisRecognizerOptions](xref:botbuilder-ai.LuisRecognizerOptions) definition. */ - constructor(public application: LuisApplication, _options?: LuisRecognizerOptions) { + constructor( + public application: LuisApplication, + _options?: LuisRecognizerOptions, + ) { if (!application) { throw new Error('Null Application\n'); } diff --git a/libraries/botbuilder-ai/src/luisRecognizerOptionsV2.ts b/libraries/botbuilder-ai/src/luisRecognizerOptionsV2.ts index 68ce30cb7b..b7b413aba3 100644 --- a/libraries/botbuilder-ai/src/luisRecognizerOptionsV2.ts +++ b/libraries/botbuilder-ai/src/luisRecognizerOptionsV2.ts @@ -15,7 +15,7 @@ import { LuisRecognizerInternal } from './luisRecognizerOptions'; import { NullTelemetryClient, TurnContext, RecognizerResult } from 'botbuilder-core'; import { DialogContext } from 'botbuilder-dialogs'; -// eslint-disable-next-line @typescript-eslint/no-var-requires +// eslint-disable-next-line @typescript-eslint/no-require-imports const pjson: Record<'name' | 'version', string> = require('../package.json'); const LUIS_TRACE_TYPE = 'https://www.luis.ai/schemas/trace'; @@ -29,7 +29,6 @@ const LUIS_TRACE_LABEL = 'Luis Trace'; * @returns {boolean} A boolean value that indicates param options is a [LuisRecognizerOptionsV2](xref:botbuilder-ai.LuisRecognizerOptionsV2). */ export function isLuisRecognizerOptionsV2(options: unknown): options is LuisRecognizerOptionsV2 { - // eslint-disable-next-line @typescript-eslint/no-explicit-any return (options as any).apiVersion && (options as any).apiVersion === 'v2'; } @@ -52,7 +51,7 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { // shouldn't effect production bots. const creds = new TokenCredentials(application.endpointKey); const baseUri = application.endpoint || 'https://westus.api.cognitive.microsoft.com'; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + this.luisClient = new LuisClient(creds as any, baseUri); this.options = { @@ -123,7 +122,7 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { 'User-Agent': this.getUserAgent(), }, ...luisPredictionOptions, - } + }, ); // Map results const result = { @@ -133,7 +132,7 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { entities: this.getEntitiesAndMetadata( luisResult.entities, luisResult.compositeEntities, - luisPredictionOptions.includeInstanceData === undefined || luisPredictionOptions.includeInstanceData + luisPredictionOptions.includeInstanceData === undefined || luisPredictionOptions.includeInstanceData, ), sentiment: this.getSentiment(luisResult), luisResult: luisPredictionOptions.includeAPIResults ? luisResult : null, @@ -170,17 +169,15 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { private getEntitiesAndMetadata( entities: EntityModel[], compositeEntities: CompositeEntityModel[] | undefined, - verbose: boolean - // eslint-disable-next-line @typescript-eslint/no-explicit-any + verbose: boolean, ): any { - // eslint-disable-next-line @typescript-eslint/no-explicit-any const entitiesAndMetadata: any = verbose ? { $instance: {} } : {}; let compositeEntityTypes: string[] = []; // We start by populating composite entities so that entities covered by them are removed from the entities list if (compositeEntities) { compositeEntityTypes = compositeEntities.map( - (compositeEntity: CompositeEntityModel) => compositeEntity.parentType + (compositeEntity: CompositeEntityModel) => compositeEntity.parentType, ); compositeEntities.forEach((compositeEntity: CompositeEntityModel) => { entities = this.populateCompositeEntity(compositeEntity, entities, entitiesAndMetadata, verbose); @@ -200,7 +197,7 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { this.addProperty( entitiesAndMetadata.$instance, this.getNormalizedEntityName(entity), - this.getEntityMetadata(entity) + this.getEntityMetadata(entity), ); } } @@ -212,12 +209,10 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { private populateCompositeEntity( compositeEntity: CompositeEntityModel, entities: EntityModel[], - entitiesAndMetadata: any, // eslint-disable-line @typescript-eslint/no-explicit-any - verbose: boolean + entitiesAndMetadata: any, + verbose: boolean, ): EntityModel[] { - // eslint-disable-next-line @typescript-eslint/no-explicit-any const childrenEntities: any = verbose ? { $instance: {} } : {}; - // eslint-disable-next-line @typescript-eslint/no-explicit-any let childrenEntitiesMetadata: any = {}; // This is now implemented as O(n^2) search and can be reduced to O(2n) using a map as an optimization if n grows @@ -258,7 +253,7 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { this.addProperty( childrenEntities.$instance, this.getNormalizedEntityName(entity), - this.getEntityMetadata(entity) + this.getEntityMetadata(entity), ); } } @@ -278,14 +273,13 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { this.addProperty( entitiesAndMetadata.$instance, this.getNormalizedEntityName(compositeEntityMetadata), - childrenEntitiesMetadata + childrenEntitiesMetadata, ); } return filteredEntities; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private getEntityValue(entity: EntityModel): any { if (entity.type.startsWith('builtin.geographyV2.')) { return { @@ -310,13 +304,9 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { return entity.resolution; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any const vals: any = entity.resolution.values; - // eslint-disable-next-line @typescript-eslint/no-explicit-any const type = vals[0].type; - // eslint-disable-next-line @typescript-eslint/no-explicit-any const timexes = vals.map((t: any) => t.timex); - // eslint-disable-next-line @typescript-eslint/no-explicit-any const distinct = timexes.filter((v, i, a) => a.indexOf(v) === i); return { type: type, timex: distinct }; @@ -391,7 +381,6 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { } // If a property doesn't exist add it to a new array, otherwise append it to the existing array - // eslint-disable-next-line @typescript-eslint/ban-types private addProperty(obj: object, key: string, value: unknown): void { if (key in obj) { obj[key] = obj[key].concat(value); @@ -423,7 +412,7 @@ export class LuisRecognizerV2 extends LuisRecognizerInternal { private emitTraceInfo( context: TurnContext, luisResult: LuisResult, - recognizerResult: RecognizerResult + recognizerResult: RecognizerResult, ): Promise { const traceInfo = { recognizerResult: recognizerResult, diff --git a/libraries/botbuilder-ai/src/luisRecognizerOptionsV3.ts b/libraries/botbuilder-ai/src/luisRecognizerOptionsV3.ts index bfaff2c5b6..99cd407695 100644 --- a/libraries/botbuilder-ai/src/luisRecognizerOptionsV3.ts +++ b/libraries/botbuilder-ai/src/luisRecognizerOptionsV3.ts @@ -6,8 +6,7 @@ * Licensed under the MIT License. */ -import fetch from 'node-fetch'; -import { RequestInfo, RequestInit } from 'node-fetch'; +import fetch, { RequestInfo, RequestInit } from 'node-fetch'; import { LuisApplication, LuisRecognizerOptionsV3 } from './luisRecognizer'; import { LuisResult } from './luisV2-models/luisResult'; import { LuisRecognizerInternal } from './luisRecognizerOptions'; @@ -31,7 +30,6 @@ const MetadataKey = '$instance'; * @returns {boolean} A boolean value that indicates param options is a [LuisRecognizerOptionsV3](xref:botbuilder-ai.LuisRecognizerOptionsV3). */ export function isLuisRecognizerOptionsV3(options: unknown): options is LuisRecognizerOptionsV3 { - // eslint-disable-next-line @typescript-eslint/no-explicit-any return (options as any).apiVersion && (options as any).apiVersion === 'v3'; } @@ -143,7 +141,7 @@ export class LuisRecognizerV3 extends LuisRecognizerInternal { private async recognize( context: TurnContext, utterance: string, - options: LuisRecognizerOptionsV3 + options: LuisRecognizerOptionsV3, ): Promise { if (!utterance.trim()) { // Bypass LUIS if the activity's text is null or whitespace @@ -240,7 +238,7 @@ export class LuisRecognizerV3 extends LuisRecognizerInternal { context: TurnContext, luisResult: LuisResult, recognizerResult: RecognizerResult, - options: LuisRecognizerOptionsV3 + options: LuisRecognizerOptionsV3, ): Promise { const traceInfo = { recognizerResult: recognizerResult, diff --git a/libraries/botbuilder-ai/src/luisSchema.d.ts b/libraries/botbuilder-ai/src/luisSchema.d.ts index 2914c7df8f..0f73aebb49 100644 --- a/libraries/botbuilder-ai/src/luisSchema.d.ts +++ b/libraries/botbuilder-ai/src/luisSchema.d.ts @@ -30,7 +30,7 @@ export interface Entity { startIndex?: number; endIndex?: number; score?: number; - resolution?: { [propertyName: string]: any }; // eslint-disable-line @typescript-eslint/no-explicit-any + resolution?: { [propertyName: string]: any }; } /** diff --git a/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts b/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts index 5ed5aa9648..54c1e950d8 100644 --- a/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts +++ b/libraries/botbuilder-ai/src/luisV2-models/luisPrediction.ts @@ -37,7 +37,7 @@ export class LuisPrediction { resolve( appId: string, query: string, - options?: PredictionResolveOptionalParams + options?: PredictionResolveOptionalParams, ): Promise; /** * @param appId The LUIS application ID (Guid). @@ -55,7 +55,7 @@ export class LuisPrediction { appId: string, query: string, options: PredictionResolveOptionalParams, - callback: ServiceCallback + callback: ServiceCallback, ): void; /** * @param appId The LUIS application ID (Guid). @@ -68,7 +68,7 @@ export class LuisPrediction { appId: string, query: string, options?: PredictionResolveOptionalParams | ServiceCallback, - callback?: ServiceCallback + callback?: ServiceCallback, ): Promise { return this.client.sendOperationRequest( { @@ -77,7 +77,7 @@ export class LuisPrediction { options, }, resolveOperationSpec, - callback + callback, ) as Promise; } } diff --git a/libraries/botbuilder-ai/src/qnaCardBuilder.ts b/libraries/botbuilder-ai/src/qnaCardBuilder.ts index 3a9d6a1e5a..bb1bdff412 100644 --- a/libraries/botbuilder-ai/src/qnaCardBuilder.ts +++ b/libraries/botbuilder-ai/src/qnaCardBuilder.ts @@ -26,7 +26,7 @@ export class QnACardBuilder { suggestionsList: string[], cardTitle: string, cardNoMatchText: string, - useTeamsAdaptiveCard = false + useTeamsAdaptiveCard = false, ): Partial { if (!Array.isArray(suggestionsList)) { throw new Error('Missing suggestionsList'); @@ -76,7 +76,7 @@ export class QnACardBuilder { static getQnAAnswerCard( result: QnAMakerResult, displayPreciseAnswerOnly: boolean, - useTeamsAdaptiveCard = false + useTeamsAdaptiveCard = false, ): Partial { if (!result) { throw new Error('Missing QnAMaker result'); diff --git a/libraries/botbuilder-ai/src/qnaMaker.ts b/libraries/botbuilder-ai/src/qnaMaker.ts index 5d8b266184..b9ecdbc6b9 100644 --- a/libraries/botbuilder-ai/src/qnaMaker.ts +++ b/libraries/botbuilder-ai/src/qnaMaker.ts @@ -46,7 +46,7 @@ export interface QnAMakerClient { turnContext: TurnContext, options?: QnAMakerOptions, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise; /** @@ -62,7 +62,7 @@ export interface QnAMakerClient { turnContext: TurnContext, options?: QnAMakerOptions, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise; /** @@ -114,7 +114,7 @@ export interface QnAMakerTelemetryClient { context: TurnContext, options?: QnAMakerOptions, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise; } @@ -146,7 +146,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { private readonly endpoint: QnAMakerEndpoint, options: QnAMakerOptions = {}, telemetryClient?: BotTelemetryClient, - logPersonalInformation?: boolean + logPersonalInformation?: boolean, ) { if (!endpoint) { throw new TypeError('QnAMaker requires valid QnAMakerEndpoint.'); @@ -216,7 +216,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { context: TurnContext, options?: QnAMakerOptions, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { if (!context) { throw new TypeError('QnAMaker.getAnswers() requires a TurnContext.'); @@ -244,7 +244,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { context: TurnContext, options: QnAMakerOptions, telemetryProperties: { [key: string]: string }, - telemetryMetrics: { [key: string]: number } + telemetryMetrics: { [key: string]: number }, ): Promise { if (!context) { throw new TypeError('QnAMaker.getAnswersRaw() requires a TurnContext.'); @@ -266,7 +266,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { context: TurnContext, options?: QnAMakerOptions, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { const question: string = this.getTrimmedMessageText(context); const queryOptions: QnAMakerOptions = { ...this._options, ...options } as QnAMakerOptions; @@ -282,7 +282,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { const sortedQnaAnswers: QnAMakerResult[] = GenerateAnswerUtils.sortAnswersWithinThreshold( result?.answers, - queryOptions + queryOptions, ); queryResult.push(...sortedQnaAnswers); @@ -351,7 +351,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { async generateAnswer( question: string | undefined, top?: number, - _scoreThreshold?: number + _scoreThreshold?: number, ): Promise { const trimmedAnswer: string = question ? question.trim() : ''; @@ -359,7 +359,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { const result: QnAMakerResults = await this.callService( this.endpoint, question, - typeof top === 'number' ? top : 1 + typeof top === 'number' ? top : 1, ); return result.answers.sort((a: QnAMakerResult, b: QnAMakerResult) => b.score - a.score); @@ -417,13 +417,13 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { qnaResults: QnAMakerResult[], turnContext: TurnContext, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { const [properties, metrics] = await this.fillQnAEvent( qnaResults, turnContext, telemetryProperties, - telemetryMetrics + telemetryMetrics, ); this.telemetryClient.trackEvent({ @@ -447,7 +447,7 @@ export class QnAMaker implements QnAMakerClient, QnAMakerTelemetryClient { qnaResults: QnAMakerResult[], turnContext: TurnContext, telemetryProperties?: Record, - telemetryMetrics?: Record + telemetryMetrics?: Record, ): Promise<[Record, Record]> { const properties: Record = { [QnATelemetryConstants.knowledgeBaseIdProperty]: this.endpoint.knowledgeBaseId, diff --git a/libraries/botbuilder-ai/src/qnaMakerBotComponent.ts b/libraries/botbuilder-ai/src/qnaMakerBotComponent.ts index d0ae9099f2..ff17fc4309 100644 --- a/libraries/botbuilder-ai/src/qnaMakerBotComponent.ts +++ b/libraries/botbuilder-ai/src/qnaMakerBotComponent.ts @@ -30,7 +30,7 @@ export class QnAMakerBotComponent extends BotComponent { }, ]; }, - }) + }), ); } } diff --git a/libraries/botbuilder-ai/src/qnaMakerDialog.ts b/libraries/botbuilder-ai/src/qnaMakerDialog.ts index bb55911565..df5e4f19e7 100644 --- a/libraries/botbuilder-ai/src/qnaMakerDialog.ts +++ b/libraries/botbuilder-ai/src/qnaMakerDialog.ts @@ -59,9 +59,10 @@ import { CustomQuestionAnswering } from './customQuestionAnswering'; import { ServiceType } from './qnamaker-interfaces/serviceType'; class QnAMakerDialogActivityConverter - implements Converter, DialogStateManager>> { + implements Converter, DialogStateManager>> +{ convert( - value: string | TemplateInterface, DialogStateManager> + value: string | TemplateInterface, DialogStateManager>, ): TemplateInterface, DialogStateManager> { if (typeof value === 'string') { return new BindToActivity(MessageFactory.text(value) as Activity); @@ -239,7 +240,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon * Gets or sets the template to send to the user when QnA Maker does not find an answer. */ noAnswer: TemplateInterface, DialogStateManager> = new BindToActivity( - MessageFactory.text(this.defaultNoAnswer) + MessageFactory.text(this.defaultNoAnswer), ); /** @@ -262,7 +263,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon * active learning card. */ cardNoMatchResponse: TemplateInterface, DialogStateManager> = new BindToActivity( - MessageFactory.text(this.defaultCardNoMatchResponse) + MessageFactory.text(this.defaultCardNoMatchResponse), ); /** @@ -364,7 +365,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon enablePreciseAnswer?: boolean, displayPreciseAnswerOnly?: boolean, qnaServiceType?: ServiceType, - useTeamsAdaptiveCard?: boolean + useTeamsAdaptiveCard?: boolean, ); /** @@ -401,7 +402,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon enablePreciseAnswer?: boolean, displayPreciseAnswerOnly?: boolean, qnaServiceType?: ServiceType, - useTeamsAdaptiveCard?: boolean + useTeamsAdaptiveCard?: boolean, ); /** @@ -426,7 +427,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon enablePreciseAnswer?: boolean, displayPreciseAnswerOnly?: boolean, qnaServiceType?: ServiceType, - useTeamsAdaptiveCard?: boolean + useTeamsAdaptiveCard?: boolean, ) { super(dialogId); if (knowledgeBaseId) { @@ -448,9 +449,8 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon if (top) { this.top = new IntExpression(top); } - const qnaSuggestionsActivityFactoryParsed = qnaSuggestionsActivityFactory.safeParse( - activeLearningTitleOrFactory - ); + const qnaSuggestionsActivityFactoryParsed = + qnaSuggestionsActivityFactory.safeParse(activeLearningTitleOrFactory); if (qnaSuggestionsActivityFactoryParsed.success) { if (!cardNoMatchText) { // Without a developer-provided cardNoMatchText, the end user will not be able to tell the convey to the bot and QnA Maker that the suggested alternative questions were not correct. @@ -461,7 +461,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon this.suggestionsActivityFactory = qnaSuggestionsActivityFactoryParsed.data; } else { this.activeLearningCardTitle = new StringExpression( - activeLearningTitleOrFactory?.toString() ?? this.defaultCardTitle + activeLearningTitleOrFactory?.toString() ?? this.defaultCardTitle, ); } @@ -482,7 +482,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon } this.cardNoMatchResponse = new BindToActivity( - cardNoMatchResponse ?? MessageFactory.text(this.defaultCardNoMatchResponse) + cardNoMatchResponse ?? MessageFactory.text(this.defaultCardNoMatchResponse), ); if (enablePreciseAnswer != undefined) { @@ -559,7 +559,6 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon * @param {object} options (Optional) Initial information to pass to the dialog. * @returns {Promise} A promise resolving to the turn result */ - // eslint-disable-next-line @typescript-eslint/ban-types async beginDialog(dc: DialogContext, options?: object): Promise { if (!dc) { throw new Error('Missing DialogContext'); @@ -636,7 +635,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon this.resetOptions(dc, dialogOptions); const response = await qnaClient.getAnswersRaw(dc.context, dialogOptions.qnaMakerOptions); // disable interruption if we have answers. - return response.answers?.length > 0 ?? false; + return response.answers?.length > 0; } } @@ -672,14 +671,14 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon endpoint, await this.getQnAMakerOptions(dc), this.telemetryClient, - logPersonalInformation + logPersonalInformation, ); } else { return new QnAMaker( endpoint, await this.getQnAMakerOptions(dc), this.telemetryClient, - logPersonalInformation + logPersonalInformation, ); } } @@ -728,7 +727,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon * * @param {WaterfallStepContext} step the waterfall step context * @returns {Promise} a promise resolving to the dialog turn result - **/ + */ protected async displayQnAResult(step: WaterfallStepContext): Promise { const dialogOptions: QnAMakerDialogOptions = step.activeDialog.state[this.options]; const reply = step.context.activity.text; @@ -757,7 +756,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon const message = QnACardBuilder.getQnAAnswerCard( response[0], this.displayPreciseAnswerOnly, - this.useTeamsAdaptiveCard + this.useTeamsAdaptiveCard, ); await step.context.sendActivity(message); } else { @@ -767,7 +766,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon const message = QnACardBuilder.getQnAAnswerCard( response[0], this.displayPreciseAnswerOnly, - this.useTeamsAdaptiveCard + this.useTeamsAdaptiveCard, ); await step.context.sendActivity(message); } @@ -861,13 +860,13 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon const message = this.suggestionsActivityFactory?.( suggestedQuestions, - dialogOptions.qnaDialogResponseOptions.cardNoMatchText + dialogOptions.qnaDialogResponseOptions.cardNoMatchText, ) ?? QnACardBuilder.getSuggestionsCard( suggestedQuestions, dialogOptions.qnaDialogResponseOptions.activeLearningCardTitle, dialogOptions.qnaDialogResponseOptions.cardNoMatchText, - this.useTeamsAdaptiveCard + this.useTeamsAdaptiveCard, ); z.record(z.unknown()).parse(message, { path: ['message'] }); @@ -961,7 +960,7 @@ export class QnAMakerDialog extends WaterfallDialog implements QnAMakerDialogCon const message = QnACardBuilder.getQnAAnswerCard( answer, this.displayPreciseAnswerOnly, - this.useTeamsAdaptiveCard + this.useTeamsAdaptiveCard, ); await step.context.sendActivity(message); return Dialog.EndOfTurn; diff --git a/libraries/botbuilder-ai/src/qnaMakerRecognizer.ts b/libraries/botbuilder-ai/src/qnaMakerRecognizer.ts index 335ac94547..f5afb504b4 100644 --- a/libraries/botbuilder-ai/src/qnaMakerRecognizer.ts +++ b/libraries/botbuilder-ai/src/qnaMakerRecognizer.ts @@ -124,7 +124,7 @@ export class QnAMakerRecognizer extends Recognizer implements QnAMakerRecognizer * The flag to indicate if personal information should be logged in telemetry. */ logPersonalInformation: BoolExpression = new BoolExpression( - '=settings.runtimeSettings.telemetry.logPersonalInformation' + '=settings.runtimeSettings.telemetry.logPersonalInformation', ); /** @@ -193,7 +193,7 @@ export class QnAMakerRecognizer extends Recognizer implements QnAMakerRecognizer dc: DialogContext, activity: Activity, telemetryProperties?: { [key: string]: string }, - telemetryMetrics?: { [key: string]: number } + telemetryMetrics?: { [key: string]: number }, ): Promise { // identify matched intents const recognizerResult: RecognizerResult = { @@ -270,7 +270,7 @@ export class QnAMakerRecognizer extends Recognizer implements QnAMakerRecognizer dc, 'QnAMakerRecognizerResult', this.fillRecognizerResultTelemetryProperties(recognizerResult, telemetryProperties, dc), - telemetryMetrics + telemetryMetrics, ); return recognizerResult; } @@ -344,11 +344,11 @@ export class QnAMakerRecognizer extends Recognizer implements QnAMakerRecognizer protected fillRecognizerResultTelemetryProperties( recognizerResult: RecognizerResult, telemetryProperties: Record, - dc: DialogContext + dc: DialogContext, ): Record { if (!dc) { throw new Error( - 'DialogContext needed for state in AdaptiveRecognizer.fillRecognizerResultTelemetryProperties method.' + 'DialogContext needed for state in AdaptiveRecognizer.fillRecognizerResultTelemetryProperties method.', ); } const { intent, score } = getTopScoringIntent(recognizerResult); @@ -359,7 +359,7 @@ export class QnAMakerRecognizer extends Recognizer implements QnAMakerRecognizer Intents: intentsCount > 0 ? JSON.stringify(recognizerResult.intents) : undefined, Entities: recognizerResult.entities ? JSON.stringify(recognizerResult.entities) : undefined, AdditionalProperties: JSON.stringify( - omit(recognizerResult, ['text', 'alteredText', 'intents', 'entities']) + omit(recognizerResult, ['text', 'alteredText', 'intents', 'entities']), ), }; diff --git a/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerPrompt.ts b/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerPrompt.ts index 79f9a73b88..25777f0f9a 100644 --- a/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerPrompt.ts +++ b/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerPrompt.ts @@ -22,7 +22,7 @@ export interface QnAMakerPrompt { /** * The QnA object returned from the API (Optional parameter). */ - qna?: object; // eslint-disable-line @typescript-eslint/ban-types + qna?: object; /** * Display Text - Text displayed to represent a follow up question prompt. diff --git a/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerResult.ts b/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerResult.ts index 98343eff62..6f51a21e4b 100644 --- a/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerResult.ts +++ b/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerResult.ts @@ -31,7 +31,7 @@ export interface QnAMakerResult { /** * Metadata associated with the answer (If any) */ - metadata?: any; // eslint-disable-line @typescript-eslint/no-explicit-any + metadata?: any; /** * The source from which the QnA was extracted (If any) diff --git a/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerTraceInfo.ts b/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerTraceInfo.ts index 44d83c7972..6046249f22 100644 --- a/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerTraceInfo.ts +++ b/libraries/botbuilder-ai/src/qnamaker-interfaces/qnamakerTraceInfo.ts @@ -42,12 +42,12 @@ export interface QnAMakerTraceInfo { /** * Filters used on query. Not used in JavaScript SDK v4 yet. */ - strictFilters: any[]; // eslint-disable-line @typescript-eslint/no-explicit-any + strictFilters: any[]; /** * Metadata related to query. Not used in JavaScript SDK v4 yet. */ - metadataBoost: any[]; // eslint-disable-line @typescript-eslint/no-explicit-any + metadataBoost: any[]; /** * The context for multi-turn responses. diff --git a/libraries/botbuilder-ai/src/qnamaker-utils/activeLearningUtils.ts b/libraries/botbuilder-ai/src/qnamaker-utils/activeLearningUtils.ts index fae501adf6..dfe2175722 100644 --- a/libraries/botbuilder-ai/src/qnamaker-utils/activeLearningUtils.ts +++ b/libraries/botbuilder-ai/src/qnamaker-utils/activeLearningUtils.ts @@ -59,12 +59,12 @@ export class ActiveLearningUtils { ActiveLearningUtils.includeForClustering( prevScore, qnaSearchResults[i].score * 100, - ActiveLearningUtils.PreviousLowScoreVariationMultiplier + ActiveLearningUtils.PreviousLowScoreVariationMultiplier, ) && this.includeForClustering( topAnswerScore, qnaSearchResults[i].score * 100, - ActiveLearningUtils.MaxLowScoreVariationMultiplier + ActiveLearningUtils.MaxLowScoreVariationMultiplier, ) ) { prevScore = qnaSearchResults[i].score * 100; diff --git a/libraries/botbuilder-ai/src/qnamaker-utils/bindToActivity.ts b/libraries/botbuilder-ai/src/qnamaker-utils/bindToActivity.ts index 099115bb8b..926ecda725 100644 --- a/libraries/botbuilder-ai/src/qnamaker-utils/bindToActivity.ts +++ b/libraries/botbuilder-ai/src/qnamaker-utils/bindToActivity.ts @@ -28,7 +28,6 @@ export class BindToActivity implements TemplateInterface> { * @param _data Data to bind to. If Null, then dc.State will be used. * @returns The linked activity. */ - // eslint-disable-next-line @typescript-eslint/ban-types async bind(_context: DialogContext, _data?: object): Promise> { return this.activity; } diff --git a/libraries/botbuilder-ai/src/qnamaker-utils/generateAnswerUtils.ts b/libraries/botbuilder-ai/src/qnamaker-utils/generateAnswerUtils.ts index 92deee4b51..60cd458a42 100644 --- a/libraries/botbuilder-ai/src/qnamaker-utils/generateAnswerUtils.ts +++ b/libraries/botbuilder-ai/src/qnamaker-utils/generateAnswerUtils.ts @@ -34,7 +34,10 @@ export class GenerateAnswerUtils { * @param {QnAMakerOptions} _options Settings used to configure the instance. * @param {QnAMakerEndpoint} endpoint The endpoint of the knowledge base to query. */ - constructor(public _options: QnAMakerOptions, private readonly endpoint: QnAMakerEndpoint) { + constructor( + public _options: QnAMakerOptions, + private readonly endpoint: QnAMakerEndpoint, + ) { this.httpRequestUtils = new HttpRequestUtils(); this.validateOptions(this._options); @@ -47,11 +50,11 @@ export class GenerateAnswerUtils { * @param {string} question Question which need to be queried. * @param {QnAMakerOptions} options (Optional) The options for the QnA Maker knowledge base. If null, constructor option is used for this instance. * @returns {Promise} a promise that resolves to the query results. - .*/ + */ async queryQnaService( endpoint: QnAMakerEndpoint, question: string, - options?: QnAMakerOptions + options?: QnAMakerOptions, ): Promise { const result = await this.queryQnaServiceRaw(endpoint, question, options); @@ -69,7 +72,7 @@ export class GenerateAnswerUtils { async queryQnaServiceRaw( endpoint: QnAMakerEndpoint, question: string, - options?: QnAMakerOptions + options?: QnAMakerOptions, ): Promise { const url = `${endpoint.host}/knowledgebases/${endpoint.knowledgeBaseId}/generateanswer`; const queryOptions: QnAMakerOptions = { ...this._options, ...options } as QnAMakerOptions; @@ -77,7 +80,7 @@ export class GenerateAnswerUtils { const legacyMetadata = this.getMetadata( queryOptions.strictFilters, queryOptions.strictFiltersJoinOperator, - queryOptions.filters + queryOptions.filters, ); queryOptions.strictFilters = legacyMetadata.metadata; queryOptions.filters = null; @@ -94,7 +97,7 @@ export class GenerateAnswerUtils { url, payloadBody, this.endpoint, - queryOptions.timeout + queryOptions.timeout, ); if (Array.isArray(qnaResults?.answers)) { @@ -115,8 +118,7 @@ export class GenerateAnswerUtils { async emitTraceInfo( turnContext: TurnContext, answers: QnAMakerResult[], - queryOptions?: QnAMakerOptions - // eslint-disable-next-line @typescript-eslint/no-explicit-any + queryOptions?: QnAMakerOptions, ): Promise { const requestOptions: QnAMakerOptions = { ...this._options, ...queryOptions }; const { scoreThreshold, top, strictFilters, metadataBoost, context, qnaId } = requestOptions; @@ -169,7 +171,7 @@ export class GenerateAnswerUtils { */ static sortAnswersWithinThreshold( answers: QnAMakerResult[] = [] as QnAMakerResult[], - queryOptions: QnAMakerOptions + queryOptions: QnAMakerOptions, ): QnAMakerResult[] { const minScore: number = typeof queryOptions.scoreThreshold === 'number' ? queryOptions.scoreThreshold : 0.001; @@ -183,7 +185,6 @@ export class GenerateAnswerUtils { .sort((a: QnAMakerResult, b: QnAMakerResult) => b.score - a.score); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any private formatQnaResult(qnaResult: QnAMakerResults | any): QnAMakerResults { qnaResult.answers = qnaResult.answers.map((answer: QnAMakerResult & { qnaId?: number }) => { answer.score = answer.score / 100; @@ -204,7 +205,7 @@ export class GenerateAnswerUtils { private validateScoreThreshold(scoreThreshold: number): void { if (typeof scoreThreshold !== 'number' || !(scoreThreshold > 0 && scoreThreshold <= 1)) { throw new TypeError( - `"${scoreThreshold}" is an invalid scoreThreshold. QnAMakerOptions.scoreThreshold must have a value between 0 and 1.` + `"${scoreThreshold}" is an invalid scoreThreshold. QnAMakerOptions.scoreThreshold must have a value between 0 and 1.`, ); } } @@ -212,7 +213,7 @@ export class GenerateAnswerUtils { private validateTop(qnaOptionTop: number): void { if (!Number.isInteger(qnaOptionTop) || qnaOptionTop < 1) { throw new RangeError( - `"${qnaOptionTop}" is an invalid top value. QnAMakerOptions.top must be an integer greater than 0.` + `"${qnaOptionTop}" is an invalid top value. QnAMakerOptions.top must be an integer greater than 0.`, ); } } @@ -220,7 +221,7 @@ export class GenerateAnswerUtils { private getMetadata( strictFilters: QnAMakerMetadata[], operator: JoinOperator, - filters: Filters + filters: Filters, ): { metadata: QnAMakerMetadata[]; compoundOperation: JoinOperator } { if (!strictFilters) { return { metadata: strictFilters, compoundOperation: operator ? operator : JoinOperator.AND }; diff --git a/libraries/botbuilder-ai/src/qnamaker-utils/httpRequestUtils.ts b/libraries/botbuilder-ai/src/qnamaker-utils/httpRequestUtils.ts index a799437409..cbb8005ec1 100644 --- a/libraries/botbuilder-ai/src/qnamaker-utils/httpRequestUtils.ts +++ b/libraries/botbuilder-ai/src/qnamaker-utils/httpRequestUtils.ts @@ -15,7 +15,7 @@ import { QnAMakerResults } from '../qnamaker-interfaces/qnamakerResults'; import { getFetch } from '../globals'; const fetch = getFetch(); -// eslint-disable-next-line @typescript-eslint/no-var-requires +// eslint-disable-next-line @typescript-eslint/no-require-imports const pjson: Record<'name' | 'version', string> = require('../../package.json'); /** * Http request utils class. @@ -37,7 +37,7 @@ export class HttpRequestUtils { requestUrl: string, payloadBody: string, endpoint: QnAMakerEndpoint, - timeout?: number + timeout?: number, ): Promise { if (!requestUrl) { throw new TypeError('Request url cannot be null.'); diff --git a/libraries/botbuilder-ai/src/qnamaker-utils/languageServiceUtils.ts b/libraries/botbuilder-ai/src/qnamaker-utils/languageServiceUtils.ts index 237a255000..ba3d016946 100644 --- a/libraries/botbuilder-ai/src/qnamaker-utils/languageServiceUtils.ts +++ b/libraries/botbuilder-ai/src/qnamaker-utils/languageServiceUtils.ts @@ -46,7 +46,10 @@ export class LanguageServiceUtils { * @param {QnAMakerOptions} _options Settings used to configure the instance. * @param {QnAMakerEndpoint} endpoint The endpoint of the knowledge base to query. */ - constructor(public _options: QnAMakerOptions, readonly endpoint: QnAMakerEndpoint) { + constructor( + public _options: QnAMakerOptions, + readonly endpoint: QnAMakerEndpoint, + ) { this.httpRequestUtils = new HttpRequestUtils(); this.validateOptions(this._options); @@ -92,7 +95,7 @@ export class LanguageServiceUtils { filters: this.getFilters( queryOptions.strictFilters, queryOptions.strictFiltersJoinOperator, - queryOptions.filters + queryOptions.filters, ), qnaId: queryOptions.qnaId, rankerType: queryOptions.rankerType, @@ -106,7 +109,7 @@ export class LanguageServiceUtils { url, payloadBody, this.endpoint, - queryOptions.timeout + queryOptions.timeout, ); if (Array.isArray(qnaResults?.answers)) { @@ -127,8 +130,7 @@ export class LanguageServiceUtils { async emitTraceInfo( turnContext: TurnContext, answers: QnAMakerResult[], - queryOptions?: QnAMakerOptions - // eslint-disable-next-line @typescript-eslint/no-explicit-any + queryOptions?: QnAMakerOptions, ): Promise { const requestOptions: QnAMakerOptions = { ...this._options, ...queryOptions }; const { scoreThreshold, top, strictFilters, metadataBoost, context, qnaId } = requestOptions; @@ -216,7 +218,7 @@ export class LanguageServiceUtils { private validateScoreThreshold(scoreThreshold: number): void { if (typeof scoreThreshold !== 'number' || !(scoreThreshold > 0 && scoreThreshold <= 1)) { throw new TypeError( - `"${scoreThreshold}" is an invalid scoreThreshold. QnAMakerOptions.scoreThreshold must have a value between 0 and 1.` + `"${scoreThreshold}" is an invalid scoreThreshold. QnAMakerOptions.scoreThreshold must have a value between 0 and 1.`, ); } } @@ -224,7 +226,7 @@ export class LanguageServiceUtils { private validateTop(qnaOptionTop: number): void { if (!Number.isInteger(qnaOptionTop) || qnaOptionTop < 1) { throw new RangeError( - `"${qnaOptionTop}" is an invalid top value. QnAMakerOptions.top must be an integer greater than 0.` + `"${qnaOptionTop}" is an invalid top value. QnAMakerOptions.top must be an integer greater than 0.`, ); } } @@ -232,7 +234,7 @@ export class LanguageServiceUtils { private getFilters( strictFilters: QnAMakerMetadata[], metadataJoinOperator: JoinOperator, - filters: Filters + filters: Filters, ): Filters { if (filters) { return filters; diff --git a/libraries/botbuilder-ai/tests/languageService.test.js b/libraries/botbuilder-ai/tests/languageService.test.js index df5812f6e7..a78f0ca309 100644 --- a/libraries/botbuilder-ai/tests/languageService.test.js +++ b/libraries/botbuilder-ai/tests/languageService.test.js @@ -50,6 +50,7 @@ describe('LanguageService', function () { }; let sandbox; + beforeEach(function () { sandbox = sinon.createSandbox(); nock.cleanAll(); @@ -63,7 +64,7 @@ describe('LanguageService', function () { nock(`https://${hostname}.cognitiveservices.azure.com`) .matchHeader('user-Agent', /botbuilder-ai\/4.*/) .post( - `/language/:query-knowledgebases?projectName=${knowledgeBaseId}&deploymentName=production&api-version=2021-10-01` + `/language/:query-knowledgebases?projectName=${knowledgeBaseId}&deploymentName=production&api-version=2021-10-01`, ) .replyWithFile(200, `${filePath}${file}`); }); @@ -160,7 +161,7 @@ describe('LanguageService', function () { sinon.match({ telemetryClient: sinon.match.instanceOf(NullTelemetryClient), logPersonalInformation: false, - }) + }), ); }); @@ -173,7 +174,7 @@ describe('LanguageService', function () { sinon.match({ telemetryClient: sinon.match.instanceOf(NullTelemetryClient), logPersonalInformation: false, - }) + }), ); }); }); @@ -425,7 +426,7 @@ describe('LanguageService', function () { metrics: sinon.match({ score: sinon.match.number, }), - }) + }), ) .once(); @@ -457,7 +458,7 @@ describe('LanguageService', function () { questionId: '-1', username: sinon.match.string, }), - }) + }), ) .once(); @@ -491,7 +492,7 @@ describe('LanguageService', function () { metrics: sinon.match({ score: sinon.match.number, }), - }) + }), ) .once(); @@ -518,7 +519,7 @@ describe('LanguageService', function () { foo: 'bar', ImportantProperty: 'ImportantValue', }), - }) + }), ) .once(); @@ -538,7 +539,7 @@ describe('LanguageService', function () { metrics: sinon.match({ score: sinon.match.number, }), - }) + }), ) .once(); @@ -573,7 +574,7 @@ describe('LanguageService', function () { username: sinon.match.string, }), metrics: sinon.match({ score }), - }) + }), ) .once(); @@ -584,7 +585,7 @@ describe('LanguageService', function () { context, null, { question: 'OVERRIDE', MyImportantProperty: 'MyImportantValue' }, - { score } + { score }, ); sandbox.verify(); @@ -701,6 +702,7 @@ describe('LanguageService', function () { }); }); }); + describe('QnAMakerDialog', function () { it('Construct QnAMakerDialog constructor with new LanguageService parameters', async function () { const strictFilters = [ diff --git a/libraries/botbuilder-ai/tests/luisRecognizer.test.js b/libraries/botbuilder-ai/tests/luisRecognizer.test.js index 466f49bead..3534b341c0 100644 --- a/libraries/botbuilder-ai/tests/luisRecognizer.test.js +++ b/libraries/botbuilder-ai/tests/luisRecognizer.test.js @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-non-literal-fs-filename */ const assert = require('assert'); const fs = require('fs-extra'); const nock = require('nock'); @@ -30,7 +29,7 @@ class ThrowErrorRecognizer extends LuisRecognizer { super( { applicationId: luisAppId, endpointKey: endpointKey }, { includeAllIntents: true, includeInstanceData: true }, - true + true, ); } @@ -138,7 +137,6 @@ function getExpectedData(oracle) { const query = 'verbose=(true|false)&staging=false&spellCheck=false&log=true'; const path = `/luis/v2\\.0/apps/${luisAppId}`; const pattern = `${path}\\?${query}`; - // eslint-disable-next-line security/detect-non-literal-regexp const uri = new RegExp(pattern); const requestContent = expectedData.text != undefined ? `"${expectedData.text}"` : undefined; const responseBody = expectedData.v2; @@ -171,7 +169,7 @@ async function testJson( telemetryClient, telemetryMetrics, telemetryProperties, - } = {} + } = {}, ) { const expectedPath = getExpectedPath(file); const expectedData = getExpectedData(expectedPath); @@ -187,7 +185,7 @@ async function testJson( logPersonalInformation, telemetryClient, }, - true + true, ); const result = await recognizer.recognize(context, telemetryProperties, telemetryMetrics); @@ -209,7 +207,7 @@ describe('LuisRecognizer', function () { const recognizer = new LuisRecognizer( { applicationId: luisAppId, endpointKey: endpointKey }, { includeAllIntents: true }, - true + true, ); const maybeIt = !mockLuis && endpointKey === 'MockedKey' ? it.skip : it; @@ -401,7 +399,7 @@ describe('LuisRecognizer', function () { assert(res.entities.Address[0].$instance.State[0].score); assert( res.entities.Address[0].$instance.State[0].score > 0 && - res.entities.Address[0].$instance.State[0].score <= 1 + res.entities.Address[0].$instance.State[0].score <= 1, ); }); @@ -410,7 +408,7 @@ describe('LuisRecognizer', function () { const recognizer = new LuisRecognizer( { applicationId: luisAppId, endpointKey: endpointKey }, - { includeAllIntents: true, apiVersion: 'v2', includeAPIResults: true } + { includeAllIntents: true, apiVersion: 'v2', includeAPIResults: true }, ); const context = new TestContext({ text: expectedData.text }); @@ -601,7 +599,7 @@ describe('LuisRecognizer', function () { const recognizer = new ThrowErrorRecognizer(); const context = new TestContext({ text: 'Hello world!' }); await assert.rejects(recognizer.recognize(context), Error('Test')); - } + }, ); maybeIt('should send user-agent header.', async () => { @@ -634,8 +632,8 @@ describe('LuisRecognizer', function () { assert.throws( () => new LuisRecognizer(endpointWithNoSubscriptionKey), new Error( - `Invalid \`endpointKey\` value detected: ${expectedSubscriptionKey}\nPlease make sure your endpointKey is a valid LUIS Endpoint Key, e.g. "048ec46dc58e495482b0c447cfdbd291".` - ) + `Invalid \`endpointKey\` value detected: ${expectedSubscriptionKey}\nPlease make sure your endpointKey is a valid LUIS Endpoint Key, e.g. "048ec46dc58e495482b0c447cfdbd291".`, + ), ); }); @@ -646,8 +644,8 @@ describe('LuisRecognizer', function () { assert.throws( () => new LuisRecognizer(endpointWithNoAppId), new Error( - `Invalid \`applicationId\` value detected: ${expectedApplicationId}\nPlease make sure your applicationId is a valid LUIS Application Id, e.g. "b31aeaf3-3511-495b-a07f-571fc873214b".` - ) + `Invalid \`applicationId\` value detected: ${expectedApplicationId}\nPlease make sure your applicationId is a valid LUIS Application Id, e.g. "b31aeaf3-3511-495b-a07f-571fc873214b".`, + ), ); }); @@ -655,8 +653,8 @@ describe('LuisRecognizer', function () { assert.throws( () => new LuisRecognizer('this.is.not.a.url'), new Error( - `Invalid \`applicationId\` value detected: ${expectedApplicationId}\nPlease make sure your applicationId is a valid LUIS Application Id, e.g. "b31aeaf3-3511-495b-a07f-571fc873214b".` - ) + `Invalid \`applicationId\` value detected: ${expectedApplicationId}\nPlease make sure your applicationId is a valid LUIS Application Id, e.g. "b31aeaf3-3511-495b-a07f-571fc873214b".`, + ), ); }); @@ -917,7 +915,7 @@ describe('LuisRecognizer', function () { telemetryClient: telemetryClient, logPersonalInformation: true, }, - true + true, ); const res = await recognizer.recognize(context, properties, metrics); @@ -998,7 +996,7 @@ describe('LuisRecognizer', function () { telemetryClient: telemetryClient, logPersonalInformation: true, }, - true + true, ); const res = await recognizer.recognize(context, properties, metrics); @@ -1037,7 +1035,7 @@ describe('LuisRecognizer', function () { const recognizer = new LuisRecognizer( { applicationId: luisAppId, endpointKey: endpointKey }, luisPredictionDefaultOptions, - true + true, ); const mergedOptions = luisPredictionUserOptions ? recognizer.setLuisPredictionOptions(recognizer.options, luisPredictionUserOptions) @@ -1060,7 +1058,7 @@ describe('LuisRecognizer', function () { const recognizer = new LuisRecognizer( { applicationId: luisAppId, endpointKey: endpointKey }, luisPredictionDefaultOptions, - true + true, ); const mergedOptions = recognizer.buildRecognizer(luisPredictionUserOptions); assert.strictEqual(mergedOptions.predictionOptions.includeAllIntents, false); @@ -1081,7 +1079,7 @@ describe('LuisRecognizer', function () { const recognizer = new LuisRecognizer( { applicationId: luisAppId, endpointKey: endpointKey }, luisPredictionDefaultOptions, - true + true, ); const mergedOptions = recognizer.buildRecognizer(luisPredictionUserOptions); assert.strictEqual(mergedOptions.options.includeAllIntents, false); @@ -1098,7 +1096,7 @@ describe('LuisRecognizer', function () { const recognizer = new LuisRecognizer( { applicationId: luisAppId, endpointKey: endpointKey }, luisPredictionDefaultOptions, - true + true, ); const mergedOptions = luisPredictionUserOptions ? recognizer.setLuisPredictionOptions(recognizer.options, luisPredictionUserOptions) diff --git a/libraries/botbuilder-ai/tests/luisSdk.test.js b/libraries/botbuilder-ai/tests/luisSdk.test.js index 8ecf61352a..c5d9668c02 100644 --- a/libraries/botbuilder-ai/tests/luisSdk.test.js +++ b/libraries/botbuilder-ai/tests/luisSdk.test.js @@ -25,7 +25,7 @@ function GetExpected(oracle) { const query = 'verbose=(true|false)(&staging=false&spellCheck=false&log=true|)'; const path = `/luis/v2\\.0/apps/${applicationId}`; const pattern = `${path}\\?${query}`; - const uri = new RegExp(pattern); // eslint-disable-line security/detect-non-literal-regexp + const uri = new RegExp(pattern); const requestContent = expected.text != undefined ? `"${expected.text}"` : undefined; const responseBody = expected; @@ -145,25 +145,31 @@ describe('LuisPredict', function () { this.timeout(10000); if (!mockLuis && k === 'MockedKey') { console.warn( - 'WARNING: skipping LuisRecognizer test suite because the LUISAPPKEY environment variable is not defined' + 'WARNING: skipping LuisRecognizer test suite because the LUISAPPKEY environment variable is not defined', ); return; } + it('test built-ins composite1', async function () { await TestJson('Composite1.json'); }); + it('test built-ins composite2', async function () { await TestJson('Composite2.json'); }); + it('test built-ins composite3', async function () { await TestJson('Composite3.json'); }); + it('test built-ins prebuilt', async function () { await TestJson('Prebuilt.json'); }); + it('test patterns', async function () { await TestJson('Patterns.json'); }); + it('should return single intent and a simple entity', async function () { const result = await TestJson('SingleIntent_SimplyEntity.json', false); diff --git a/libraries/botbuilder-ai/tests/luisV3OracleTests.test.js b/libraries/botbuilder-ai/tests/luisV3OracleTests.test.js index 4f52838edb..2148ada608 100644 --- a/libraries/botbuilder-ai/tests/luisV3OracleTests.test.js +++ b/libraries/botbuilder-ai/tests/luisV3OracleTests.test.js @@ -30,7 +30,7 @@ async function TestJson( telemetryProperties, telemetryMetrics, logPersonalInformation, - useUtteranceInsteadOfContext = false + useUtteranceInsteadOfContext = false, ) { if (includeAllIntents === undefined) includeAllIntents = true; if (includeInstance === undefined) includeInstance = true; @@ -117,7 +117,7 @@ describe('LuisRecognizer V3', function () { if (!mockLuis && endpointKey === 'MockedKey') { console.warn( - 'WARNING: skipping LuisRecognizer test suite because the LUISAPPKEY environment variable is not defined' + 'WARNING: skipping LuisRecognizer test suite because the LUISAPPKEY environment variable is not defined', ); return; } @@ -136,7 +136,7 @@ describe('LuisRecognizer V3', function () { undefined, undefined, undefined, - useUtteranceInsteadOfContext + useUtteranceInsteadOfContext, ); }); @@ -154,7 +154,7 @@ describe('LuisRecognizer V3', function () { undefined, undefined, undefined, - useUtteranceInsteadOfContext + useUtteranceInsteadOfContext, ); }); diff --git a/libraries/botbuilder-ai/tests/qnaMaker.test.js b/libraries/botbuilder-ai/tests/qnaMaker.test.js index 8c3c2eede4..63a376a796 100644 --- a/libraries/botbuilder-ai/tests/qnaMaker.test.js +++ b/libraries/botbuilder-ai/tests/qnaMaker.test.js @@ -49,6 +49,7 @@ describe('QnAMaker', function () { }; let sandbox; + beforeEach(function () { sandbox = sinon.createSandbox(); nock.cleanAll(); @@ -157,7 +158,7 @@ describe('QnAMaker', function () { sinon.match({ telemetryClient: sinon.match.instanceOf(NullTelemetryClient), logPersonalInformation: false, - }) + }), ); }); @@ -170,7 +171,7 @@ describe('QnAMaker', function () { sinon.match({ telemetryClient: sinon.match.instanceOf(NullTelemetryClient), logPersonalInformation: false, - }) + }), ); }); }); @@ -195,6 +196,7 @@ describe('QnAMaker', function () { assert.deepStrictEqual(results[0].metadata, filters.metadataFilter.metadata); }); + it('returns answer with strictFilters specified', async function () { const qna = new QnAMaker(endpoint); const context = new TestContext({ text: 'where are the unicorns?' }); @@ -214,6 +216,7 @@ describe('QnAMaker', function () { assert.deepStrictEqual(results[0].metadata, strictFilters); }); + it('returns answer without any options specified', async function () { const qna = new QnAMaker(endpoint); const context = new TestContext({ text: 'where are the unicorns?' }); @@ -361,7 +364,7 @@ describe('QnAMaker', function () { sinon.match({ id: qnaId, qnaId: sinon.match.undefined, - }) + }), ); }); @@ -432,7 +435,7 @@ describe('QnAMaker', function () { metrics: sinon.match({ score: sinon.match.number, }), - }) + }), ) .once(); @@ -464,7 +467,7 @@ describe('QnAMaker', function () { articleFound: 'true', }), metrics: { score: 0 }, - }) + }), ) .once(); @@ -499,7 +502,7 @@ describe('QnAMaker', function () { metrics: sinon.match({ score: sinon.match.number, }), - }) + }), ) .once(); @@ -526,7 +529,7 @@ describe('QnAMaker', function () { foo: 'bar', ImportantProperty: 'ImportantValue', }), - }) + }), ) .once(); @@ -546,7 +549,7 @@ describe('QnAMaker', function () { metrics: sinon.match({ score: sinon.match.number, }), - }) + }), ) .once(); @@ -581,7 +584,7 @@ describe('QnAMaker', function () { username: sinon.match.string, }), metrics: sinon.match({ score }), - }) + }), ) .once(); @@ -592,7 +595,7 @@ describe('QnAMaker', function () { context, null, { question: 'OVERRIDE', MyImportantProperty: 'MyImportantValue' }, - { score } + { score }, ); sandbox.verify(); @@ -610,6 +613,7 @@ describe('QnAMaker', function () { message: 'QnAMaker.getAnswers() requires a TurnContext.', }); }); + it('throws TypeError if context is undefined in getAnswersRaw', async function () { const qna = new QnAMaker(endpoint); @@ -703,7 +707,7 @@ describe('QnAMaker', function () { assert(found); const traceActivity = context.sent.find( - (activity) => activity.type === 'trace' && activity.name === 'QnAMaker' + (activity) => activity.type === 'trace' && activity.name === 'QnAMaker', ); sinon.assert.match( @@ -719,7 +723,7 @@ describe('QnAMaker', function () { knowledgeBaseId, scoreThreshold: sinon.match.number, }), - }) + }), ); }); diff --git a/libraries/botbuilder-ai/tests/qnaMakerDialog.test.js b/libraries/botbuilder-ai/tests/qnaMakerDialog.test.js index 77d9db5f5f..8e6e084267 100644 --- a/libraries/botbuilder-ai/tests/qnaMakerDialog.test.js +++ b/libraries/botbuilder-ai/tests/qnaMakerDialog.test.js @@ -20,8 +20,7 @@ const { const KB_ID = process.env.QNAKNOWLEDGEBASEID; const ENDPOINT_KEY = process.env.QNAENDPOINTKEY; const HOSTNAME = process.env.QNAHOSTNAME || 'test-qna-app'; -const isMockQna = false || !(KB_ID && ENDPOINT_KEY); - +const isMockQna = !(KB_ID && ENDPOINT_KEY); const beginMessage = { text: 'begin', type: 'message' }; describe('QnAMakerDialog', function () { @@ -297,6 +296,7 @@ describe('QnAMakerDialog', function () { describe('Active Learning', function () { let sandbox; const testFilesPath = `${__dirname}/TestData/QnAMakerDialog/`; + beforeEach(function () { nock.cleanAll(); nock(`https://${HOSTNAME}.azurewebsites.net`) @@ -329,7 +329,7 @@ describe('QnAMakerDialog', function () { undefined, undefined, activeLearningCardTitle, - cardNoMatchText + cardNoMatchText, ); dm.rootDialog = qnaDialog; @@ -386,7 +386,7 @@ describe('QnAMakerDialog', function () { undefined, undefined, activeLearningCardTitle, - cardNoMatchText + cardNoMatchText, ); qnaDialog.useTeamsAdaptiveCard = true; @@ -447,7 +447,7 @@ describe('QnAMakerDialog', function () { strictEqual(noMatchingQuestionsText, cardNoMatchText); return MessageFactory.suggestedActions(suggestionsList, noMatchingQuestionsText); }, - cardNoMatchText + cardNoMatchText, ); dm.rootDialog = qnaDialog; @@ -470,7 +470,7 @@ describe('QnAMakerDialog', function () { const endpointKey = 'dummyEndpointKey'; throws( () => new QnAMakerDialog(kbId, endpointKey, HOSTNAME, undefined, undefined, (_) => {}, undefined), - new Error('cardNoMatchText is required when using the suggestionsActivityFactory.') + new Error('cardNoMatchText is required when using the suggestionsActivityFactory.'), ); }); @@ -493,7 +493,7 @@ describe('QnAMakerDialog', function () { strictEqual(noMatchingQuestionsText, cardNoMatchText); return 1; }, - cardNoMatchText + cardNoMatchText, ); dm.rootDialog = qnaDialog; @@ -506,7 +506,7 @@ describe('QnAMakerDialog', function () { (thrown) => thrown.message.includes('invalid_type') && thrown.message.includes('"expected": "object"') && - thrown.message.includes('"received": "number"') + thrown.message.includes('"received": "number"'), ); }); @@ -535,7 +535,7 @@ describe('QnAMakerDialog', function () { undefined, undefined, suggestionsCardTitle, - cardNoMatchText + cardNoMatchText, ); dm.rootDialog = qnaDialog; @@ -545,7 +545,7 @@ describe('QnAMakerDialog', function () { await rejects( adapter.send('QnaMaker_TopNAnswer.json').startTest(), - (thrown) => thrown.message.includes('invalid_type') && thrown.message.includes('Required') + (thrown) => thrown.message.includes('invalid_type') && thrown.message.includes('Required'), ); sandbox.verify(); @@ -576,7 +576,7 @@ describe('QnAMakerDialog', function () { undefined, undefined, suggestionsCardTitle, - cardNoMatchText + cardNoMatchText, ); qnaDialog.useTeamsAdaptiveCard = true; @@ -587,7 +587,7 @@ describe('QnAMakerDialog', function () { await rejects( adapter.send('QnaMaker_TopNAnswer.json').startTest(), - (thrown) => thrown.message.includes('invalid_type') && thrown.message.includes('Required') + (thrown) => thrown.message.includes('invalid_type') && thrown.message.includes('Required'), ); sandbox.verify(); diff --git a/libraries/botbuilder-ai/tests/qnaMakerRecognizer.test.js b/libraries/botbuilder-ai/tests/qnaMakerRecognizer.test.js index eab050fd35..cd00ef2cd3 100644 --- a/libraries/botbuilder-ai/tests/qnaMakerRecognizer.test.js +++ b/libraries/botbuilder-ai/tests/qnaMakerRecognizer.test.js @@ -42,7 +42,7 @@ const validateAnswers = (result) => { strictEqual( Object.entries(result.entities.answer).length, 1, - 'if there is a match there should only be 1 top answer' + 'if there is a match there should only be 1 top answer', ); strictEqual(result.entities.$instance.answer[0].startIndex, 0); ok(result.entities.$instance.answer[0].endIndex); diff --git a/libraries/botbuilder-applicationinsights/eslint.config.cjs b/libraries/botbuilder-applicationinsights/eslint.config.cjs deleted file mode 100644 index 63647b52cc..0000000000 --- a/libraries/botbuilder-applicationinsights/eslint.config.cjs +++ /dev/null @@ -1,10 +0,0 @@ -const onlyWarn = require("eslint-plugin-only-warn"); -const sharedConfig = require("../../eslint.config.cjs") - -module.exports = [ - ...sharedConfig, - { - plugins: { - "only-warn": onlyWarn, - }, - }]; diff --git a/libraries/botbuilder-applicationinsights/package.json b/libraries/botbuilder-applicationinsights/package.json index e414308a7d..746c82a0f2 100644 --- a/libraries/botbuilder-applicationinsights/package.json +++ b/libraries/botbuilder-applicationinsights/package.json @@ -30,8 +30,7 @@ "dependencies": { "applicationinsights": "^2.9.6", "botbuilder-core": "4.1.6", - "cls-hooked": "^4.2.2", - "eslint-plugin-only-warn": "^1.1.0" + "cls-hooked": "^4.2.2" }, "scripts": { "build": "tsc -b", @@ -39,7 +38,7 @@ "build:rollup": "yarn clean && yarn build && api-extractor run --verbose --local", "clean": "rimraf _ts3.4 lib tsconfig.tsbuildinfo", "depcheck": "depcheck --config ../../.depcheckrc", - "lint": "eslint .", + "lint": "eslint . --config ../../eslint.config.cjs", "postbuild": "downlevel-dts lib _ts3.4/lib --checksum", "test": "npm-run-all build test:mocha", "test:compat": "api-extractor run --verbose", diff --git a/libraries/botbuilder-applicationinsights/src/applicationInsightsTelemetryClient.ts b/libraries/botbuilder-applicationinsights/src/applicationInsightsTelemetryClient.ts index 93cea83548..af029818e0 100644 --- a/libraries/botbuilder-applicationinsights/src/applicationInsightsTelemetryClient.ts +++ b/libraries/botbuilder-applicationinsights/src/applicationInsightsTelemetryClient.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /** * @module botbuilder-applicationinsights */ diff --git a/libraries/botbuilder-applicationinsights/src/telemetryInitializerMiddleware.ts b/libraries/botbuilder-applicationinsights/src/telemetryInitializerMiddleware.ts index 2318afcab2..b07e9f7e89 100644 --- a/libraries/botbuilder-applicationinsights/src/telemetryInitializerMiddleware.ts +++ b/libraries/botbuilder-applicationinsights/src/telemetryInitializerMiddleware.ts @@ -1,9 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License -import { TelemetryLoggerMiddleware } from 'botbuilder-core'; -import { Middleware } from 'botbuilder-core'; -import { TurnContext } from 'botbuilder-core'; +import { TelemetryLoggerMiddleware, Middleware, TurnContext } from 'botbuilder-core'; import { CorrelationContext } from 'applicationinsights/out/AutoCollection/CorrelationContextManager'; import * as appInsights from 'applicationinsights'; diff --git a/libraries/botbuilder-applicationinsights/tests/TelemetryWaterfallTest.test.js b/libraries/botbuilder-applicationinsights/tests/TelemetryWaterfallTest.test.js index 28ada17e39..51ba2ca546 100644 --- a/libraries/botbuilder-applicationinsights/tests/TelemetryWaterfallTest.test.js +++ b/libraries/botbuilder-applicationinsights/tests/TelemetryWaterfallTest.test.js @@ -90,7 +90,7 @@ describe('TelemetryWaterfall', function () { if (telemetry.name === 'WaterfallStep') { assert( telemetry.properties.StepName === 'Step' + (count + 1) + 'of' + dialog.steps.length, - 'waterfallstep step name is wrong' + 'waterfallstep step name is wrong', ); count++; } @@ -252,23 +252,23 @@ describe('TelemetryWaterfall', function () { assert( component.findDialog('secondary').telemetryClient instanceof NullTelemetryClient, - 'should be nulltelemetryclient by default' + 'should be nulltelemetryclient by default', ); assert( component.telemetryClient instanceof NullTelemetryClient, - 'child dialog should have same telemetry client' + 'child dialog should have same telemetry client', ); component.telemetryClient = new TestClient(); assert( component.findDialog('secondary').telemetryClient instanceof TestClient, - 'child dialogs should now be TestClient' + 'child dialogs should now be TestClient', ); assert(component.telemetryClient instanceof TestClient, 'component should have a testclient as well'); assert( component.telemetryClient === component.findDialog('secondary').telemetryClient, - 'component should have same client as children' + 'component should have same client as children', ); component.addDialog(new WaterfallDialog('third'), [ @@ -279,29 +279,29 @@ describe('TelemetryWaterfall', function () { assert( component.findDialog('third').telemetryClient instanceof TestClient, - 'child dialogs should now be TestClient' + 'child dialogs should now be TestClient', ); assert( component.findDialog('secondary').telemetryClient instanceof TestClient, - 'child dialogs should now be TestClient' + 'child dialogs should now be TestClient', ); assert( component.telemetryClient === component.findDialog('third').telemetryClient, - 'component should have same client as new children' + 'component should have same client as new children', ); assert( component.findDialog('third').telemetryClient === component.findDialog('secondary').telemetryClient, - 'children should have identical clients' + 'children should have identical clients', ); component.telemetryClient = null; assert( component.findDialog('secondary').telemetryClient instanceof NullTelemetryClient, - 'child dialog should be reset to nulltelemetryclient' + 'child dialog should be reset to nulltelemetryclient', ); assert( component.telemetryClient instanceof NullTelemetryClient, - 'component should be reset to nulltelemetryclient' + 'component should be reset to nulltelemetryclient', ); }); }); diff --git a/libraries/botbuilder-applicationinsights/tests/telemetryInitializer.test.js b/libraries/botbuilder-applicationinsights/tests/telemetryInitializer.test.js index f3286c9f12..182abc2a90 100644 --- a/libraries/botbuilder-applicationinsights/tests/telemetryInitializer.test.js +++ b/libraries/botbuilder-applicationinsights/tests/telemetryInitializer.test.js @@ -151,7 +151,7 @@ describe('TelemetryInitializerMiddleware', function () { (err) => { assert.strictEqual(err.message, 'context is null'); return true; - } + }, ); }); @@ -175,7 +175,7 @@ describe('TelemetryInitializerMiddleware', function () { () => new Promise((resolve) => { resolve(); - }) + }), ); const updatedContext = appInsights.getCorrelationContext(); @@ -200,7 +200,7 @@ describe('TelemetryInitializerMiddleware', function () { () => new Promise((resolve) => { resolve(); - }) + }), ); const updatedContext = appInsights.getCorrelationContext(); @@ -229,7 +229,7 @@ describe('TelemetryInitializerMiddleware', function () { () => new Promise((resolve) => { resolve(); - }) + }), ); const updatedContext = appInsights.getCorrelationContext(); diff --git a/libraries/botbuilder-azure-blobs/eslint.config.cjs b/libraries/botbuilder-azure-blobs/eslint.config.cjs deleted file mode 100644 index 63647b52cc..0000000000 --- a/libraries/botbuilder-azure-blobs/eslint.config.cjs +++ /dev/null @@ -1,10 +0,0 @@ -const onlyWarn = require("eslint-plugin-only-warn"); -const sharedConfig = require("../../eslint.config.cjs") - -module.exports = [ - ...sharedConfig, - { - plugins: { - "only-warn": onlyWarn, - }, - }]; diff --git a/libraries/botbuilder-azure-blobs/package.json b/libraries/botbuilder-azure-blobs/package.json index 656322961d..0e34526d4b 100644 --- a/libraries/botbuilder-azure-blobs/package.json +++ b/libraries/botbuilder-azure-blobs/package.json @@ -30,7 +30,6 @@ "@azure/storage-blob": "^12.24.0", "botbuilder-core": "4.1.6", "botbuilder-stdlib": "4.1.6", - "eslint-plugin-only-warn": "^1.1.0", "p-map": "^4.0.0", "zod": "^3.23.8", "@azure/core-http": "^3.0.4" @@ -40,7 +39,7 @@ "build-docs": "typedoc --theme markdown --entryPoint botbuilder-azure-blobs --excludePrivate --includeDeclarations --ignoreCompilerErrors --module amd --out ..\\..\\doc\\botbuilder-azure-blobs .\\lib\\index.d.ts --hideGenerator --name \"Bot Builder SDK - Azure Blobs\" --readme none", "clean": "rimraf _ts3.4 lib tsconfig.tsbuildinfo", "depcheck": "depcheck --config ../../.depcheckrc", - "lint": "eslint .", + "lint": "eslint . --config ../../eslint.config.cjs", "postbuild": "downlevel-dts lib _ts3.4/lib --checksum", "test": "yarn build && nyc mocha --check-leaks tests", "test:compat": "api-extractor run --verbose" diff --git a/libraries/botbuilder-azure-blobs/src/blobsStorage.ts b/libraries/botbuilder-azure-blobs/src/blobsStorage.ts index 4b7d02c061..8b6825d89c 100644 --- a/libraries/botbuilder-azure-blobs/src/blobsStorage.ts +++ b/libraries/botbuilder-azure-blobs/src/blobsStorage.ts @@ -54,7 +54,7 @@ export class BlobsStorage implements Storage { containerName: string, options?: BlobsStorageOptions, url = '', - credential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential + credential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential, ) { if (url != '' && credential != null) { z.object({ url: z.string() }).parse({ @@ -80,7 +80,7 @@ export class BlobsStorage implements Storage { this._containerClient = new ContainerClient( connectionString, containerName, - options?.storagePipelineOptions + options?.storagePipelineOptions, ); // At most one promise at a time to be friendly to local emulator users @@ -121,7 +121,7 @@ export class BlobsStorage implements Storage { const blob = await ignoreError( this._containerClient.getBlobClient(sanitizeBlobKey(key)).download(), - isStatusCodeError(404) + isStatusCodeError(404), ); if (!blob) { @@ -140,7 +140,7 @@ export class BlobsStorage implements Storage { }, { concurrency: this._concurrency, - } + }, ) ).reduce((acc, { key, value }) => (value ? { ...acc, [key]: value } : acc), {}); } @@ -158,18 +158,25 @@ export class BlobsStorage implements Storage { await pmap( Object.entries(changes), - ([key, { eTag = '', ...change }]) => { - const blob = this._containerClient.getBlockBlobClient(sanitizeBlobKey(key)); - const serialized = JSON.stringify(change); - - return blob.upload(serialized, serialized.length, { - conditions: typeof eTag === 'string' && eTag !== '*' ? { ifMatch: eTag } : {}, - blobHTTPHeaders: { blobContentType: 'application/json' }, - }); + async ([key, { eTag = '', ...change }]) => { + try { + const blob = this._containerClient.getBlockBlobClient(sanitizeBlobKey(key)); + const serialized = JSON.stringify(change); + return await blob.upload(serialized, serialized.length, { + conditions: typeof eTag === 'string' && eTag !== '*' ? { ifMatch: eTag } : {}, + blobHTTPHeaders: { blobContentType: 'application/json' }, + }); + } catch (err: any) { + if (err.statusCode === 412) { + throw new Error(`Storage: error writing "${key}" due to eTag conflict.`); + } else { + throw err; + } + } }, { concurrency: this._concurrency, - } + }, ); } @@ -189,7 +196,7 @@ export class BlobsStorage implements Storage { (key) => ignoreError(this._containerClient.deleteBlob(sanitizeBlobKey(key)), isStatusCodeError(404)), { concurrency: this._concurrency, - } + }, ); } } diff --git a/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts b/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts index 23f1919847..af31ec7e7c 100644 --- a/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts +++ b/libraries/botbuilder-azure-blobs/src/blobsTranscriptStore.ts @@ -44,7 +44,7 @@ function getBlobKey(activity: Activity, options?: BlobsTranscriptStoreOptions): return sanitizeBlobKey( [activity.channelId, activity.conversation.id, `${formatTicks(timestamp)}-${activity.id}.json`].join('/'), - options + options, ); } @@ -102,7 +102,7 @@ export class BlobsTranscriptStore implements TranscriptStore { containerName: string, options?: BlobsTranscriptStoreOptions, blobServiceUri = '', - tokenCredential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential + tokenCredential?: StorageSharedKeyCredential | AnonymousCredential | TokenCredential, ) { if (blobServiceUri != '' && tokenCredential != null) { z.object({ blobServiceUri: z.string() }).parse({ @@ -116,7 +116,7 @@ export class BlobsTranscriptStore implements TranscriptStore { this._containerClient = new ContainerClient( blobServiceUri, tokenCredential, - options?.storagePipelineOptions + options?.storagePipelineOptions, ); // At most one promise at a time to be friendly to local emulator users @@ -132,7 +132,7 @@ export class BlobsTranscriptStore implements TranscriptStore { this._containerClient = new ContainerClient( connectionString, containerName, - options?.storagePipelineOptions + options?.storagePipelineOptions, ); // At most one promise at a time to be friendly to local emulator users @@ -170,7 +170,7 @@ export class BlobsTranscriptStore implements TranscriptStore { channelId: string, conversationId: string, continuationToken?: string, - startDate?: Date + startDate?: Date, ): Promise> { z.object({ channelId: z.string(), conversationId: z.string() }).parse({ channelId, conversationId }); @@ -195,7 +195,7 @@ export class BlobsTranscriptStore implements TranscriptStore { const fromIdx = startDate != null ? blobItems.findIndex( - (blobItem) => blobItem?.properties?.createdOn && blobItem?.properties?.createdOn >= startDate + (blobItem) => blobItem?.properties?.createdOn && blobItem?.properties?.createdOn >= startDate, ) : 0; @@ -213,7 +213,7 @@ export class BlobsTranscriptStore implements TranscriptStore { const activity = (await StreamConsumers.json(readableStreamBody)) as any; return { ...activity, timestamp: new Date(activity.timestamp) } as Activity; }, - { concurrency: this._concurrency } + { concurrency: this._concurrency }, ); activities.forEach((activity) => { diff --git a/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js b/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js index 350a4c64a8..1a7fcb4dd8 100644 --- a/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js +++ b/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js @@ -26,7 +26,7 @@ describe('BlobsStorage', function () { assert.throws(() => new BlobsStorage(null, null, null, [], {}), 'throws for missing url'); assert.throws( () => new BlobsStorage(null, null, null, 'url', {}), - ReferenceError('Invalid credential type.') + ReferenceError('Invalid credential type.'), ); }); @@ -40,7 +40,7 @@ describe('BlobsStorage', function () { null, null, 'https://test.blob.core.windows.net/blob', - new StorageSharedKeyCredential('accountName', 'accountKey') + new StorageSharedKeyCredential('accountName', 'accountKey'), ); }); }); @@ -53,6 +53,21 @@ describe('BlobsStorage', function () { maybeIt('should write a set of values', async () => { await client.write({ foo, bar }); }); + + maybeIt('should fail with eTag conflict error', async () => { + const changes = { + item1: { + key1: 'value1', + eTag: 'etag1', + }, + item2: { + key2: 'value2', + eTag: 'etag1', + }, + }; + + await assert.rejects(() => client.write(changes), 'Storage: error writing "item2" due to eTag conflict.'); + }); }); describe('delete()', function () { @@ -87,6 +102,7 @@ describe('BlobsStorage', function () { } let sandbox; + beforeEach(function () { sandbox = sinon.createSandbox({}); }); diff --git a/libraries/botbuilder-azure-blobs/tests/blobsTranscriptStore.test.js b/libraries/botbuilder-azure-blobs/tests/blobsTranscriptStore.test.js index 0399ad5255..96dc2157d5 100644 --- a/libraries/botbuilder-azure-blobs/tests/blobsTranscriptStore.test.js +++ b/libraries/botbuilder-azure-blobs/tests/blobsTranscriptStore.test.js @@ -72,7 +72,7 @@ describe('BlobsTranscriptStore', function () { assert.throws(() => new BlobsTranscriptStore(null, null, null, [], {}), 'throws for missing url'); assert.throws( () => new BlobsTranscriptStore(null, null, null, 'url', {}), - ReferenceError('Invalid credential type.') + ReferenceError('Invalid credential type.'), ); }); @@ -110,7 +110,7 @@ describe('BlobsTranscriptStore', function () { channelId, conversationId, undefined, - rest[0].timestamp + rest[0].timestamp, ); assert.deepStrictEqual(result.items, rest); }); @@ -154,7 +154,7 @@ describe('BlobsTranscriptStore', function () { channelId, id, created, - })) + })), ); }); }); diff --git a/libraries/botbuilder-lg/eslint.config.cjs b/libraries/botbuilder-lg/eslint.config.cjs index d355eccb1c..ab85c270af 100644 --- a/libraries/botbuilder-lg/eslint.config.cjs +++ b/libraries/botbuilder-lg/eslint.config.cjs @@ -1,13 +1,8 @@ -const onlyWarn = require("eslint-plugin-only-warn"); -const sharedConfig = require("../../eslint.config.cjs") +const sharedConfig = require('../../eslint.config.cjs'); module.exports = [ ...sharedConfig, { - ignores: ["**/generated/*"], + ignores: ['**/generated/*'], }, - { - plugins: { - "only-warn": onlyWarn, - }, - }]; +]; diff --git a/libraries/botbuilder-lg/package.json b/libraries/botbuilder-lg/package.json index ec2c204e22..aebc699762 100644 --- a/libraries/botbuilder-lg/package.json +++ b/libraries/botbuilder-lg/package.json @@ -21,7 +21,6 @@ "dependencies": { "adaptive-expressions": "4.1.6", "antlr4ts": "0.5.0-alpha.4", - "eslint-plugin-only-warn": "^1.1.0", "lodash": "^4.17.19", "uuid": "^10.0.0" }, diff --git a/libraries/botbuilder-lg/src/analyzer.ts b/libraries/botbuilder-lg/src/analyzer.ts index 46775a9c47..5ff8b7dc3f 100644 --- a/libraries/botbuilder-lg/src/analyzer.ts +++ b/libraries/botbuilder-lg/src/analyzer.ts @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-object-injection */ /** * @module botbuilder-lg */ @@ -16,7 +15,7 @@ import { LGTemplateParserVisitor } from './generated/LGTemplateParserVisitor'; import { Template } from './template'; import { TemplateExtensions } from './templateExtensions'; import { Templates } from './templates'; -import keyBy = require('lodash/keyBy'); +import keyBy from 'lodash/keyBy'; import { IfConditionRuleContext, @@ -37,7 +36,8 @@ import { TemplateErrors } from './templateErrors'; */ export class Analyzer extends AbstractParseTreeVisitor - implements LGTemplateParserVisitor { + implements LGTemplateParserVisitor +{ /** * Templates. */ @@ -85,7 +85,7 @@ export class Analyzer throw new Error( `${TemplateErrors.loopDetected} ${this.evalutationTargetStack .reverse() - .map((e) => e.templateName)} => ${templateName}` + .map((e) => e.templateName)} => ${templateName}`, ); } } diff --git a/libraries/botbuilder-lg/src/customizedMemory.ts b/libraries/botbuilder-lg/src/customizedMemory.ts index 58430f14f5..d95ecfae58 100644 --- a/libraries/botbuilder-lg/src/customizedMemory.ts +++ b/libraries/botbuilder-lg/src/customizedMemory.ts @@ -63,7 +63,6 @@ export class CustomizedMemory implements MemoryInterface { * @param _path Memory path. * @param _value Value to set. */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars setValue(_path: string, _value: any): void { return; } diff --git a/libraries/botbuilder-lg/src/diagnostic.ts b/libraries/botbuilder-lg/src/diagnostic.ts index 0c2aa691c1..a8deb8a989 100644 --- a/libraries/botbuilder-lg/src/diagnostic.ts +++ b/libraries/botbuilder-lg/src/diagnostic.ts @@ -43,7 +43,7 @@ export class Diagnostic { message: string, severity: DiagnosticSeverity = DiagnosticSeverity.Error, source?: string, - code?: string + code?: string, ) { this.message = message; this.range = range; diff --git a/libraries/botbuilder-lg/src/errorListener.ts b/libraries/botbuilder-lg/src/errorListener.ts index 96c394b4ec..8a04e8dc18 100644 --- a/libraries/botbuilder-lg/src/errorListener.ts +++ b/libraries/botbuilder-lg/src/errorListener.ts @@ -48,22 +48,21 @@ export class ErrorListener implements ANTLRErrorListener { offendingSymbol: any, line: number, charPositionInLine: number, - // eslint-disable-next-line @typescript-eslint/no-unused-vars msg: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars - e: RecognitionException | undefined + e: RecognitionException | undefined, ): void { const startPosition: Position = new Position(this.lineOffset + line, charPositionInLine); const stopPosition: Position = new Position( this.lineOffset + line, - charPositionInLine + offendingSymbol.stopIndex - offendingSymbol.startIndex + 1 + charPositionInLine + offendingSymbol.stopIndex - offendingSymbol.startIndex + 1, ); const range: Range = new Range(startPosition, stopPosition); const diagnostic: Diagnostic = new Diagnostic( range, TemplateErrors.syntaxError(msg), DiagnosticSeverity.Error, - this.source + this.source, ); throw new TemplateException(diagnostic.toString(), [diagnostic]); diff --git a/libraries/botbuilder-lg/src/evaluationOptions.ts b/libraries/botbuilder-lg/src/evaluationOptions.ts index a2cac51423..c73fd6ccfa 100644 --- a/libraries/botbuilder-lg/src/evaluationOptions.ts +++ b/libraries/botbuilder-lg/src/evaluationOptions.ts @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-object-injection */ /** * @module botbuilder-lg */ diff --git a/libraries/botbuilder-lg/src/evaluator.ts b/libraries/botbuilder-lg/src/evaluator.ts index 2c1110a1d4..ec5c7a8129 100644 --- a/libraries/botbuilder-lg/src/evaluator.ts +++ b/libraries/botbuilder-lg/src/evaluator.ts @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-object-injection */ /* eslint-disable security/detect-non-literal-fs-filename */ /** * @module botbuilder-lg @@ -19,7 +18,7 @@ import { Template } from './template'; import { TemplateErrors } from './templateErrors'; import { TemplateExtensions } from './templateExtensions'; import { Templates } from './templates'; -import keyBy = require('lodash/keyBy'); +import keyBy from 'lodash/keyBy'; import { Constant, @@ -118,7 +117,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe // generate a new customzied expression parser by injecting the templates as functions this.expressionParser = new ExpressionParser( - this.customizedEvaluatorLookup(templates.expressionParser.EvaluatorLookup) + this.customizedEvaluatorLookup(templates.expressionParser.EvaluatorLookup), ); } @@ -145,7 +144,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe `${TemplateErrors.loopDetected} ${this.evaluationTargetStack .reverse() .map((u: EvaluationTarget): string => u.templateName) - .join(' => ')}` + .join(' => ')}`, ); } @@ -184,7 +183,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe if (this.evaluationTargetStack.length !== 0) { this.evaluationTargetStack[this.evaluationTargetStack.length - 1].cachedEvaluatedChildren.set( currentEvulateId, - result + result, ); } } @@ -216,7 +215,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe const propertyObject = this.evalExpression( body.expressionInStructure().text, body.expressionInStructure(), - body.text + body.text, ); // Full reference to another structured template is limited to the structured template with same type if ( @@ -247,7 +246,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe for (const item of values) { if (TemplateExtensions.isPureExpression(item)) { result.push( - this.evalExpression(item.expressionInStructure(0).text, item.expressionInStructure(0), ctx.text) + this.evalExpression(item.expressionInStructure(0).text, item.expressionInStructure(0), ctx.text), ); } else { let itemStringResult = ''; @@ -412,7 +411,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe switchExprs[0].text, switchExprs[0], switchcaseNodes[0].switchCaseStat().text, - switchErrorPrefix + switchErrorPrefix, ); let idx = 0; for (const caseNode of switchcaseNodes) { @@ -435,7 +434,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe caseExprs[0].text, caseExprs[0], caseNode.switchCaseStat().text, - caseErrorPrefix + caseErrorPrefix, ); if (FunctionUtils.commonEquals(switchExprResult, caseExprResult)) { return this.visit(caseNode.normalTemplateBody()); @@ -460,7 +459,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe .reverse() .join('') .replace(regex, (sub: string) => - this.evalExpression(sub.split('').reverse().join('')).toString().split('').reverse().join('') + this.evalExpression(sub.split('').reverse().join('')).toString().split('').reverse().join(''), ) .split('') .reverse() @@ -511,7 +510,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe result: unknown, templateName: string, inlineContent = '', - errorPrefix = '' + errorPrefix = '', ): void { let errorMsg = ''; @@ -525,7 +524,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe if (inlineContent && inlineContent.trim() !== '') { errorMsg = Evaluator.concatErrorMsg( errorMsg, - TemplateErrors.errorExpression(inlineContent, templateName, errorPrefix) + TemplateErrors.errorExpression(inlineContent, templateName, errorPrefix), ); } @@ -565,7 +564,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe private evalExpressionInCondition( expressionContext: ParserRuleContext, contentLine: string, - errorPrefix = '' + errorPrefix = '', ): boolean { const exp = TemplateExtensions.trimExpression(expressionContext.text); const { value: result, error: error } = this.evalByAdaptiveExpression(exp, this.currentTarget().scope); @@ -592,7 +591,7 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe exp: string, expressionContext?: ParserRuleContext, inlineContent = '', - errorPrefix = '' + errorPrefix = '', ): unknown { exp = TemplateExtensions.trimExpression(exp); const { value: result, error: error } = this.evalByAdaptiveExpression(exp, this.currentTarget().scope); @@ -623,117 +622,146 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe } // Genearte a new lookup function based on one lookup function - private readonly customizedEvaluatorLookup = (baseLookup: EvaluatorLookup) => ( - name: string - ): ExpressionEvaluator => { - const standardFunction = baseLookup(name); + private readonly customizedEvaluatorLookup = + (baseLookup: EvaluatorLookup) => + (name: string): ExpressionEvaluator => { + const standardFunction = baseLookup(name); - if (standardFunction !== undefined) { - return standardFunction; - } + if (standardFunction !== undefined) { + return standardFunction; + } + + const pointIndex = name.indexOf('.'); + if (pointIndex > 0) { + const alias = name.substr(0, pointIndex); + const realTemplate = this.templates.namedReferences[alias]; + if (realTemplate) { + const realTemplateName = name.substr(pointIndex + 1); + return new ExpressionEvaluator( + realTemplateName, + FunctionUtils.apply(this.evaluateWithTemplates(realTemplateName, realTemplate)), + ReturnType.Object, + ); + } + } - const pointIndex = name.indexOf('.'); - if (pointIndex > 0) { - const alias = name.substr(0, pointIndex); - const realTemplate = this.templates.namedReferences[alias]; - if (realTemplate) { - const realTemplateName = name.substr(pointIndex + 1); + if (name.startsWith('lg.')) { + name = name.substring(3); + } + + const templateName = this.parseTemplateName(name).pureTemplateName; + if (templateName in this.templateMap) { return new ExpressionEvaluator( - realTemplateName, - FunctionUtils.apply(this.evaluateWithTemplates(realTemplateName, realTemplate)), - ReturnType.Object + templateName, + FunctionUtils.apply(this.templateEvaluator(name)), + ReturnType.Object, + this.validTemplateReference, ); } - } - if (name.startsWith('lg.')) { - name = name.substring(3); - } - - const templateName = this.parseTemplateName(name).pureTemplateName; - if (templateName in this.templateMap) { - return new ExpressionEvaluator( - templateName, - FunctionUtils.apply(this.templateEvaluator(name)), - ReturnType.Object, - this.validTemplateReference - ); - } + if (name === Evaluator.templateFunctionName) { + return new ExpressionEvaluator( + Evaluator.templateFunctionName, + FunctionUtils.apply(this.templateFunction()), + ReturnType.Object, + this.validateTemplateFunction, + ); + } - if (name === Evaluator.templateFunctionName) { - return new ExpressionEvaluator( - Evaluator.templateFunctionName, - FunctionUtils.apply(this.templateFunction()), - ReturnType.Object, - this.validateTemplateFunction - ); - } + if (Templates.enableFromFile) { + if (name === Evaluator.fromFileFunctionName) { + return new ExpressionEvaluator( + Evaluator.fromFileFunctionName, + FunctionUtils.apply(this.fromFile()), + ReturnType.Object, + (expr): void => FunctionUtils.validateOrder(expr, [ReturnType.String], ReturnType.String), + ); + } + } - if (Templates.enableFromFile) { - if (name === Evaluator.fromFileFunctionName) { + if (name === Evaluator.activityAttachmentFunctionName) { return new ExpressionEvaluator( - Evaluator.fromFileFunctionName, - FunctionUtils.apply(this.fromFile()), + Evaluator.activityAttachmentFunctionName, + FunctionUtils.apply(this.activityAttachment()), ReturnType.Object, - (expr): void => FunctionUtils.validateOrder(expr, [ReturnType.String], ReturnType.String) + (expr): void => FunctionUtils.validateOrder(expr, undefined, ReturnType.Object, ReturnType.String), ); } - } - if (name === Evaluator.activityAttachmentFunctionName) { - return new ExpressionEvaluator( - Evaluator.activityAttachmentFunctionName, - FunctionUtils.apply(this.activityAttachment()), - ReturnType.Object, - (expr): void => FunctionUtils.validateOrder(expr, undefined, ReturnType.Object, ReturnType.String) - ); - } + if (name === Evaluator.isTemplateFunctionName) { + return new ExpressionEvaluator( + Evaluator.isTemplateFunctionName, + FunctionUtils.apply(this.isTemplate()), + ReturnType.Boolean, + FunctionUtils.validateUnaryString, + ); + } - if (name === Evaluator.isTemplateFunctionName) { - return new ExpressionEvaluator( - Evaluator.isTemplateFunctionName, - FunctionUtils.apply(this.isTemplate()), - ReturnType.Boolean, - FunctionUtils.validateUnaryString - ); - } + if (name === Evaluator.expandTextFunctionName) { + return new ExpressionEvaluator( + Evaluator.expandTextFunctionName, + FunctionUtils.apply(this.expandText()), + ReturnType.Object, + FunctionUtils.validateUnaryString, + ); + } - if (name === Evaluator.expandTextFunctionName) { - return new ExpressionEvaluator( - Evaluator.expandTextFunctionName, - FunctionUtils.apply(this.expandText()), - ReturnType.Object, - FunctionUtils.validateUnaryString - ); - } + return undefined; + }; - return undefined; - }; + private readonly isTemplate = + () => + (args: readonly unknown[]): boolean => { + const templateName = args[0].toString(); + return templateName in this.templateMap; + }; - private readonly isTemplate = () => (args: readonly unknown[]): boolean => { - const templateName = args[0].toString(); - return templateName in this.templateMap; - }; + private readonly fromFile = + () => + (args: readonly unknown[]): unknown => { + const filePath: string = TemplateExtensions.normalizePath(args[0].toString()); + const resourcePath: string = this.getResourcePath(filePath); + let format = FileFormat.Evaluated; + if (args.length > 1) { + const expected = args[1].toString().toLowerCase(); + const currentFormat = Object.values(FileFormat).find((f) => f.toLowerCase() === expected); + if (currentFormat != null) { + format = currentFormat; + } + } - private readonly fromFile = () => (args: readonly unknown[]): unknown => { - const filePath: string = TemplateExtensions.normalizePath(args[0].toString()); - const resourcePath: string = this.getResourcePath(filePath); - let format = FileFormat.Evaluated; - if (args.length > 1) { - const expected = args[1].toString().toLowerCase(); - const currentFormat = Object.values(FileFormat).find((f) => f.toLowerCase() === expected); - if (currentFormat != null) { - format = currentFormat; + let result: unknown; + if (format === FileFormat.Binary) { + result = fs.readFileSync(resourcePath); + } else if (format === FileFormat.Raw) { + result = fs.readFileSync(resourcePath, 'utf-8'); + } else { + const stringContent = fs.readFileSync(resourcePath, 'utf-8'); + + const newScope = this.evaluationTargetStack.length > 0 ? this.currentTarget().scope : undefined; + const newTemplates = new Templates( + this.templates.allTemplates, + undefined, + undefined, + undefined, + undefined, + undefined, + this.expressionParser, + undefined, + [], + undefined, + this.templates.namedReferences, + ); + result = newTemplates.evaluateText(stringContent, newScope, this.lgOptions); } - } - let result: unknown; - if (format === FileFormat.Binary) { - result = fs.readFileSync(resourcePath); - } else if (format === FileFormat.Raw) { - result = fs.readFileSync(resourcePath, 'utf-8'); - } else { - const stringContent = fs.readFileSync(resourcePath, 'utf-8'); + return result; + }; + + private readonly expandText = + () => + (args: readonly unknown[]): unknown => { + const stringContent = args[0].toString(); const newScope = this.evaluationTargetStack.length > 0 ? this.currentTarget().scope : undefined; const newTemplates = new Templates( @@ -747,33 +775,10 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe undefined, [], undefined, - this.templates.namedReferences + this.templates.namedReferences, ); - result = newTemplates.evaluateText(stringContent, newScope, this.lgOptions); - } - - return result; - }; - - private readonly expandText = () => (args: readonly unknown[]): unknown => { - const stringContent = args[0].toString(); - - const newScope = this.evaluationTargetStack.length > 0 ? this.currentTarget().scope : undefined; - const newTemplates = new Templates( - this.templates.allTemplates, - undefined, - undefined, - undefined, - undefined, - undefined, - this.expressionParser, - undefined, - [], - undefined, - this.templates.namedReferences - ); - return newTemplates.evaluateText(stringContent, newScope, this.lgOptions); - }; + return newTemplates.evaluateText(stringContent, newScope, this.lgOptions); + }; /** * @private @@ -801,28 +806,32 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe return resourcePath; } - private readonly activityAttachment = () => (args: readonly unknown[]): unknown => { - return { - [Evaluator.LGType]: 'attachment', - contenttype: args[1].toString(), - content: args[0], + private readonly activityAttachment = + () => + (args: readonly unknown[]): unknown => { + return { + [Evaluator.LGType]: 'attachment', + contenttype: args[1].toString(), + content: args[0], + }; }; - }; - private readonly evaluateWithTemplates = (templateName: string, templates: Templates) => ( - args: readonly unknown[] - ): unknown => { - const newScope = this.constructScope(templateName, args.slice(0), templates.allTemplates); + private readonly evaluateWithTemplates = + (templateName: string, templates: Templates) => + (args: readonly unknown[]): unknown => { + const newScope = this.constructScope(templateName, args.slice(0), templates.allTemplates); - return templates.evaluate(templateName, newScope); - }; + return templates.evaluate(templateName, newScope); + }; - private readonly templateFunction = () => (args: readonly unknown[]): unknown => { - const templateName: string = args[0].toString(); - const newScope = this.constructScope(templateName, args.slice(1), this.templates.allTemplates); + private readonly templateFunction = + () => + (args: readonly unknown[]): unknown => { + const templateName: string = args[0].toString(); + const newScope = this.constructScope(templateName, args.slice(1), this.templates.allTemplates); - return this.evaluateTemplate(templateName, newScope); - }; + return this.evaluateTemplate(templateName, newScope); + }; private readonly validateTemplateFunction = (expression: Expression): void => { FunctionUtils.validateAtLeastOne(expression); @@ -857,11 +866,13 @@ export class Evaluator extends AbstractParseTreeVisitor implements LGTe } } - private readonly templateEvaluator = (templateName: string) => (args: readonly unknown[]): unknown => { - const newScope = this.constructScope(templateName, Array.from(args), this.templates.allTemplates); + private readonly templateEvaluator = + (templateName: string) => + (args: readonly unknown[]): unknown => { + const newScope = this.constructScope(templateName, Array.from(args), this.templates.allTemplates); - return this.evaluateTemplate(templateName, newScope); - }; + return this.evaluateTemplate(templateName, newScope); + }; private readonly validTemplateReference = (expression: Expression): void => { return this.checkTemplateReference(expression.type, expression.children); diff --git a/libraries/botbuilder-lg/src/expander.ts b/libraries/botbuilder-lg/src/expander.ts index 273f22b689..e235ea3056 100644 --- a/libraries/botbuilder-lg/src/expander.ts +++ b/libraries/botbuilder-lg/src/expander.ts @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-object-injection */ /* eslint-disable security/detect-non-literal-fs-filename */ /** * @module botbuilder-lg @@ -20,7 +19,7 @@ import { Template } from './template'; import { TemplateErrors } from './templateErrors'; import { TemplateExtensions } from './templateExtensions'; import { Templates } from './templates'; -import keyBy = require('lodash/keyBy'); +import keyBy from 'lodash/keyBy'; import { Constant, @@ -96,10 +95,10 @@ export class Expander extends AbstractParseTreeVisitor implements LGT // Generate a new customized expression parser by injecting the template as functions. this.expanderExpressionParser = new ExpressionParser( - this.customizedEvaluatorLookup(templates.expressionParser.EvaluatorLookup, true) + this.customizedEvaluatorLookup(templates.expressionParser.EvaluatorLookup, true), ); this.evaluatorExpressionParser = new ExpressionParser( - this.customizedEvaluatorLookup(templates.expressionParser.EvaluatorLookup, false) + this.customizedEvaluatorLookup(templates.expressionParser.EvaluatorLookup, false), ); } @@ -124,7 +123,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT `${TemplateErrors.loopDetected} ${this.evaluationTargetStack .reverse() .map((u: EvaluationTarget): string => u.templateName) - .join(' => ')}` + .join(' => ')}`, ); } @@ -229,7 +228,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT if (x !== undefined && x !== null) { propertyObjects.push(x); } - } + }, ); const tempResult = []; for (const res of expandedResult) { @@ -284,7 +283,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT for (const item of values) { if (TemplateExtensions.isPureExpression(item)) { result.push( - this.evalExpression(item.expressionInStructure(0).text, item.expressionInStructure(0), ctx.text) + this.evalExpression(item.expressionInStructure(0).text, item.expressionInStructure(0), ctx.text), ); } else { let itemStringResult: unknown[] = ['']; @@ -293,7 +292,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT const errorPrefix = `Property '${ctx.STRUCTURE_IDENTIFIER().text}':`; itemStringResult = this.stringArrayConcat( itemStringResult, - this.evalExpression(child.text, child, ctx.text, errorPrefix) + this.evalExpression(child.text, child, ctx.text, errorPrefix), ); } else { const node = child as TerminalNode; @@ -333,7 +332,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT switchExprs[0].text, switchExprs[0], switchcaseNodes[0].switchCaseStat().text, - switchErrorPrefix + switchErrorPrefix, ); let idx = 0; for (const caseNode of switchcaseNodes) { @@ -357,7 +356,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT caseExprs[0].text, caseExprs[0], caseNode.switchCaseStat().text, - caseErrorPrefix + caseErrorPrefix, ); if (FunctionUtils.commonEquals(switchExprResult[0], caseExprResult[0])) { return this.visit(caseNode.normalTemplateBody()); @@ -382,7 +381,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT if (child instanceof ExpressionContext) { result = this.stringArrayConcat( result, - this.evalExpression(child.text, child, ctx.text, prefixErrorMsg) + this.evalExpression(child.text, child, ctx.text, prefixErrorMsg), ); } else { const node = child as TerminalNode; @@ -478,7 +477,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT private evalExpressionInCondition( expressionContext: ParserRuleContext, contentLine: string, - errorPrefix = '' + errorPrefix = '', ): boolean { const exp = TemplateExtensions.trimExpression(expressionContext.text); const { value: result, error: error } = this.evalByAdaptiveExpression(exp, this.currentTarget().scope); @@ -566,124 +565,128 @@ export class Expander extends AbstractParseTreeVisitor implements LGT return str1.toString() + str2.toString(); } - private readonly customizedEvaluatorLookup = (baseLookup: EvaluatorLookup, isExpander: boolean) => ( - name: string - ): ExpressionEvaluator => { - const standardFunction = baseLookup(name); + private readonly customizedEvaluatorLookup = + (baseLookup: EvaluatorLookup, isExpander: boolean) => + (name: string): ExpressionEvaluator => { + const standardFunction = baseLookup(name); - if (standardFunction !== undefined) { - return standardFunction; - } + if (standardFunction !== undefined) { + return standardFunction; + } - const pointIndex = name.indexOf('.'); - if (pointIndex > 0) { - const alias = name.substr(0, pointIndex); - const realTemplate = this.templates.namedReferences[alias]; - if (realTemplate) { - const realTemplateName = name.substr(pointIndex + 1); - return new ExpressionEvaluator( - realTemplateName, - FunctionUtils.apply(this.evaluateWithTemplates(realTemplateName, realTemplate)), - ReturnType.Object - ); + const pointIndex = name.indexOf('.'); + if (pointIndex > 0) { + const alias = name.substr(0, pointIndex); + const realTemplate = this.templates.namedReferences[alias]; + if (realTemplate) { + const realTemplateName = name.substr(pointIndex + 1); + return new ExpressionEvaluator( + realTemplateName, + FunctionUtils.apply(this.evaluateWithTemplates(realTemplateName, realTemplate)), + ReturnType.Object, + ); + } } - } - if (name.startsWith('lg.')) { - name = name.substring(3); - } + if (name.startsWith('lg.')) { + name = name.substring(3); + } - const templateName = this.parseTemplateName(name).pureTemplateName; - if (templateName in this.templateMap) { - if (isExpander) { + const templateName = this.parseTemplateName(name).pureTemplateName; + if (templateName in this.templateMap) { + if (isExpander) { + return new ExpressionEvaluator( + templateName, + FunctionUtils.apply(this.templateExpander(name)), + ReturnType.Object, + this.validTemplateReference, + ); + } else { + return new ExpressionEvaluator( + templateName, + FunctionUtils.apply(this.templateEvaluator(name)), + ReturnType.Object, + this.validTemplateReference, + ); + } + } + + if (name === Evaluator.templateFunctionName) { return new ExpressionEvaluator( - templateName, - FunctionUtils.apply(this.templateExpander(name)), + Evaluator.templateFunctionName, + FunctionUtils.apply(this.templateFunction()), ReturnType.Object, - this.validTemplateReference + this.validateTemplateFunction, ); - } else { + } + + if (Templates.enableFromFile) { + if (name === Evaluator.fromFileFunctionName) { + return new ExpressionEvaluator( + Evaluator.fromFileFunctionName, + FunctionUtils.apply(this.fromFile()), + ReturnType.Object, + (expr): void => FunctionUtils.validateOrder(expr, [ReturnType.String], ReturnType.String), + ); + } + } + + if (name === Evaluator.activityAttachmentFunctionName) { return new ExpressionEvaluator( - templateName, - FunctionUtils.apply(this.templateEvaluator(name)), + Evaluator.activityAttachmentFunctionName, + FunctionUtils.apply(this.activityAttachment()), ReturnType.Object, - this.validTemplateReference + (expr): void => FunctionUtils.validateOrder(expr, undefined, ReturnType.Object, ReturnType.String), ); } - } - if (name === Evaluator.templateFunctionName) { - return new ExpressionEvaluator( - Evaluator.templateFunctionName, - FunctionUtils.apply(this.templateFunction()), - ReturnType.Object, - this.validateTemplateFunction - ); - } + if (name === Evaluator.isTemplateFunctionName) { + return new ExpressionEvaluator( + Evaluator.isTemplateFunctionName, + FunctionUtils.apply(this.isTemplate()), + ReturnType.Boolean, + FunctionUtils.validateUnaryString, + ); + } - if (Templates.enableFromFile) { - if (name === Evaluator.fromFileFunctionName) { + if (name === Evaluator.expandTextFunctionName) { return new ExpressionEvaluator( - Evaluator.fromFileFunctionName, - FunctionUtils.apply(this.fromFile()), + Evaluator.expandTextFunctionName, + FunctionUtils.apply(this.expandText()), ReturnType.Object, - (expr): void => FunctionUtils.validateOrder(expr, [ReturnType.String], ReturnType.String) + FunctionUtils.validateUnaryString, ); } - } - - if (name === Evaluator.activityAttachmentFunctionName) { - return new ExpressionEvaluator( - Evaluator.activityAttachmentFunctionName, - FunctionUtils.apply(this.activityAttachment()), - ReturnType.Object, - (expr): void => FunctionUtils.validateOrder(expr, undefined, ReturnType.Object, ReturnType.String) - ); - } - - if (name === Evaluator.isTemplateFunctionName) { - return new ExpressionEvaluator( - Evaluator.isTemplateFunctionName, - FunctionUtils.apply(this.isTemplate()), - ReturnType.Boolean, - FunctionUtils.validateUnaryString - ); - } - - if (name === Evaluator.expandTextFunctionName) { - return new ExpressionEvaluator( - Evaluator.expandTextFunctionName, - FunctionUtils.apply(this.expandText()), - ReturnType.Object, - FunctionUtils.validateUnaryString - ); - } - return undefined; - }; + return undefined; + }; - private readonly evaluateWithTemplates = (templateName: string, templates: Templates) => ( - args: readonly unknown[] - ): unknown => { - const newScope = this.constructScope(templateName, args.slice(0), templates.allTemplates); + private readonly evaluateWithTemplates = + (templateName: string, templates: Templates) => + (args: readonly unknown[]): unknown => { + const newScope = this.constructScope(templateName, args.slice(0), templates.allTemplates); - return templates.evaluate(templateName, newScope); - }; + return templates.evaluate(templateName, newScope); + }; - private readonly templateEvaluator = (templateName: string) => (args: readonly unknown[]): unknown => { - const newScope = this.constructScope(templateName, Array.from(args), this.templates.allTemplates); + private readonly templateEvaluator = + (templateName: string) => + (args: readonly unknown[]): unknown => { + const newScope = this.constructScope(templateName, Array.from(args), this.templates.allTemplates); - const value = this.expandTemplate(templateName, newScope); - const randomNumber = Extensions.randomNext(this.currentTarget().scope, 0, value.length); + const value = this.expandTemplate(templateName, newScope); + const randomNumber = Extensions.randomNext(this.currentTarget().scope, 0, value.length); - return value[randomNumber]; - }; + return value[randomNumber]; + }; - private readonly templateExpander = (templateName: string) => (args: readonly unknown[]): unknown[] => { - const newScope = this.constructScope(templateName, Array.from(args), this.templates.allTemplates); + private readonly templateExpander = + (templateName: string) => + (args: readonly unknown[]): unknown[] => { + const newScope = this.constructScope(templateName, Array.from(args), this.templates.allTemplates); - return this.expandTemplate(templateName, newScope); - }; + return this.expandTemplate(templateName, newScope); + }; /** * @private @@ -691,7 +694,7 @@ export class Expander extends AbstractParseTreeVisitor implements LGT private reconstructExpression( expanderExpression: Expression, evaluatorExpression: Expression, - foundPrebuiltFunction: boolean + foundPrebuiltFunction: boolean, ): Expression { if (this.templateMap[expanderExpression.type]) { if (foundPrebuiltFunction) { @@ -705,37 +708,66 @@ export class Expander extends AbstractParseTreeVisitor implements LGT expanderExpression.children[i] = this.reconstructExpression( expanderExpression.children[i], evaluatorExpression.children[i], - foundPrebuiltFunction + foundPrebuiltFunction, ); } return expanderExpression; } - private readonly isTemplate = () => (args: readonly unknown[]): boolean => { - const templateName = args[0].toString(); - return templateName in this.templateMap; - }; + private readonly isTemplate = + () => + (args: readonly unknown[]): boolean => { + const templateName = args[0].toString(); + return templateName in this.templateMap; + }; - private readonly fromFile = () => (args: readonly unknown[]): unknown => { - const filePath: string = TemplateExtensions.normalizePath(args[0].toString()); - const resourcePath: string = this.getResourcePath(filePath); - let format = FileFormat.Evaluated; - if (args.length > 1) { - const expected = args[1].toString().toLowerCase(); - const currentFormat = Object.values(FileFormat).find((f) => f.toLowerCase() === expected); - if (currentFormat != null) { - format = currentFormat; + private readonly fromFile = + () => + (args: readonly unknown[]): unknown => { + const filePath: string = TemplateExtensions.normalizePath(args[0].toString()); + const resourcePath: string = this.getResourcePath(filePath); + let format = FileFormat.Evaluated; + if (args.length > 1) { + const expected = args[1].toString().toLowerCase(); + const currentFormat = Object.values(FileFormat).find((f) => f.toLowerCase() === expected); + if (currentFormat != null) { + format = currentFormat; + } } - } - let result: unknown; - if (format === FileFormat.Binary) { - result = fs.readFileSync(resourcePath); - } else if (format === FileFormat.Raw) { - result = fs.readFileSync(resourcePath, 'utf-8'); - } else { - const stringContent = fs.readFileSync(resourcePath, 'utf-8'); + let result: unknown; + if (format === FileFormat.Binary) { + result = fs.readFileSync(resourcePath); + } else if (format === FileFormat.Raw) { + result = fs.readFileSync(resourcePath, 'utf-8'); + } else { + const stringContent = fs.readFileSync(resourcePath, 'utf-8'); + + const newScope = this.evaluationTargetStack.length > 0 ? this.currentTarget().scope : undefined; + const newTemplates = new Templates( + this.templates.allTemplates, + undefined, + undefined, + undefined, + undefined, + undefined, + this.templates.expressionParser, + undefined, + [], + undefined, + this.templates.namedReferences, + ); + result = newTemplates.evaluateText(stringContent, newScope, this.lgOptions); + } + + return result; + }; + + private readonly expandText = + () => + (args: readonly unknown[]): unknown => { + const stringContent = args[0].toString(); const newScope = this.evaluationTargetStack.length > 0 ? this.currentTarget().scope : undefined; const newTemplates = new Templates( @@ -749,33 +781,10 @@ export class Expander extends AbstractParseTreeVisitor implements LGT undefined, [], undefined, - this.templates.namedReferences + this.templates.namedReferences, ); - result = newTemplates.evaluateText(stringContent, newScope, this.lgOptions); - } - - return result; - }; - - private readonly expandText = () => (args: readonly unknown[]): unknown => { - const stringContent = args[0].toString(); - - const newScope = this.evaluationTargetStack.length > 0 ? this.currentTarget().scope : undefined; - const newTemplates = new Templates( - this.templates.allTemplates, - undefined, - undefined, - undefined, - undefined, - undefined, - this.templates.expressionParser, - undefined, - [], - undefined, - this.templates.namedReferences - ); - return newTemplates.evaluateText(stringContent, newScope, this.lgOptions); - }; + return newTemplates.evaluateText(stringContent, newScope, this.lgOptions); + }; /** * @private @@ -803,21 +812,25 @@ export class Expander extends AbstractParseTreeVisitor implements LGT return resourcePath; } - private readonly activityAttachment = () => (args: readonly unknown[]): Record => { - return { - [Evaluator.LGType]: 'attachment', - contenttype: args[1].toString(), - content: args[0], + private readonly activityAttachment = + () => + (args: readonly unknown[]): Record => { + return { + [Evaluator.LGType]: 'attachment', + contenttype: args[1].toString(), + content: args[0], + }; }; - }; - private readonly templateFunction = () => (args: readonly unknown[]): unknown[] => { - const templateName: string = args[0].toString(); - const newScope = this.constructScope(templateName, args.slice(1), this.templates.allTemplates); - const value = this.expandTemplate(templateName, newScope); + private readonly templateFunction = + () => + (args: readonly unknown[]): unknown[] => { + const templateName: string = args[0].toString(); + const newScope = this.constructScope(templateName, args.slice(1), this.templates.allTemplates); + const value = this.expandTemplate(templateName, newScope); - return value; - }; + return value; + }; private readonly validateTemplateFunction = (expression: Expression): void => { FunctionUtils.validateAtLeastOne(expression); diff --git a/libraries/botbuilder-lg/src/extractor.ts b/libraries/botbuilder-lg/src/extractor.ts index 22543f43d0..3df5a8d2db 100644 --- a/libraries/botbuilder-lg/src/extractor.ts +++ b/libraries/botbuilder-lg/src/extractor.ts @@ -6,7 +6,7 @@ * Licensed under the MIT License. */ import { AbstractParseTreeVisitor, TerminalNode } from 'antlr4ts/tree'; -import keyBy = require('lodash/keyBy'); +import keyBy from 'lodash/keyBy'; import { LGTemplateParserVisitor } from './generated/LGTemplateParserVisitor'; import { Template } from './template'; @@ -26,7 +26,8 @@ import { */ export class Extractor extends AbstractParseTreeVisitor> - implements LGTemplateParserVisitor> { + implements LGTemplateParserVisitor> +{ readonly templates: Template[]; readonly templateMap: Record; @@ -55,7 +56,7 @@ export class Extractor const templateBodies = this.visit(template.templateBodyParseTree); let isNormalTemplate = true; templateBodies.forEach( - (templateBody) => (isNormalTemplate = isNormalTemplate && templateBody === undefined) + (templateBody) => (isNormalTemplate = isNormalTemplate && templateBody === undefined), ); if (isNormalTemplate) { @@ -128,8 +129,8 @@ export class Extractor const node: TerminalNode = ifExpr ? conditionNode.IF() : elseIfExpr - ? conditionNode.ELSEIF() - : conditionNode.ELSE(); + ? conditionNode.ELSEIF() + : conditionNode.ELSE(); const conditionLabel: string = node.text.toLowerCase(); const childTemplateBodyResult: string[] = []; const templateBodies = this.visit(ifRule.normalTemplateBody()); @@ -167,8 +168,8 @@ export class Extractor const node: TerminalNode = switchExpr ? switchCaseStat.SWITCH() : caseExpr - ? switchCaseStat.CASE() - : switchCaseStat.DEFAULT(); + ? switchCaseStat.CASE() + : switchCaseStat.DEFAULT(); if (switchExpr) { continue; } diff --git a/libraries/botbuilder-lg/src/index.ts b/libraries/botbuilder-lg/src/index.ts index 0c10a62236..a7b32eb138 100644 --- a/libraries/botbuilder-lg/src/index.ts +++ b/libraries/botbuilder-lg/src/index.ts @@ -22,7 +22,6 @@ export * from './evaluationTarget'; export * from './templateExtensions'; export * from './analyzerResult'; export * from './templateErrors'; -export * from './evaluator'; export * from './errorListener'; export * from './customizedMemory'; export * from './expander'; diff --git a/libraries/botbuilder-lg/src/multiLanguageLG.ts b/libraries/botbuilder-lg/src/multiLanguageLG.ts index c29562a06d..42789c1b11 100644 --- a/libraries/botbuilder-lg/src/multiLanguageLG.ts +++ b/libraries/botbuilder-lg/src/multiLanguageLG.ts @@ -877,7 +877,7 @@ export class MultiLanguageLG { constructor( templatesPerLocale: Map | undefined, filePerLocale: Map | undefined, - defaultLanguage?: string + defaultLanguage?: string, ) { if (templatesPerLocale !== undefined) { this.lgPerLocale = templatesPerLocale; diff --git a/libraries/botbuilder-lg/src/staticChecker.ts b/libraries/botbuilder-lg/src/staticChecker.ts index fe7cc100ba..21d930d494 100644 --- a/libraries/botbuilder-lg/src/staticChecker.ts +++ b/libraries/botbuilder-lg/src/staticChecker.ts @@ -35,7 +35,8 @@ import { */ export class StaticChecker extends AbstractParseTreeVisitor - implements LGTemplateParserVisitor { + implements LGTemplateParserVisitor +{ private readonly templates: Templates; private currentTemplate: Template; private _expressionParser: ExpressionParserInterface; @@ -77,7 +78,7 @@ export class StaticChecker Range.DefaultRange, TemplateErrors.noTemplate, DiagnosticSeverity.Warning, - this.templates.source + this.templates.source, ); result.push(diagnostic); return result; @@ -96,10 +97,10 @@ export class StaticChecker range, TemplateErrors.duplicatedTemplateInDiffTemplate( sameTemplate.name, - sameTemplate.sourceRange.source + sameTemplate.sourceRange.source, ), DiagnosticSeverity.Error, - this.templates.source + this.templates.source, ); templateDiagnostics.push(diagnostic); } @@ -151,8 +152,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.invalidStrucName(errorName.text), undefined, - context.structuredBodyNameLine() - ) + context.structuredBodyNameLine(), + ), ); } @@ -209,12 +210,12 @@ export class StaticChecker const node: TerminalNode = ifExpr ? conditionNode.IF() : elseIfExpr - ? conditionNode.ELSEIF() - : conditionNode.ELSE(); + ? conditionNode.ELSEIF() + : conditionNode.ELSE(); if (node.text.split(' ').length - 1 > 1) { result.push( - this.buildLGDiagnostic(TemplateErrors.invalidWhitespaceInCondition, undefined, conditionNode) + this.buildLGDiagnostic(TemplateErrors.invalidWhitespaceInCondition, undefined, conditionNode), ); } @@ -223,8 +224,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.notStartWithIfInCondition, DiagnosticSeverity.Warning, - conditionNode - ) + conditionNode, + ), ); } @@ -237,8 +238,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.notEndWithElseInCondition, DiagnosticSeverity.Warning, - conditionNode - ) + conditionNode, + ), ); } @@ -249,7 +250,7 @@ export class StaticChecker if (!elseExpr) { if (ifRule.ifCondition().expression().length !== 1) { result.push( - this.buildLGDiagnostic(TemplateErrors.invalidExpressionInCondition, undefined, conditionNode) + this.buildLGDiagnostic(TemplateErrors.invalidExpressionInCondition, undefined, conditionNode), ); } else { const errorPrefix = "Condition '" + conditionNode.expression(0).text + "': "; @@ -258,7 +259,7 @@ export class StaticChecker } else { if (ifRule.ifCondition().expression().length !== 0) { result.push( - this.buildLGDiagnostic(TemplateErrors.extraExpressionInCondition, undefined, conditionNode) + this.buildLGDiagnostic(TemplateErrors.extraExpressionInCondition, undefined, conditionNode), ); } } @@ -266,7 +267,7 @@ export class StaticChecker result = result.concat(this.visit(ifRule.normalTemplateBody())); } else { result.push( - this.buildLGDiagnostic(TemplateErrors.missingTemplateBodyInCondition, undefined, conditionNode) + this.buildLGDiagnostic(TemplateErrors.missingTemplateBodyInCondition, undefined, conditionNode), ); } @@ -296,23 +297,27 @@ export class StaticChecker const node: TerminalNode = switchExpr ? switchCaseStat.SWITCH() : caseExpr - ? switchCaseStat.CASE() - : switchCaseStat.DEFAULT(); + ? switchCaseStat.CASE() + : switchCaseStat.DEFAULT(); if (node.text.split(' ').length - 1 > 1) { result.push( - this.buildLGDiagnostic(TemplateErrors.invalidWhitespaceInSwitchCase, undefined, switchCaseStat) + this.buildLGDiagnostic(TemplateErrors.invalidWhitespaceInSwitchCase, undefined, switchCaseStat), ); } if (idx === 0 && !switchExpr) { result.push( - this.buildLGDiagnostic(TemplateErrors.notStartWithSwitchInSwitchCase, undefined, switchCaseStat) + this.buildLGDiagnostic(TemplateErrors.notStartWithSwitchInSwitchCase, undefined, switchCaseStat), ); } if (idx > 0 && switchExpr) { result.push( - this.buildLGDiagnostic(TemplateErrors.multipleSwithStatementInSwitchCase, undefined, switchCaseStat) + this.buildLGDiagnostic( + TemplateErrors.multipleSwithStatementInSwitchCase, + undefined, + switchCaseStat, + ), ); } @@ -321,8 +326,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.invalidStatementInMiddlerOfSwitchCase, undefined, - switchCaseStat - ) + switchCaseStat, + ), ); } @@ -332,8 +337,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.notEndWithDefaultInSwitchCase, DiagnosticSeverity.Warning, - switchCaseStat - ) + switchCaseStat, + ), ); } else { if (length === 2) { @@ -341,8 +346,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.missingCaseInSwitchCase, DiagnosticSeverity.Warning, - switchCaseStat - ) + switchCaseStat, + ), ); } } @@ -350,7 +355,7 @@ export class StaticChecker if (switchExpr || caseExpr) { if (switchCaseStat.expression().length !== 1) { result.push( - this.buildLGDiagnostic(TemplateErrors.invalidExpressionInSwiathCase, undefined, switchCaseStat) + this.buildLGDiagnostic(TemplateErrors.invalidExpressionInSwiathCase, undefined, switchCaseStat), ); } else { let errorPrefix = switchExpr ? 'Switch' : 'Case'; @@ -360,7 +365,7 @@ export class StaticChecker } else { if (switchCaseStat.expression().length !== 0 || switchCaseStat.TEXT().length !== 0) { result.push( - this.buildLGDiagnostic(TemplateErrors.extraExpressionInSwitchCase, undefined, switchCaseStat) + this.buildLGDiagnostic(TemplateErrors.extraExpressionInSwitchCase, undefined, switchCaseStat), ); } } @@ -372,8 +377,8 @@ export class StaticChecker this.buildLGDiagnostic( TemplateErrors.missingTemplateBodyInSwitchCase, undefined, - switchCaseStat - ) + switchCaseStat, + ), ); } } @@ -446,7 +451,7 @@ export class StaticChecker private buildLGDiagnostic( message: string, severity: DiagnosticSeverity = undefined, - context: ParserRuleContext = undefined + context: ParserRuleContext = undefined, ): Diagnostic { const lineOffset = this.currentTemplate !== undefined ? this.currentTemplate.sourceRange.range.start.line : 0; diff --git a/libraries/botbuilder-lg/src/templateExtensions.ts b/libraries/botbuilder-lg/src/templateExtensions.ts index 0d1c49995b..ac08c37853 100644 --- a/libraries/botbuilder-lg/src/templateExtensions.ts +++ b/libraries/botbuilder-lg/src/templateExtensions.ts @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-object-injection */ /** * @module botbuilder-lg */ @@ -188,7 +187,7 @@ export class TemplateExtensions { const startPosition = new Position(lineOffset + context.start.line, context.start.charPositionInLine); const stopPosition = new Position( lineOffset + context.stop.line, - context.stop.charPositionInLine + context.stop.text.length + context.stop.charPositionInLine + context.stop.text.length, ); return new Range(startPosition, stopPosition); diff --git a/libraries/botbuilder-lg/src/templates.ts b/libraries/botbuilder-lg/src/templates.ts index f4e9c2cd61..289bb0675f 100644 --- a/libraries/botbuilder-lg/src/templates.ts +++ b/libraries/botbuilder-lg/src/templates.ts @@ -1,4 +1,3 @@ -/* eslint-disable security/detect-object-injection */ /** * @module botbuilder-lg */ @@ -20,11 +19,10 @@ import { SimpleObjectMemory, ValueWithError, } from 'adaptive-expressions'; -import { ImportResolverDelegate, TemplatesTransformer } from './templatesParser'; +import { ImportResolverDelegate, TemplatesTransformer, TemplatesParser } from './templatesParser'; import { Evaluator } from './evaluator'; import { Expander } from './expander'; import { Analyzer } from './analyzer'; -import { TemplatesParser } from './templatesParser'; import { AnalyzerResult } from './analyzerResult'; import { TemplateErrors } from './templateErrors'; import { TemplateExtensions } from './templateExtensions'; @@ -133,7 +131,7 @@ export class Templates implements Iterable