From 203c044db65f88f0ae7c28de7b379a7f4d17fa51 Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:38:23 -0300 Subject: [PATCH 01/13] Catch 412 error in blobsStorage write (#4800) --- .../src/blobsStorage.ts | 25 ++++++++++++------- .../tests/blobsStorage.test.js | 15 +++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/libraries/botbuilder-azure-blobs/src/blobsStorage.ts b/libraries/botbuilder-azure-blobs/src/blobsStorage.ts index 4b7d02c061..985cd035c8 100644 --- a/libraries/botbuilder-azure-blobs/src/blobsStorage.ts +++ b/libraries/botbuilder-azure-blobs/src/blobsStorage.ts @@ -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, - } + }, ); } diff --git a/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js b/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js index 350a4c64a8..348a4e7ce4 100644 --- a/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js +++ b/libraries/botbuilder-azure-blobs/tests/blobsStorage.test.js @@ -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 () { From 345fccbddff997fe8687bb343236feb606d0ae63 Mon Sep 17 00:00:00 2001 From: Joel Mut <62260472+sw-joelmut@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:39:46 -0300 Subject: [PATCH 02/13] fix: Upgrade cross-spawn dependency to latest version (#4798) * Fix cross-spawn issue * Fix eslint upgrade issue --- package.json | 4 +- yarn.lock | 309 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 188 insertions(+), 125 deletions(-) diff --git a/package.json b/package.json index ce3dfe13d9..33a5cef8b5 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "depcheck": "^1.4.7", "esbuild-plugin-polyfill-node": "^0.3.0", "https-browserify": "^1.0.0", - "eslint": "^9.12.0", + "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsdoc": "^50.3.1", @@ -106,7 +106,7 @@ "typedoc-plugin-markdown": "^4.2.7", "typedoc": "^0.26.7", "typescript": "~4.7", - "typescript-eslint": "^8.11.0", + "typescript-eslint": "^8.15.0", "webpack-dev-server": "^5.1.0", "wsrun": "^5.2.4" }, diff --git a/yarn.lock b/yarn.lock index be3977e8c6..db4fd32504 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2707,29 +2707,34 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.11.0": +"@eslint-community/regexpp@^4.10.0": version "4.11.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== +"@eslint-community/regexpp@^4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + "@eslint/compat@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@eslint/compat/-/compat-1.2.0.tgz#8d36b8c0e1e9e91068a1df8938977a9e4535d83c" integrity sha512-CkPWddN7J9JPrQedEr2X7AjK9y1jaMJtxZ4A/+jTMFA2+n5BWhcKHW/EbJyARqg2zzQfgtWUtVmG3hrG6+nGpg== -"@eslint/config-array@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d" - integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== +"@eslint/config-array@^0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.0.tgz#3251a528998de914d59bb21ba4c11767cf1b3519" + integrity sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ== dependencies: "@eslint/object-schema" "^2.1.4" debug "^4.3.1" minimatch "^3.1.2" -"@eslint/core@^0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.6.0.tgz#9930b5ba24c406d67a1760e94cdbac616a6eb674" - integrity sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg== +"@eslint/core@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.0.tgz#168ee076f94b152c01ca416c3e5cf82290ab4fcd" + integrity sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg== "@eslint/eslintrc@^3.1.0": version "3.1.0" @@ -2746,20 +2751,35 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.12.0": - version "9.12.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.12.0.tgz#69ca3ca9fab9a808ec6d67b8f6edb156cbac91e1" - integrity sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA== +"@eslint/eslintrc@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" + integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@9.15.0": + version "9.15.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.15.0.tgz#df0e24fe869143b59731942128c19938fdbadfb5" + integrity sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg== "@eslint/object-schema@^2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== -"@eslint/plugin-kit@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz#8712dccae365d24e9eeecb7b346f85e750ba343d" - integrity sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig== +"@eslint/plugin-kit@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz#812980a6a41ecf3a8341719f92a6d1e784a2e0e8" + integrity sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA== dependencies: levn "^0.4.1" @@ -2785,17 +2805,17 @@ resolved "https://registry.yarnpkg.com/@httptoolkit/esm/-/esm-3.3.0.tgz#7eb6f2487c55c25c57b623c81ac64c3ec5097e09" integrity sha512-gS+TH14750cveYP5p2q/oLyjVV5+qRFZMOpsPzK1KrgacqKc6RLDmt3ioGaMjsn1aianQbROkl4QXDJmO5swPA== -"@humanfs/core@^0.19.0": - version "0.19.0" - resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.0.tgz#08db7a8c73bb07673d9ebd925f2dad746411fcec" - integrity sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw== +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== -"@humanfs/node@^0.16.5": - version "0.16.5" - resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.5.tgz#a9febb7e7ad2aff65890fdc630938f8d20aa84ba" - integrity sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg== +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== dependencies: - "@humanfs/core" "^0.19.0" + "@humanfs/core" "^0.19.1" "@humanwhocodes/retry" "^0.3.0" "@humanwhocodes/module-importer@^1.0.1": @@ -2803,11 +2823,16 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/retry@^0.3.0", "@humanwhocodes/retry@^0.3.1": +"@humanwhocodes/retry@^0.3.0": version "0.3.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== +"@humanwhocodes/retry@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -4524,62 +4549,62 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz#c3f087d20715fa94310b30666c08b3349e0ab084" - integrity sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA== +"@typescript-eslint/eslint-plugin@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz#c95c6521e70c8b095a684d884d96c0c1c63747d2" + integrity sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.11.0" - "@typescript-eslint/type-utils" "8.11.0" - "@typescript-eslint/utils" "8.11.0" - "@typescript-eslint/visitor-keys" "8.11.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/type-utils" "8.15.0" + "@typescript-eslint/utils" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.11.0.tgz#2ad1481388dc1c937f50b2d138c9ca57cc6c5cce" - integrity sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg== +"@typescript-eslint/parser@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.15.0.tgz#92610da2b3af702cfbc02a46e2a2daa6260a9045" + integrity sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A== dependencies: - "@typescript-eslint/scope-manager" "8.11.0" - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/typescript-estree" "8.11.0" - "@typescript-eslint/visitor-keys" "8.11.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/typescript-estree" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz#9d399ce624118966732824878bc9a83593a30405" - integrity sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ== +"@typescript-eslint/scope-manager@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz#28a1a0f13038f382424f45a988961acaca38f7c6" + integrity sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA== dependencies: - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/visitor-keys" "8.11.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" -"@typescript-eslint/type-utils@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz#b7f9e6120c1ddee8a1a07615646642ad85fc91b5" - integrity sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg== +"@typescript-eslint/type-utils@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz#a6da0f93aef879a68cc66c73fe42256cb7426c72" + integrity sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw== dependencies: - "@typescript-eslint/typescript-estree" "8.11.0" - "@typescript-eslint/utils" "8.11.0" + "@typescript-eslint/typescript-estree" "8.15.0" + "@typescript-eslint/utils" "8.15.0" debug "^4.3.4" ts-api-utils "^1.3.0" -"@typescript-eslint/types@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.11.0.tgz#7c766250502097f49bbc2e651132e6bf489e20b8" - integrity sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw== +"@typescript-eslint/types@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.15.0.tgz#4958edf3d83e97f77005f794452e595aaf6430fc" + integrity sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ== -"@typescript-eslint/typescript-estree@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz#35fe5d3636fc5727c52429393415412e552e222b" - integrity sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg== +"@typescript-eslint/typescript-estree@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz#915c94e387892b114a2a2cc0df2d7f19412c8ba7" + integrity sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg== dependencies: - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/visitor-keys" "8.11.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -4587,23 +4612,23 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.11.0.tgz#4480d1e9f2bb18ea3510c79f870a1aefc118103d" - integrity sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g== +"@typescript-eslint/utils@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.15.0.tgz#ac04679ad19252776b38b81954b8e5a65567cef6" + integrity sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.11.0" - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/typescript-estree" "8.11.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/typescript-estree" "8.15.0" -"@typescript-eslint/visitor-keys@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz#273de1cbffe63d9f9cd7dfc20b5a5af66310cb92" - integrity sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw== +"@typescript-eslint/visitor-keys@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz#9ea5a85eb25401d2aa74ec8a478af4e97899ea12" + integrity sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q== dependencies: - "@typescript-eslint/types" "8.11.0" - eslint-visitor-keys "^3.4.3" + "@typescript-eslint/types" "8.15.0" + eslint-visitor-keys "^4.2.0" "@ungap/structured-clone@^1.0.0": version "1.2.0" @@ -4873,6 +4898,11 @@ acorn@^8.12.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + acorn@^8.4.1: version "8.8.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" @@ -6796,9 +6826,9 @@ cross-fetch@^4.0.0: node-fetch "^2.6.12" cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + version "6.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57" + integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw== dependencies: nice-try "^1.0.4" path-key "^2.0.1" @@ -6806,10 +6836,10 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^7.0.0, cross-spawn@^7.0.3, cross-spawn@^7.0.5: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -8062,10 +8092,10 @@ eslint-scope@5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.1.0.tgz#70214a174d4cbffbc3e8a26911d8bf51b9ae9d30" - integrity sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw== +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -8082,7 +8112,7 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== @@ -8092,31 +8122,36 @@ eslint-visitor-keys@^4.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c" integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg== -eslint@^9.12.0: - version "9.12.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.12.0.tgz#54fcba2876c90528396da0fa44b6446329031e86" - integrity sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + +eslint@^9.15.0: + version "9.15.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.15.0.tgz#77c684a4e980e82135ebff8ee8f0a9106ce6b8a6" + integrity sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.11.0" - "@eslint/config-array" "^0.18.0" - "@eslint/core" "^0.6.0" - "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.12.0" - "@eslint/plugin-kit" "^0.2.0" - "@humanfs/node" "^0.16.5" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.19.0" + "@eslint/core" "^0.9.0" + "@eslint/eslintrc" "^3.2.0" + "@eslint/js" "9.15.0" + "@eslint/plugin-kit" "^0.2.3" + "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.3.1" + "@humanwhocodes/retry" "^0.4.1" "@types/estree" "^1.0.6" "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" - cross-spawn "^7.0.2" + cross-spawn "^7.0.5" debug "^4.3.2" escape-string-regexp "^4.0.0" - eslint-scope "^8.1.0" - eslint-visitor-keys "^4.1.0" - espree "^10.2.0" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -8131,9 +8166,8 @@ eslint@^9.12.0: minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.3" - text-table "^0.2.0" -espree@^10.0.1, espree@^10.1.0, espree@^10.2.0: +espree@^10.0.1, espree@^10.1.0: version "10.2.0" resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6" integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g== @@ -8142,6 +8176,15 @@ espree@^10.0.1, espree@^10.1.0, espree@^10.2.0: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.1.0" +espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -14366,7 +14409,16 @@ string-argv@~0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -14481,7 +14533,14 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@6.0.1, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -14746,11 +14805,6 @@ text-decoder@^1.1.0: dependencies: b4a "^1.6.4" -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - textextensions@^2.5.0: version "2.6.0" resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.6.0.tgz#d7e4ab13fe54e32e08873be40d51b74229b00fc4" @@ -15130,14 +15184,14 @@ typescript-compare@^0.0.2: dependencies: typescript-logic "^0.0.0" -typescript-eslint@^8.11.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.11.0.tgz#74a0551972d675b4141672cec3acc5139b7399c0" - integrity sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA== +typescript-eslint@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.15.0.tgz#c8a2a0d183c3eb48ae176aa078c1b9daa584cf9d" + integrity sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w== dependencies: - "@typescript-eslint/eslint-plugin" "8.11.0" - "@typescript-eslint/parser" "8.11.0" - "@typescript-eslint/utils" "8.11.0" + "@typescript-eslint/eslint-plugin" "8.15.0" + "@typescript-eslint/parser" "8.15.0" + "@typescript-eslint/utils" "8.15.0" typescript-logic@^0.0.0: version "0.0.0" @@ -15915,7 +15969,7 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -15942,6 +15996,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From ff562bc339c3b450c42c7ba79d8b5a4abcf23190 Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:40:03 -0300 Subject: [PATCH 03/13] feat: Update versions for generators (#4796) * Update templates' package.json files * Include generators in update-versions script * Fix pattern in unit tests * Fix indentation * Upgrade TS version to latest --- .../app/templates/core/package-with-tests.json.js | 10 +++++----- .../app/templates/core/package-with-tests.json.ts | 13 +++++++------ .../generators/app/templates/core/package.json.js | 8 ++++---- .../generators/app/templates/core/package.json.ts | 11 ++++++----- .../generators/app/templates/core/tsconfig.json | 6 ++++-- .../generators/app/templates/echo/package.json.js | 4 ++-- .../generators/app/templates/echo/package.json.ts | 7 ++++--- .../generators/app/templates/echo/tsconfig.json | 6 ++++-- .../generators/app/templates/empty/package.json.js | 4 ++-- .../generators/app/templates/empty/package.json.ts | 7 ++++--- .../generators/app/templates/empty/tsconfig.json | 6 ++++-- libraries/botbuilder-repo-utils/src/package.ts | 2 +- .../botbuilder-repo-utils/src/updateVersions.ts | 7 ++++++- libraries/botbuilder-repo-utils/src/workspace.ts | 6 +++++- .../tests/updateVersions.test.ts | 4 ++-- package.json | 8 ++++---- 16 files changed, 64 insertions(+), 45 deletions(-) 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/libraries/botbuilder-repo-utils/src/package.ts b/libraries/botbuilder-repo-utils/src/package.ts index afcbdc1913..366c291e76 100644 --- a/libraries/botbuilder-repo-utils/src/package.ts +++ b/libraries/botbuilder-repo-utils/src/package.ts @@ -11,7 +11,7 @@ export interface Package { deprecated?: boolean; internal?: boolean; - workspaces?: { packages: string[] }; + workspaces?: { packages: string[]; generators: string[] }; dependencies?: Record; devDependencies?: Record; diff --git a/libraries/botbuilder-repo-utils/src/updateVersions.ts b/libraries/botbuilder-repo-utils/src/updateVersions.ts index 8b5eddb247..5894824e31 100644 --- a/libraries/botbuilder-repo-utils/src/updateVersions.ts +++ b/libraries/botbuilder-repo-utils/src/updateVersions.ts @@ -94,8 +94,13 @@ export const command = (argv: string[], quiet = false) => async (): Promise>( diff --git a/libraries/botbuilder-repo-utils/src/workspace.ts b/libraries/botbuilder-repo-utils/src/workspace.ts index 7e9ca6c358..aa2feea71c 100644 --- a/libraries/botbuilder-repo-utils/src/workspace.ts +++ b/libraries/botbuilder-repo-utils/src/workspace.ts @@ -41,7 +41,11 @@ export async function collectWorkspacePackages( filters: Partial = {} ): Promise> { // Note: posix is required, this emits absolute paths that are platform specific - const paths = await glob(workspaces.map((workspace) => path.posix.join(repoRoot, workspace, 'package.json'))); + const paths = await glob( + workspaces.map((workspace) => + path.posix.join(repoRoot, workspace, '{package.json,package-with-tests.json}{,.js,.ts}'), + ), + ); const maybeWorkspaces = await Promise.all( paths.map( diff --git a/libraries/botbuilder-repo-utils/tests/updateVersions.test.ts b/libraries/botbuilder-repo-utils/tests/updateVersions.test.ts index 6121beefca..b2f9ec1f3b 100644 --- a/libraries/botbuilder-repo-utils/tests/updateVersions.test.ts +++ b/libraries/botbuilder-repo-utils/tests/updateVersions.test.ts @@ -189,8 +189,8 @@ describe('updateVersions', function () { return { ...workspace, relPath, - absPath: path.join(root, ...relPath, 'package.json'), - posixPath: path.posix.join(root, ...relPath, 'package.json'), + absPath: path.join(root, ...relPath, '{package.json,package-with-tests.json}{,.js,.ts}'), + posixPath: path.posix.join(root, ...relPath, '{package.json,package-with-tests.json}{,.js,.ts}'), }; }); diff --git a/package.json b/package.json index 33a5cef8b5..8748f779d4 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,12 @@ "workspaces": { "packages": [ "libraries/*", - "libraries/functional-tests/dialogToDialog/*", - "libraries/testskills/*", "testing/*", "testing/browser-functional/browser-echo-bot", - "tools", - "transcripts" + "tools" + ], + "generators": [ + "generators/generator-botbuilder/generators/app/templates/*" ], "nohoist": [ "**/@types/selenium-webdriver" From ba6704607b4ee5a238fcb23ab3dffe1d52f0391f Mon Sep 17 00:00:00 2001 From: Joel Mut <62260472+sw-joelmut@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:40:41 -0300 Subject: [PATCH 04/13] Refactor test:consumer script to use Mocha for better formatting and retries in case of failure (#4793) --- testing/consumer-test/.gitignore | 1 + testing/consumer-test/generateTests.ts | 32 +++++++++++ testing/consumer-test/package.json | 10 ++-- testing/consumer-test/run.ts | 65 ----------------------- testing/consumer-test/test.ts | 5 ++ testing/consumer-test/tests/typescript.js | 20 +++++++ 6 files changed, 63 insertions(+), 70 deletions(-) create mode 100644 testing/consumer-test/.gitignore create mode 100644 testing/consumer-test/generateTests.ts delete mode 100644 testing/consumer-test/run.ts create mode 100644 testing/consumer-test/tests/typescript.js diff --git a/testing/consumer-test/.gitignore b/testing/consumer-test/.gitignore new file mode 100644 index 0000000000..e67c65a344 --- /dev/null +++ b/testing/consumer-test/.gitignore @@ -0,0 +1 @@ +tests/generated/* \ No newline at end of file diff --git a/testing/consumer-test/generateTests.ts b/testing/consumer-test/generateTests.ts new file mode 100644 index 0000000000..5c6c4d51d4 --- /dev/null +++ b/testing/consumer-test/generateTests.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * This script generates test files for each version of TypeScript, so the test can run in parallel. + */ + +import fs from 'fs'; +import path from 'path'; + +const versions = ['4.7', '4.8', '4.9', '5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6']; +const targets = ['es6', 'esnext']; + +const testsDir = path.resolve(__dirname, 'tests/generated'); + +if (fs.existsSync(testsDir)) { + fs.rmSync(testsDir, { recursive: true }); +} + +fs.mkdirSync(testsDir); + +for (const version of versions) { + fs.writeFileSync( + path.resolve(testsDir, `typescript.${version}.test.js`), + ` +const testVersion = require('../typescript'); +testVersion('${version}', ['${targets.join("','")}']); + `, + ); +} diff --git a/testing/consumer-test/package.json b/testing/consumer-test/package.json index a54057d0b7..70023e1613 100644 --- a/testing/consumer-test/package.json +++ b/testing/consumer-test/package.json @@ -4,7 +4,9 @@ "version": "1.0.0", "scripts": { "lint": "eslint .", - "test": "ts-node run.ts --verbose" + "test": "npm-run-all test:gen test:mocha", + "test:gen": "ts-node ./generateTests.ts", + "test:mocha": "mocha ./tests/generated/*.test.js --parallel" }, "dependencies": { "adaptive-expressions": "4.1.6", @@ -35,11 +37,9 @@ "botframework-connector": "4.1.6", "botframework-schema": "4.1.6", "botframework-streaming": "4.1.6", - "eslint-plugin-only-warn": "^1.1.0", - "minimist": "^1.2.6", - "p-map": "^4.0.0" + "eslint-plugin-only-warn": "^1.1.0" }, "devDependencies": { - "@types/minimist": "^1.2.5" + "mocha": "^10.7.3" } } diff --git a/testing/consumer-test/run.ts b/testing/consumer-test/run.ts deleted file mode 100644 index 52a915a3ff..0000000000 --- a/testing/consumer-test/run.ts +++ /dev/null @@ -1,65 +0,0 @@ -import minimist from 'minimist'; -import pmap from 'p-map'; -import { exec } from 'child_process'; -import { promisify } from 'util'; - -const execp = promisify(exec); - -const versions = ['4.7', '4.8', '4.9', '5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6']; - -(async () => { - const flags = minimist(process.argv.slice(2), { - boolean: ['verbose'], - alias: { v: 'verbose' }, - }); - - try { - const [minTarget, maxTarget] = ['es6', 'esnext']; - console.log( - `Running typescript consumer test against ["${versions.join( - '", "' - )}"] with '${minTarget}' and '${maxTarget}' targets.` - ); - - const results = await pmap( - versions, - (version) => - Promise.all([ - execp(`npx -p typescript@${version} tsc -p tsconfig-test.json --target ${minTarget}`), - execp(`npx -p typescript@${version} tsc -p tsconfig-test.json --target ${maxTarget}`), - ]) - .then(() => ({ err: null, version, success: true })) - .catch((err) => ({ err, version, success: false })), - { concurrency: 2 } - ); - - const initialValue: { success: string[]; failed: string[] } = { - success: [], - failed: [], - }; - - const { success, failed } = results.reduce((acc, result) => { - if (result.success) { - acc.success.push(result.version); - } else { - acc.failed.push(result.version); - } - - return acc; - }, initialValue); - - console.log('Success:', success); - console.log('Failed:', failed); - - if (flags.verbose) { - results - .filter(({ success }) => success === false) - .forEach(({ err, version }) => console.error(`typescript@${version}`, err)); - } - - process.exit(failed.length ? 1 : 0); - } catch (error) { - console.error(error); - process.exit(-1); - } -})(); diff --git a/testing/consumer-test/test.ts b/testing/consumer-test/test.ts index 94865313cc..0620f330e5 100644 --- a/testing/consumer-test/test.ts +++ b/testing/consumer-test/test.ts @@ -1,3 +1,8 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + import * as adaptiveExpressions from 'adaptive-expressions'; import * as adaptiveExpressionsIE11 from 'adaptive-expressions-ie11'; import * as botbuilder from 'botbuilder'; diff --git a/testing/consumer-test/tests/typescript.js b/testing/consumer-test/tests/typescript.js new file mode 100644 index 0000000000..f74debc1b8 --- /dev/null +++ b/testing/consumer-test/tests/typescript.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + +const { exec } = require('child_process'); +const { promisify } = require('util'); +const execp = promisify(exec); + +module.exports = function testVersion(version, targets) { + describe(`typescript:${version}`, function () { + this.timeout(300000); // 5 minutes + this.retries(1); + for (const target of targets) { + it(`target:${target}`, async function () { + await execp(`npx -p typescript@${version} tsc -p tsconfig-test.json --target ${target}`); + }); + } + }); +}; From c92f9983aa676861f9a8c42175d7cf074ba61563 Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:41:37 -0300 Subject: [PATCH 05/13] fix: [#4684] ESLint issues in botbuilder-ai (#4790) * Fix eslint issues in botbuilder-ai * Add build step to lint GitHub action --- .github/workflows/lint.yml | 3 ++ libraries/botbuilder-ai/eslint.config.cjs | 11 ----- libraries/botbuilder-ai/package.json | 3 +- libraries/botbuilder-ai/src/custom.window.ts | 2 +- .../src/customQuestionAnswering.ts | 20 ++++----- libraries/botbuilder-ai/src/globals.ts | 6 +-- libraries/botbuilder-ai/src/instanceData.ts | 2 +- libraries/botbuilder-ai/src/intentData.ts | 2 +- .../src/luisAdaptivePredictionOptions.ts | 3 +- .../src/luisAdaptiveRecognizer.ts | 8 ++-- .../botbuilder-ai/src/luisBotComponent.ts | 2 +- libraries/botbuilder-ai/src/luisRecognizer.ts | 25 ++++++----- .../src/luisRecognizerOptions.ts | 5 ++- .../src/luisRecognizerOptionsV2.ts | 35 ++++++--------- .../src/luisRecognizerOptionsV3.ts | 8 ++-- libraries/botbuilder-ai/src/luisSchema.d.ts | 2 +- .../src/luisV2-models/luisPrediction.ts | 8 ++-- libraries/botbuilder-ai/src/qnaCardBuilder.ts | 4 +- libraries/botbuilder-ai/src/qnaMaker.ts | 26 +++++------ .../botbuilder-ai/src/qnaMakerBotComponent.ts | 2 +- libraries/botbuilder-ai/src/qnaMakerDialog.ts | 43 +++++++++---------- .../botbuilder-ai/src/qnaMakerRecognizer.ts | 12 +++--- .../src/qnamaker-interfaces/qnamakerPrompt.ts | 2 +- .../src/qnamaker-interfaces/qnamakerResult.ts | 2 +- .../qnamaker-interfaces/qnamakerTraceInfo.ts | 4 +- .../src/qnamaker-utils/activeLearningUtils.ts | 4 +- .../src/qnamaker-utils/bindToActivity.ts | 1 - .../src/qnamaker-utils/generateAnswerUtils.ts | 27 ++++++------ .../src/qnamaker-utils/httpRequestUtils.ts | 4 +- .../qnamaker-utils/languageServiceUtils.ts | 18 ++++---- .../tests/languageService.test.js | 22 +++++----- .../tests/luisRecognizer.test.js | 40 ++++++++--------- libraries/botbuilder-ai/tests/luisSdk.test.js | 10 ++++- .../tests/luisV3OracleTests.test.js | 8 ++-- .../botbuilder-ai/tests/qnaMaker.test.js | 28 ++++++------ .../tests/qnaMakerDialog.test.js | 24 +++++------ .../tests/qnaMakerRecognizer.test.js | 2 +- 37 files changed, 209 insertions(+), 219 deletions(-) delete mode 100644 libraries/botbuilder-ai/eslint.config.cjs 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/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); From 7feb45666975969ade7d11a6eb495ed950e1bf3d Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:42:25 -0300 Subject: [PATCH 06/13] Add missing directory to workspaces (#4801) --- generators/generator-botbuilder/package.json | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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/package.json b/package.json index 8748f779d4..4ad0f3de24 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "tools" ], "generators": [ + "generators/generator-botbuilder", "generators/generator-botbuilder/generators/app/templates/*" ], "nohoist": [ From 925a2c6de80307a5d1cb0b9e478a86837f7ba9b2 Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:51:34 -0300 Subject: [PATCH 07/13] fix: [#4684] ESLint issues in botbuilder-azure-blobs (#4802) * Fix ESLint issues in botbuilder-azure-blobs * Remove eslint-plugin-only-warn dependency --- libraries/botbuilder-azure-blobs/eslint.config.cjs | 10 ---------- libraries/botbuilder-azure-blobs/package.json | 3 +-- .../botbuilder-azure-blobs/src/blobsStorage.ts | 10 +++++----- .../src/blobsTranscriptStore.ts | 14 +++++++------- .../tests/blobsStorage.test.js | 5 +++-- .../tests/blobsTranscriptStore.test.js | 6 +++--- 6 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 libraries/botbuilder-azure-blobs/eslint.config.cjs 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 985cd035c8..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), {}); } @@ -196,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 348a4e7ce4..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'), ); }); }); @@ -102,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, - })) + })), ); }); }); From 64a10b15524cf2bf185ed3e0cca44ac8c9c6f4c6 Mon Sep 17 00:00:00 2001 From: Cecilia Avila <44245136+ceciliaavila@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:07:52 -0300 Subject: [PATCH 08/13] Fix eslint issues in botbuilder-lg (#4803) --- libraries/botbuilder-lg/eslint.config.cjs | 11 +- libraries/botbuilder-lg/package.json | 1 - libraries/botbuilder-lg/src/analyzer.ts | 8 +- .../botbuilder-lg/src/customizedMemory.ts | 1 - libraries/botbuilder-lg/src/diagnostic.ts | 2 +- libraries/botbuilder-lg/src/errorListener.ts | 7 +- .../botbuilder-lg/src/evaluationOptions.ts | 1 - libraries/botbuilder-lg/src/evaluator.ts | 315 ++++++++-------- libraries/botbuilder-lg/src/expander.ts | 343 +++++++++--------- libraries/botbuilder-lg/src/extractor.ts | 15 +- libraries/botbuilder-lg/src/index.ts | 1 - .../botbuilder-lg/src/multiLanguageLG.ts | 2 +- libraries/botbuilder-lg/src/staticChecker.ts | 69 ++-- .../botbuilder-lg/src/templateExtensions.ts | 3 +- libraries/botbuilder-lg/src/templates.ts | 26 +- .../botbuilder-lg/src/templatesParser.ts | 58 ++- libraries/botbuilder-lg/tests/lg.test.js | 52 ++- .../botbuilder-lg/tests/lgDiagnostic.test.js | 92 ++--- .../tests/multilanguageLG.test.js | 2 +- 19 files changed, 512 insertions(+), 497 deletions(-) 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