diff --git a/package-lock.json b/package-lock.json index 7d26985e..16825fcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,19 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@azure/ms-rest-js": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-1.2.6.tgz", + "integrity": "sha512-8cmDpxsQjVdveJwYKtNnkJorxEORLYJu9UHaUvLZA6yHExzDeISHAcSVWE0J05+VkJtqheVHF17M+2ro18Cdnw==", + "requires": { + "axios": "^0.18.0", + "form-data": "^2.3.2", + "tough-cookie": "^2.4.3", + "tslib": "^1.9.2", + "uuid": "^3.2.1", + "xml2js": "^0.4.19" + } + }, "@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", @@ -986,6 +999,23 @@ "resolved": "https://registry.npmjs.org/@kyleshockey/object-assign-deep/-/object-assign-deep-0.4.2.tgz", "integrity": "sha1-hJAPDu/DcnmPR1G1JigwuCCJIuw=" }, + "@microsoft/microsoft-graph-client": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-1.5.2.tgz", + "integrity": "sha512-lUsFLQMmi94r5+Eabmi5FBvlmxsqHPzdqm4suegFmcmnOI5+4OCLADORkRFRJXcWzTKB2ypR9x/mGv7f3r9DzA==", + "requires": { + "es6-promise": "^4.2.6", + "isomorphic-fetch": "^2.2.1", + "tslib": "^1.9.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + } + } + }, "@microsoft/recognizers-text": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text/-/recognizers-text-1.1.4.tgz", @@ -1662,6 +1692,18 @@ "@types/request": "*" } }, + "@types/sequelize": { + "version": "4.27.39", + "resolved": "https://registry.npmjs.org/@types/sequelize/-/sequelize-4.27.39.tgz", + "integrity": "sha512-FABh5gLbXgh6/0pmJQ7VzjN5KAxd/IbX3G5Z6fSBZ6DSqaYl7DBP22nGtLh2e6dPmC0rUxfJclNhzQcC3XgvVw==", + "dev": true, + "requires": { + "@types/bluebird": "*", + "@types/continuation-local-storage": "*", + "@types/lodash": "*", + "@types/validator": "*" + } + }, "@types/shelljs": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.2.tgz", @@ -2004,6 +2046,11 @@ "readable-stream": "^2.0.6" } }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2184,11 +2231,11 @@ "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=" }, "auto-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/auto-parse/-/auto-parse-1.5.1.tgz", - "integrity": "sha1-Oszj3pRKL7Xa433MW1s5yHLYeFI=", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/auto-parse/-/auto-parse-1.6.0.tgz", + "integrity": "sha512-bxQzTBuQxezN8G4d2kd8U7ozJ1vUlEFwa7RVbBIL7IH8nxWikCup/JcdMadEFwnHRUFuJrlYo7i0domuFSXp4w==", "requires": { - "typpy": "^2.3.10" + "typpy": "2.3.10" } }, "aws-sign2": { @@ -2256,9 +2303,9 @@ } }, "azure-cognitiveservices-luis-runtime": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/azure-cognitiveservices-luis-runtime/-/azure-cognitiveservices-luis-runtime-1.2.2.tgz", - "integrity": "sha512-qds2UQ85IWMj9w3HXB0BS0MqSyQ50YlVtS6Y1X6aSf2sN1RVvdct6gZnUMREgjDTKgo+/Iwh4MmPVmhvpPUu0A==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/azure-cognitiveservices-luis-runtime/-/azure-cognitiveservices-luis-runtime-1.2.0.tgz", + "integrity": "sha512-8A71ZfDs5uB+t7SX7GdESuAxgAOR+jKmhnRprx09Pk5gfdJd1HSC2moLxUhqJsS1WQ6I+g7ShG7kLXWmQIXQyg==", "requires": { "ms-rest": "^2.5.0" }, @@ -2614,9 +2661,9 @@ }, "dependencies": { "@types/node": { - "version": "9.6.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.42.tgz", - "integrity": "sha512-SpeVQJFekfnEaZZO1yl4je/36upII36L7gOT4DBx51B1GeAB45mmDb3a5OBQB+ZeFxVVOP37r8Owsl940G/fBg==" + "version": "9.6.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.45.tgz", + "integrity": "sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==" } } }, @@ -2640,22 +2687,28 @@ }, "dependencies": { "@types/node": { - "version": "9.6.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.42.tgz", - "integrity": "sha512-SpeVQJFekfnEaZZO1yl4je/36upII36L7gOT4DBx51B1GeAB45mmDb3a5OBQB+ZeFxVVOP37r8Owsl940G/fBg==" + "version": "9.6.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.45.tgz", + "integrity": "sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==" }, "botbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.2.1.tgz", - "integrity": "sha512-58664aLhN1WQwAxMBK7LZQhFh8DHwenvpgz6ADFgeZLZS28NACfX+Uta8k2+WF6RK3g+VKoGOhV/yI71c5ccVg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.3.2.tgz", + "integrity": "sha512-l7Y83WxytYSBcsFCSoqc8RqXhctnApV131nn72K/mA627DQWAK+M63gYqTFYJBjsO8ok9mNHEzPWQSE9TaJ03Q==", "requires": { "@types/filenamify": "^2.0.1", - "@types/node": "^9.3.0", + "@types/node": "^10.12.18", "async-file": "^2.0.2", - "botbuilder-core": "^4.2.1", - "botframework-connector": "^4.2.1", - "filenamify": "^2.0.0", - "rimraf": "^2.6.2" + "botbuilder-core": "^4.3.2", + "botframework-connector": "^4.3.2", + "filenamify": "^2.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz", + "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q==" + } } }, "request-promise-native": { @@ -2684,22 +2737,28 @@ }, "dependencies": { "@types/node": { - "version": "9.6.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.42.tgz", - "integrity": "sha512-SpeVQJFekfnEaZZO1yl4je/36upII36L7gOT4DBx51B1GeAB45mmDb3a5OBQB+ZeFxVVOP37r8Owsl940G/fBg==" + "version": "9.6.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.45.tgz", + "integrity": "sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==" }, "botbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.2.1.tgz", - "integrity": "sha512-58664aLhN1WQwAxMBK7LZQhFh8DHwenvpgz6ADFgeZLZS28NACfX+Uta8k2+WF6RK3g+VKoGOhV/yI71c5ccVg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.3.2.tgz", + "integrity": "sha512-l7Y83WxytYSBcsFCSoqc8RqXhctnApV131nn72K/mA627DQWAK+M63gYqTFYJBjsO8ok9mNHEzPWQSE9TaJ03Q==", "requires": { "@types/filenamify": "^2.0.1", - "@types/node": "^9.3.0", + "@types/node": "^10.12.18", "async-file": "^2.0.2", - "botbuilder-core": "^4.2.1", - "botframework-connector": "^4.2.1", - "filenamify": "^2.0.0", - "rimraf": "^2.6.2" + "botbuilder-core": "^4.3.2", + "botframework-connector": "^4.3.2", + "filenamify": "^2.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz", + "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q==" + } } } } @@ -2849,12 +2908,12 @@ } }, "botbuilder-core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.2.1.tgz", - "integrity": "sha512-U8n+eY9Cjce0GkMyyE0mv4HBjCjtyuczz6usl9XF2N7nY61jYDah4W5e4zqYdLdlqnBwfxG8ptS9pdnmVsC2ww==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botbuilder-core/-/botbuilder-core-4.3.2.tgz", + "integrity": "sha512-iKaSjOffhb4b40B3N/k1vjFq0AD5QBtx9/Tg8GdeXgxWtbY0QXiFekU7pKfPBAOS3MhY8h/u7w8SmOnrENk62w==", "requires": { "assert": "^1.4.1", - "botframework-schema": "^4.2.1" + "botframework-schema": "^4.3.2" } }, "botbuilder-core-extensions": { @@ -2943,9 +3002,9 @@ } }, "@types/node": { - "version": "9.6.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.42.tgz", - "integrity": "sha512-SpeVQJFekfnEaZZO1yl4je/36upII36L7gOT4DBx51B1GeAB45mmDb3a5OBQB+ZeFxVVOP37r8Owsl940G/fBg==" + "version": "9.6.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.45.tgz", + "integrity": "sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==" } } }, @@ -3094,18 +3153,17 @@ } }, "botframework-connector": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.2.1.tgz", - "integrity": "sha512-O2RmSG4AFyNc7h9zD2a7kdIBw8jF3Thpl8Pwfs/BpKGhRrCIJAMasV0+UbIV2Iwi2NEl7WzdpXjUsnpmB57XgQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botframework-connector/-/botframework-connector-4.3.2.tgz", + "integrity": "sha512-nwAAULKFMV2uvXf123R2MRcq3slNMYypBLdoa6KMt6Ri+S2FqVIC4vn+y+pIfFDYbOPOkXErh/JlbunOcfTteA==", "requires": { + "@azure/ms-rest-js": "1.2.6", "@types/jsonwebtoken": "7.2.8", - "@types/node": "^9.3.0", + "@types/node": "^10.12.18", "base64url": "^3.0.0", - "botframework-schema": "^4.2.1", + "botframework-schema": "^4.3.2", "form-data": "^2.3.3", "jsonwebtoken": "8.0.1", - "ms-rest-azure-js": "1.0.176", - "ms-rest-js": "1.0.455", "nock": "^10.0.3", "node-fetch": "^2.2.1", "rsa-pem-from-mod-exp": "^0.8.4" @@ -3120,9 +3178,9 @@ } }, "@types/node": { - "version": "9.6.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.42.tgz", - "integrity": "sha512-SpeVQJFekfnEaZZO1yl4je/36upII36L7gOT4DBx51B1GeAB45mmDb3a5OBQB+ZeFxVVOP37r8Owsl940G/fBg==" + "version": "10.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz", + "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q==" }, "base64url": { "version": "3.0.1", @@ -3139,19 +3197,6 @@ "mime-types": "^2.1.12" } }, - "ms-rest-js": { - "version": "1.0.455", - "resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-1.0.455.tgz", - "integrity": "sha512-RUDnFFNhk4ZdvOACg0yfaxmp5OzNwUcTIwgh/rVBeuNzgA7hOoVh5zFW06XmOtaBHXL2Bu/vWoQtzloEUlv9tw==", - "requires": { - "axios": "^0.18.0", - "form-data": "^2.3.2", - "tough-cookie": "^2.4.3", - "tslib": "^1.9.2", - "uuid": "^3.2.1", - "xml2js": "^0.4.19" - } - }, "node-fetch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", @@ -3160,33 +3205,9 @@ } }, "botframework-schema": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.2.1.tgz", - "integrity": "sha512-0aJ5UIjs6dKZYdovnlnoIb7+wBId3cubQzwC0tH6S//JhayqrKqMcD8vPPgwZHhBhBx8ZFNmKD3MJtCvZZ1GYA==", - "requires": { - "@types/node": "^9.3.0", - "ms-rest-js": "1.0.455" - }, - "dependencies": { - "@types/node": { - "version": "9.6.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.42.tgz", - "integrity": "sha512-SpeVQJFekfnEaZZO1yl4je/36upII36L7gOT4DBx51B1GeAB45mmDb3a5OBQB+ZeFxVVOP37r8Owsl940G/fBg==" - }, - "ms-rest-js": { - "version": "1.0.455", - "resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-1.0.455.tgz", - "integrity": "sha512-RUDnFFNhk4ZdvOACg0yfaxmp5OzNwUcTIwgh/rVBeuNzgA7hOoVh5zFW06XmOtaBHXL2Bu/vWoQtzloEUlv9tw==", - "requires": { - "axios": "^0.18.0", - "form-data": "^2.3.2", - "tough-cookie": "^2.4.3", - "tslib": "^1.9.2", - "uuid": "^3.2.1", - "xml2js": "^0.4.19" - } - } - } + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botframework-schema/-/botframework-schema-4.3.2.tgz", + "integrity": "sha512-++y/EOu52rRz+TWNkFbOu3Dj7fVyXRlrJktMFo6npr2ISnNNntWY5U0U3ouAUDt7aDKRsB1Rcn2LISdS5FRCoA==" }, "botlib": { "version": "0.1.21", @@ -3212,6 +3233,170 @@ "winston": "3.2.1" }, "dependencies": { + "@microsoft/recognizers-text-choice": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-choice/-/recognizers-text-choice-1.1.2.tgz", + "integrity": "sha512-4hFdqxusM0YrOXYM2RVYPl2rLjItSh6VkRiACjWB95GKC/DBGjJRYQpTxhzuZAsJSkDMinu/aLf8DvQtwUaLtA==", + "requires": { + "@microsoft/recognizers-text": "~1.1.2", + "grapheme-splitter": "^1.0.2" + } + }, + "@microsoft/recognizers-text-number": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-number/-/recognizers-text-number-1.1.2.tgz", + "integrity": "sha512-GESjSF42dllym83diyd6pmlzFwdzidewoq/qSQz89lSoTx9HdJQHjbXxwdBp7w4Ax/Jroo2lcAedM3B7alZhYQ==", + "requires": { + "@microsoft/recognizers-text": "~1.1.2", + "bignumber.js": "^7.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.sortby": "^4.7.0", + "lodash.trimend": "^4.5.1" + } + }, + "@microsoft/recognizers-text-suite": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@microsoft/recognizers-text-suite/-/recognizers-text-suite-1.1.2.tgz", + "integrity": "sha512-w3WCsKa//64jE1fGPFlV02rRg9+b3oDp+K5/skPAn4KDr80LjXxD1ulIgiJ2Ll/2OoBl8ociCiCjYA7zS3LpdQ==", + "requires": { + "@microsoft/recognizers-text": "~1.1.2", + "@microsoft/recognizers-text-choice": "~1.1.2", + "@microsoft/recognizers-text-date-time": "~1.1.2", + "@microsoft/recognizers-text-number": "~1.1.2", + "@microsoft/recognizers-text-number-with-unit": "~1.1.2", + "@microsoft/recognizers-text-sequence": "~1.1.2" + } + }, + "@types/node": { + "version": "9.6.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.45.tgz", + "integrity": "sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==" + }, + "botbuilder": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.1.7.tgz", + "integrity": "sha512-AlZhvjeqiCpeWGN1TkqBi09l6f0spYIh0Xzc4rJYF8feCFi4k2FEYC1IpiiOAtYhEBeQ9SOGFcUUwPaLmsI3Xg==", + "requires": { + "@types/filenamify": "^2.0.1", + "@types/node": "^9.3.0", + "async-file": "^2.0.2", + "botbuilder-core": "^4.1.7", + "botframework-connector": "^4.1.7", + "filenamify": "^2.0.0", + "rimraf": "^2.6.2" + } + }, + "botbuilder-ai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/botbuilder-ai/-/botbuilder-ai-4.2.0.tgz", + "integrity": "sha512-dt2OydZ9pWyMSNgha3PlC6lBq3sXUXAYmadqogNqvWpYEmIMdBOCUc02Vn2w1suxLX84GdYqdBI2klwrRZ7oKg==", + "requires": { + "@microsoft/recognizers-text-date-time": "1.1.2", + "@types/html-entities": "^1.2.16", + "@types/node": "^9.3.0", + "@types/request-promise-native": "^1.0.10", + "azure-cognitiveservices-luis-runtime": "^1.0.0", + "botbuilder": "^4.2.0", + "html-entities": "^1.2.1", + "moment": "^2.20.1", + "ms-rest": "^2.3.6", + "mstranslator": "^3.0.0", + "request": "^2.87.0", + "request-promise-native": "1.0.5" + }, + "dependencies": { + "botbuilder": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.3.2.tgz", + "integrity": "sha512-l7Y83WxytYSBcsFCSoqc8RqXhctnApV131nn72K/mA627DQWAK+M63gYqTFYJBjsO8ok9mNHEzPWQSE9TaJ03Q==", + "requires": { + "@types/filenamify": "^2.0.1", + "@types/node": "^10.12.18", + "async-file": "^2.0.2", + "botbuilder-core": "^4.3.2", + "botframework-connector": "^4.3.2", + "filenamify": "^2.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz", + "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q==" + } + } + } + } + }, + "botbuilder-azure": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/botbuilder-azure/-/botbuilder-azure-4.2.0.tgz", + "integrity": "sha512-WL8dHtVESE/qTFTGcJwlFeKyUeewoyoNr5ENavu1W40N8UjZB32ivmX2dvd0Zm4TIbeBwgmomF2gE9rE+0Rv3w==", + "requires": { + "@types/node": "^9.3.0", + "azure-storage": "^2.10.2", + "botbuilder": "^4.2.0", + "documentdb": "1.14.5", + "flat": "^4.0.0", + "semaphore": "^1.1.0" + }, + "dependencies": { + "botbuilder": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/botbuilder/-/botbuilder-4.3.2.tgz", + "integrity": "sha512-l7Y83WxytYSBcsFCSoqc8RqXhctnApV131nn72K/mA627DQWAK+M63gYqTFYJBjsO8ok9mNHEzPWQSE9TaJ03Q==", + "requires": { + "@types/filenamify": "^2.0.1", + "@types/node": "^10.12.18", + "async-file": "^2.0.2", + "botbuilder-core": "^4.3.2", + "botframework-connector": "^4.3.2", + "filenamify": "^2.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.30.tgz", + "integrity": "sha512-nsqTN6zUcm9xtdJiM9OvOJ5EF0kOI8f1Zuug27O/rgtxCRJHGqncSWfCMZUP852dCKPsDsYXGvBhxfRjDBkF5Q==" + } + } + } + } + }, + "botbuilder-dialogs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/botbuilder-dialogs/-/botbuilder-dialogs-4.2.0.tgz", + "integrity": "sha512-wi7Vk/mRHqsjNVhCbXK6yoYsQ7uS7EySM+bcDRthw5uDQ9LyHHoRg3wzT+mqbfjzwgpKR/TXxPUDM4nDL8Hz+Q==", + "requires": { + "@microsoft/recognizers-text-choice": "1.1.2", + "@microsoft/recognizers-text-date-time": "1.1.2", + "@microsoft/recognizers-text-number": "1.1.2", + "@microsoft/recognizers-text-suite": "1.1.2", + "@types/node": "^9.3.0", + "botbuilder-core": "^4.2.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "dotenv-extended": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/dotenv-extended/-/dotenv-extended-2.3.0.tgz", + "integrity": "sha512-QrFPzMr25tkdEesy2vJQDk0Yqs1Wy0IWSngaU/QNnQfukG735kXp3K+YfW6CMcR/N/3BGw5oIqyBLtGU8a5SZQ==", + "requires": { + "@types/dotenv": "^4.0.0", + "auto-parse": "^1.3.0", + "camelcase": "5.0.0", + "cross-spawn": "6.0.5", + "dotenv": "6.0.0", + "is-windows": "^1.0.0", + "lodash": "^4.17.10" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -3219,6 +3404,45 @@ "requires": { "safer-buffer": ">= 2.1.2 < 3" } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, + "sequelize": { + "version": "4.42.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-4.42.1.tgz", + "integrity": "sha512-W9i/CkBjCHLzEkJQkaxXaK82MA16b7F74PjtE7EUR+d7WU/X3U+YU5givWR+/VRXay1VXDyBOfXgw9/zdhDSDg==", + "requires": { + "bluebird": "^3.5.0", + "cls-bluebird": "^2.1.0", + "debug": "^3.1.0", + "depd": "^1.1.0", + "dottie": "^2.0.0", + "generic-pool": "3.5.0", + "inflection": "1.12.0", + "lodash": "^4.17.1", + "moment": "^2.20.0", + "moment-timezone": "^0.5.14", + "retry-as-promised": "^2.3.2", + "semver": "^5.5.0", + "terraformer-wkt-parser": "^1.1.2", + "toposort-class": "^1.0.1", + "uuid": "^3.2.1", + "validator": "^10.4.0", + "wkx": "^0.4.1" + } + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" } } }, @@ -3802,6 +4026,11 @@ "restore-cursor": "^2.0.0" } }, + "cli-spinner": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/cli-spinner/-/cli-spinner-0.2.10.tgz", + "integrity": "sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==" + }, "cli-table": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", @@ -4076,6 +4305,11 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, "commitizen": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-3.0.7.tgz", @@ -4262,6 +4496,15 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", @@ -5253,12 +5496,12 @@ "dotenv": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.0.0.tgz", - "integrity": "sha1-JON8BBdBxfSyUySVjrvDS8qWWTU=" + "integrity": "sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg==" }, "dotenv-extended": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/dotenv-extended/-/dotenv-extended-2.3.0.tgz", - "integrity": "sha1-fCWVHKt+Ib0XFbhxG0GD308tx6M=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/dotenv-extended/-/dotenv-extended-2.4.0.tgz", + "integrity": "sha512-OJmXoMk3YpxsGAibLUi4F8Uu2CN9wtDO/Uqv9kWx1bL6qXcku1jq+hk5wTaX7UVcpcl5rCbUrvN9nv0bOXC/Kw==", "requires": { "@types/dotenv": "^4.0.0", "auto-parse": "^1.3.0", @@ -5311,6 +5554,38 @@ "safe-buffer": "^5.0.1" } }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -8205,6 +8480,15 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, "isomorphic-form-data": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-0.0.1.tgz", @@ -8274,6 +8558,33 @@ "integrity": "sha512-CpKJh9VRNhS+XqZtg1UMejETGEiqwCGDC/uwPEEQwc2nfdbSm73SIE29TplG2gLYuBOOTNDqxzG6A9NtEPLt0w==", "dev": true }, + "js-beautify": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.9.0.tgz", + "integrity": "sha512-P0skmY4IDjfLiVrx+GLDeme8w5G0R1IGXgccVU5HP2VM3lRblH7qN2LTea5vZAxrDjpZBD0Jv+ahpjwVcbz/rw==", + "requires": { + "config-chain": "^1.1.12", + "editorconfig": "^0.15.2", + "glob": "^7.1.3", + "mkdirp": "~0.5.0", + "nopt": "~4.0.1" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "js-levenshtein": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", @@ -8898,6 +9209,11 @@ "pify": "^3.0.0" } }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -9474,30 +9790,6 @@ } } }, - "ms-rest-azure-js": { - "version": "1.0.176", - "resolved": "https://registry.npmjs.org/ms-rest-azure-js/-/ms-rest-azure-js-1.0.176.tgz", - "integrity": "sha512-qtEBpSf/1nJ0/m1jGLkHISRnpOeHUp5n4SvzZRdFeYnGF4SQx9v/fl8a8ZwEmyujmgbUwyLNM9qKpH5PmW7pZg==", - "requires": { - "ms-rest-js": "^1.0.443", - "tslib": "^1.9.2" - }, - "dependencies": { - "ms-rest-js": { - "version": "1.0.465", - "resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-1.0.465.tgz", - "integrity": "sha512-MMSmxy6yd/EcxcKxdKy13SckcjBWSgcFkO2Ggibw0wQvZKr3DDaOGOaivElfdRkA+djacZLl4A912MNT5VhBPA==", - "requires": { - "axios": "^0.18.0", - "form-data": "^2.3.2", - "tough-cookie": "^2.4.3", - "tslib": "^1.9.2", - "uuid": "^3.2.1", - "xml2js": "^0.4.19" - } - } - } - }, "ms-rest-js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ms-rest-js/-/ms-rest-js-1.0.1.tgz", @@ -14740,6 +15032,11 @@ "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=" }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, "protocols": { "version": "1.4.6", "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.6.tgz", @@ -15937,9 +16234,9 @@ } }, "sequelize": { - "version": "4.42.1", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-4.42.1.tgz", - "integrity": "sha512-W9i/CkBjCHLzEkJQkaxXaK82MA16b7F74PjtE7EUR+d7WU/X3U+YU5givWR+/VRXay1VXDyBOfXgw9/zdhDSDg==", + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-4.43.0.tgz", + "integrity": "sha512-GkwGFVREKBf/ql6W6RXwXy1fzb/HOk0lmOBbcQrJMvJtB65Jfg7CUh+sENh0deuWk5s79JedgZJ/yEjvtzHXaQ==", "requires": { "bluebird": "^3.5.0", "cls-bluebird": "^2.1.0", @@ -16092,6 +16389,11 @@ } } }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -16433,7 +16735,6 @@ "version": "0.5.10", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -16442,8 +16743,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -17520,11 +17820,73 @@ "semver": "^5.0.1" } }, + "ts-node": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.3.tgz", + "integrity": "sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA==", + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", "integrity": "sha1-1+TdeSRdhUKMTX5IIqeZF5VMooY=" }, + "tslint": { + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.13.1.tgz", + "integrity": "sha512-fplQqb2miLbcPhyHoMV4FU9PtNRbgmm/zI5d3SZwwmJQM6V0eodju+hplpyfhLWpmwrDNfNYU57uYRb8s0zZoQ==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.27.2" + } + }, + "tslint-microsoft-contrib": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-6.1.0.tgz", + "integrity": "sha512-8DgmiPTgNQSYTjrKKv/h1aHnDd7EkGAjTxatrjfSDp5jUXENGI7Qj7qi7T8xBdTZN9Z3nb80u0NhdBBOMcQFHg==", + "dev": true, + "requires": { + "tsutils": "^2.27.2 <2.29.0" + }, + "dependencies": { + "tsutils": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", + "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.5.tgz", @@ -18059,6 +18421,11 @@ } } }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", @@ -18577,6 +18944,11 @@ } } } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==" } } } diff --git a/package.json b/package.json index 8c5c757e..d9123a41 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,11 @@ "azure-arm-website": "5.7.0", "bluebird": "^3.5.3", "body-parser": "1.18.3", - "botbuilder": "4.3.2", - "botbuilder-ai": "4.3.2", - "botbuilder-azure": "4.3.2", + "botbuilder": "4.1.7", + "botbuilder-ai": "4.2.0", + "botbuilder-azure": "4.2.0", "botbuilder-choices": "4.0.0-preview1.2", - "botbuilder-dialogs": "4.3.2", + "botbuilder-dialogs": "4.2.0", "botbuilder-prompts": "4.0.0-preview1.2", "botlib": "^0.1.21", "chai": "4.2.0", diff --git a/packages/admin.gbapp/dialogs/AdminDialog.ts b/packages/admin.gbapp/dialogs/AdminDialog.ts index d385f175..eb27b4d4 100644 --- a/packages/admin.gbapp/dialogs/AdminDialog.ts +++ b/packages/admin.gbapp/dialogs/AdminDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -38,7 +38,7 @@ import { WaterfallDialog } from 'botbuilder-dialogs'; import { GBMinInstance, IGBDialog } from 'botlib'; -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService'; import { GBConfigService } from '../../core.gbapp/services/GBConfigService'; import { GBDeployer } from '../../core.gbapp/services/GBDeployer'; @@ -53,7 +53,7 @@ export class AdminDialog extends IGBDialog { const packageName = text.split(' ')[1]; const importer = new GBImporter(min.core); const deployer = new GBDeployer(min.core, importer); - await deployer.undeployPackageFromLocalPath(min.instance, UrlJoin('packages', packageName)); + await deployer.undeployPackageFromLocalPath(min.instance, urlJoin('packages', packageName)); } public static isSharePointPath(path: string) { @@ -63,14 +63,12 @@ export class AdminDialog extends IGBDialog { public static async deployPackageCommand(min: GBMinInstance, text: string, deployer: GBDeployer) { const packageName = text.split(' ')[1]; - if (AdminDialog.isSharePointPath(packageName)) { - await deployer.deployFromSharePoint(min.instance.instanceId, packageName); - } else { + if (!AdminDialog.isSharePointPath(packageName)) { const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH'); if (additionalPath !== undefined) { throw new Error('ADDITIONAL_DEPLOY_PATH is not set and deployPackage was called.'); } - await deployer.deployPackageFromLocalPath(min, UrlJoin(additionalPath, packageName)); + await deployer.deployPackage(min, urlJoin(additionalPath, packageName)); } } @@ -207,7 +205,7 @@ export class AdminDialog extends IGBDialog { const url = `https://login.microsoftonline.com/${ min.instance.authenticatorTenant - }/oauth2/authorize?client_id=${min.instance.authenticatorClientId}&response_type=code&redirect_uri=${UrlJoin( + }/oauth2/authorize?client_id=${min.instance.authenticatorClientId}&response_type=code&redirect_uri=${urlJoin( min.instance.botEndpoint, min.instance.botId, '/token' diff --git a/packages/admin.gbapp/index.ts b/packages/admin.gbapp/index.ts index cfd99bed..a23622a9 100644 --- a/packages/admin.gbapp/index.ts +++ b/packages/admin.gbapp/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,18 +36,29 @@ 'use strict'; -import { GBMinInstance, IGBCoreService, IGBPackage, GBDialogStep } from 'botlib'; +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; import { AdminDialog } from './dialogs/AdminDialog'; import { GuaribasAdmin } from './models/AdminModel'; +/** + * The package for admin.gbapp. + */ export class GBAdminPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; - public unloadPackage(core: IGBCoreService): void {} - public getDialogs(min: GBMinInstance) {} - public unloadBot(min: GBMinInstance): void {} - public onNewSession(min: GBMinInstance, step: GBDialogStep): void {} + public getDialogs(min: GBMinInstance) { + GBLog.verbose(`getDialogs called.`); + } + public unloadPackage(core: IGBCoreService): void { + GBLog.verbose(`unloadPackage called.`); + } + public unloadBot(min: GBMinInstance): void { + GBLog.verbose(`unloadBot called.`); + } + public onNewSession(min: GBMinInstance, step: GBDialogStep): void { + GBLog.verbose(`onNewSession called.`); + } public loadPackage(core: IGBCoreService, sequelize: Sequelize): void { core.sequelize.addModels([GuaribasAdmin]); diff --git a/packages/admin.gbapp/models/AdminModel.ts b/packages/admin.gbapp/models/AdminModel.ts index 99cd37c4..bac6116b 100644 --- a/packages/admin.gbapp/models/AdminModel.ts +++ b/packages/admin.gbapp/models/AdminModel.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -45,6 +45,9 @@ import { UpdatedAt } from 'sequelize-typescript'; +/** + * General settings store. + */ @Table export class GuaribasAdmin extends Model { diff --git a/packages/admin.gbapp/services/GBAdminService.ts b/packages/admin.gbapp/services/GBAdminService.ts index f844a299..a3a481d1 100644 --- a/packages/admin.gbapp/services/GBAdminService.ts +++ b/packages/admin.gbapp/services/GBAdminService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -37,8 +37,8 @@ 'use strict'; import { AuthenticationContext, TokenResponse } from 'adal-node'; -import { IGBAdminService, IGBCoreService } from 'botlib'; -import UrlJoin = require('url-join'); +import { IGBAdminService, IGBCoreService, IGBInstance } from 'botlib'; +import urlJoin = require('url-join'); import { GuaribasInstance } from '../../core.gbapp/models/GBModel'; import { GuaribasAdmin } from '../models/AdminModel'; const msRestAzure = require('ms-rest-azure'); @@ -70,7 +70,6 @@ export class GBAdminService implements IGBAdminService { } public static async getADALCredentialsFromUsername(username: string, password: string) { - return await msRestAzure.loginWithUsernamePassword(username, password); } @@ -101,7 +100,7 @@ export class GBAdminService implements IGBAdminService { maximumLength: 14 }; - return passwordGenerator.generatePassword(options); + return passwordGenerator.generatePassword(options); } public async setValue(instanceId: number, key: string, value: string) { @@ -123,7 +122,7 @@ export class GBAdminService implements IGBAdminService { authenticatorAuthorityHostUrl: string, authenticatorClientId: string, authenticatorClientSecret: string - ): Promise { + ): Promise { const options = { where: {} }; options.where = { instanceId: instanceId }; const item = await GuaribasInstance.findOne(options); @@ -135,7 +134,7 @@ export class GBAdminService implements IGBAdminService { return item.save(); } - public async getValue(instanceId: number, key: string) { + public async getValue(instanceId: number, key: string): Promise { const options = { where: {} }; options.where = { key: key, instanceId: instanceId }; const obj = await GuaribasAdmin.findOne(options); @@ -152,7 +151,7 @@ export class GBAdminService implements IGBAdminService { const accessToken = await this.getValue(instanceId, 'accessToken'); resolve(accessToken); } else { - const authorizationUrl = UrlJoin( + const authorizationUrl = urlJoin( instance.authenticatorAuthorityHostUrl, instance.authenticatorTenant, '/oauth2/authorize' diff --git a/packages/admin.gbapp/strings.ts b/packages/admin.gbapp/strings.ts index 0775e9ed..30beca96 100644 --- a/packages/admin.gbapp/strings.ts +++ b/packages/admin.gbapp/strings.ts @@ -16,7 +16,8 @@ export const Messages = { wrong_password: 'Sorry, wrong password. Please, try again.', enter_authenticator_tenant: 'Enter the Authenticator Tenant (eg.: domain.onmicrosoft.com):', enter_authenticator_authority_host_url: 'Enter the Authority Host URL (eg.: https://login.microsoftonline.com): ', - enter_authenticator_client_id: 'Enter the Client Id [Application Id](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview) GUID:', + enter_authenticator_client_id: `Enter the Client Id GUID: Get from + [this url](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview)`, enter_authenticator_client_secret: 'Enter the Client Secret:' }, 'pt-BR': { diff --git a/packages/analytics.gblib/index.ts b/packages/analytics.gblib/index.ts index 91e07bed..6e123cb4 100644 --- a/packages/analytics.gblib/index.ts +++ b/packages/analytics.gblib/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,14 +36,14 @@ 'use strict'; -import { GBDialogStep, GBMinInstance, IGBCoreService, IGBPackage, GBLog } from 'botlib'; +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; /** * .gblib Package handler. */ export class GBAnalyticsPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public getDialogs(min: GBMinInstance) { GBLog.verbose(`getDialogs called.`); } diff --git a/packages/analytics.gblib/models/index.ts b/packages/analytics.gblib/models/index.ts index 63b148b3..34d4a4c7 100644 --- a/packages/analytics.gblib/models/index.ts +++ b/packages/analytics.gblib/models/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -65,6 +65,56 @@ import { GuaribasChannel, GuaribasInstance } from '../../core.gbapp/models/GBMod import { GuaribasSubject } from '../../kb.gbapp/models'; import { GuaribasUser } from '../../security.gblib/models'; +/** + * A single message in a conversation. + */ +@Table +export class GuaribasConversationMessage extends Model { + + @PrimaryKey + @AutoIncrement + @Column + public conversationMessageId: number; + + @ForeignKey(() => GuaribasSubject) + @Column + public subjectId: number; + + @Column(DataType.TEXT) + public content: string; + + @Column + @CreatedAt + public createdAt: Date; + + @Column + @UpdatedAt + public updatedAt: Date; + + //tslint:disable-next-line:no-use-before-declare + @ForeignKey(() => GuaribasConversation) + @Column + public conversationId: number; + + //tslint:disable-next-line:no-use-before-declare + @BelongsTo(() => GuaribasConversation) + public conversation: GuaribasConversation; + + @ForeignKey(() => GuaribasInstance) + @Column + public instanceId: number; + + @ForeignKey(() => GuaribasUser) + @Column + public userId: number; + + @BelongsTo(() => GuaribasUser) + public user: GuaribasUser; +} + +/** + * A conversation that groups many messages. + */ @Table export class GuaribasConversation extends Model { @@ -106,45 +156,3 @@ export class GuaribasConversation extends Model { @BelongsTo(() => GuaribasUser) public startedBy: GuaribasUser; } - -@Table -export class GuaribasConversationMessage extends Model { - - @PrimaryKey - @AutoIncrement - @Column - public conversationMessageId: number; - - @ForeignKey(() => GuaribasSubject) - @Column - public subjectId: number; - - @Column(DataType.TEXT) - public content: string; - - @Column - @CreatedAt - public createdAt: Date; - - @Column - @UpdatedAt - public updatedAt: Date; - - @ForeignKey(() => GuaribasConversation) - @Column - public conversationId: number; - - @BelongsTo(() => GuaribasConversation) - public conversation: GuaribasConversation; - - @ForeignKey(() => GuaribasInstance) - @Column - public instanceId: number; - - @ForeignKey(() => GuaribasUser) - @Column - public userId: number; - - @BelongsTo(() => GuaribasUser) - public user: GuaribasUser; -} diff --git a/packages/analytics.gblib/services/AnalyticsService.ts b/packages/analytics.gblib/services/AnalyticsService.ts index abefd2bc..2a12eccf 100644 --- a/packages/analytics.gblib/services/AnalyticsService.ts +++ b/packages/analytics.gblib/services/AnalyticsService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -37,6 +37,9 @@ import { GuaribasUser } from '../../security.gblib/models'; import { GuaribasConversation, GuaribasConversationMessage } from '../models'; +/** + * Base services for Bot Analytics. + */ export class AnalyticsService { public async createConversation( user: GuaribasUser @@ -52,7 +55,7 @@ export class AnalyticsService { }); } - public createMessage( + public async createMessage( conversation: GuaribasConversation, user: GuaribasUser, content: string diff --git a/packages/azuredeployer.gbapp/dialogs/StartDialog.ts b/packages/azuredeployer.gbapp/dialogs/StartDialog.ts index dbfe0b18..8912dabf 100644 --- a/packages/azuredeployer.gbapp/dialogs/StartDialog.ts +++ b/packages/azuredeployer.gbapp/dialogs/StartDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | diff --git a/packages/azuredeployer.gbapp/index.ts b/packages/azuredeployer.gbapp/index.ts index 13563ab1..4ddaff36 100644 --- a/packages/azuredeployer.gbapp/index.ts +++ b/packages/azuredeployer.gbapp/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,11 +36,14 @@ 'use strict'; -import { GBMinInstance, IGBCoreService, IGBPackage, GBLog, GBDialogStep } from 'botlib'; +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; +/** + * Package for Azure Deployer. + */ export class GBAzureDeployerPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public getDialogs(min: GBMinInstance) { GBLog.verbose(`getDialogs called.`); } diff --git a/packages/azuredeployer.gbapp/services/AzureDeployerService.ts b/packages/azuredeployer.gbapp/services/AzureDeployerService.ts index 735b3c27..d59c2bf6 100644 --- a/packages/azuredeployer.gbapp/services/AzureDeployerService.ts +++ b/packages/azuredeployer.gbapp/services/AzureDeployerService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -54,7 +54,7 @@ const Spinner = require('cli-spinner').Spinner; // tslint:disable-next-line:no-submodule-imports import { CognitiveServicesAccount } from 'azure-arm-cognitiveservices/lib/models'; -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png'; const publicIp = require('public-ip'); @@ -89,7 +89,7 @@ export class AzureDeployerService implements IGBInstallationDeployer { req.headers = {}; req.headers['Content-Type'] = 'application/json'; req.headers['accept-language'] = '*'; - req.headers['Authorization'] = `Bearer ${accessToken}`; + req.headers.set(' Authorization', `Bearer ${accessToken}`); req.body = body; return req; @@ -220,10 +220,11 @@ export class AzureDeployerService implements IGBInstallationDeployer { const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${ this.provider }/botServices/${botId}?api-version=${this.apiVersion}`; - const url = UrlJoin(baseUrl, query); + const url = urlJoin(baseUrl, query); const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters)); const res = await httpClient.sendRequest(req); - if (!(res['bodyAsJson'] as any).id) { + // CHECK + if (!JSON.parse(res.bodyAsText).id) { throw res.bodyAsText; } GBLog.info(`Bot proxy updated at: ${endpoint}.`); @@ -399,7 +400,7 @@ export class AzureDeployerService implements IGBInstallationDeployer { private async registerProviders(subscriptionId, baseUrl, accessToken) { const query = `subscriptions/${subscriptionId}/providers/${this.provider}/register?api-version=2018-02-01`; - const requestUrl = UrlJoin(baseUrl, query); + const requestUrl = urlJoin(baseUrl, query); const req = new WebResource(); req.method = 'POST'; @@ -407,7 +408,7 @@ export class AzureDeployerService implements IGBInstallationDeployer { req.headers = {}; req.headers['Content-Type'] = 'application/json; charset=utf-8'; req.headers['accept-language'] = '*'; - req.headers['Authorization'] = `Bearer ${accessToken}`; + req.headers.set('Authorization', `Bearer ${accessToken}`); } /** @@ -461,10 +462,10 @@ export class AzureDeployerService implements IGBInstallationDeployer { let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${ this.provider }/botServices/${botId}?api-version=${this.apiVersion}`; - let url = UrlJoin(baseUrl, query); + let url = urlJoin(baseUrl, query); let req = AzureDeployerService.createRequestObject(url, accessToken, 'PUT', JSON.stringify(parameters)); const res = await httpClient.sendRequest(req); - if (!(res['bodyAsJson'] as any).id) { + if (!JSON.parse(res.bodyAsText).id) { reject(res.bodyAsText); return; @@ -476,10 +477,10 @@ export class AzureDeployerService implements IGBInstallationDeployer { query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${ this.apiVersion }`; - url = UrlJoin(baseUrl, query); + url = urlJoin(baseUrl, query); req = AzureDeployerService.createRequestObject(url, accessToken, 'GET', JSON.stringify(parameters)); const resChannel = await httpClient.sendRequest(req); - const key = (resChannel['bodyAsJson'] as any).properties.properties.sites[0].key; + const key = JSON.parse(resChannel.bodyAsText).properties.properties.sites[0].key; instance.webchatKey = key; resolve(instance); } catch (error) { @@ -504,7 +505,7 @@ export class AzureDeployerService implements IGBInstallationDeployer { const body = JSON.stringify(parameters); const apps = await this.makeNlpRequest(location, authoringKey, undefined, 'GET', 'apps'); - const app = (apps['bodyAsJson'] as any).filter(x => x.name === name)[0]; + const app = JSON.parse(apps.bodyAsText).filter(x => x.name === name)[0]; let id: string; if (!app) { const res = await this.makeNlpRequest(location, authoringKey, body, 'POST', 'apps'); @@ -526,7 +527,7 @@ export class AzureDeployerService implements IGBInstallationDeployer { const req = new WebResource(); req.method = method; req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/${resource}`; - req.headers = {}; + req.headers = {}; req.headers['Content-Type'] = 'application/json'; req.headers['accept-language'] = '*'; req.headers['Ocp-Apim-Subscription-Key'] = authoringKey; diff --git a/packages/console.gblib/index.ts b/packages/console.gblib/index.ts index b76df96d..338cf243 100644 --- a/packages/console.gblib/index.ts +++ b/packages/console.gblib/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,15 +36,15 @@ 'use strict'; -import UrlJoin = require('url-join'); - -import { GBMinInstance, IGBCoreService, IGBPackage, GBLog, GBDialogStep } from 'botlib'; - +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; import { ConsoleDirectLine } from './services/ConsoleDirectLine'; +/** + * Package for console.glib. + */ export class GBConsolePackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public channel: ConsoleDirectLine; public getDialogs(min: GBMinInstance) { GBLog.verbose(`getDialogs called.`); diff --git a/packages/core.gbapp/dialogs/WelcomeDialog.ts b/packages/core.gbapp/dialogs/WelcomeDialog.ts index ced210bb..cfc026f7 100644 --- a/packages/core.gbapp/dialogs/WelcomeDialog.ts +++ b/packages/core.gbapp/dialogs/WelcomeDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -38,10 +38,12 @@ import { BotAdapter } from 'botbuilder'; import {WaterfallDialog } from 'botbuilder-dialogs'; -import { IGBDialog } from 'botlib'; -import { GBMinInstance } from 'botlib'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { Messages } from '../strings'; +/** + * Dialog for Welcoming people. + */ export class WelcomeDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -73,9 +75,9 @@ export class WelcomeDialog extends IGBDialog { await step.replaceDialog('/ask', { firstTime: true }); if ( - step.context.activity && - step.context.activity.type == 'message' && - step.context.activity.text != '' + step.context.activity !== undefined && + step.context.activity.type === 'message' && + step.context.activity.text !== '' ) { await step.replaceDialog('/answer', { query: step.context.activity.text }); } diff --git a/packages/core.gbapp/dialogs/WhoAmIDialog.ts b/packages/core.gbapp/dialogs/WhoAmIDialog.ts index 20d7162e..201334cb 100644 --- a/packages/core.gbapp/dialogs/WhoAmIDialog.ts +++ b/packages/core.gbapp/dialogs/WhoAmIDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -38,10 +38,11 @@ import { BotAdapter } from 'botbuilder'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { IGBDialog } from 'botlib'; -import { GBMinInstance } from 'botlib'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { Messages } from '../strings'; - +/** + * Dialog for the bot explains about itself. + */ export class WhoAmIDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -55,7 +56,7 @@ export class WhoAmIDialog extends IGBDialog { const locale = step.context.activity.locale; await step.context.sendActivity(`${min.instance.description}`); - if (min.instance.whoAmIVideo) { + if (min.instance.whoAmIVideo !== undefined) { await step.context.sendActivity(Messages[locale].show_video); await min.conversationalService.sendEvent(step, 'play', { playerType: 'video', diff --git a/packages/core.gbapp/index.ts b/packages/core.gbapp/index.ts index 94f227cb..1fcf4e03 100644 --- a/packages/core.gbapp/index.ts +++ b/packages/core.gbapp/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,19 +36,18 @@ 'use strict'; -import UrlJoin = require('url-join'); - -import { GBMinInstance, IGBPackage, GBLog, GBDialogStep } from 'botlib'; - -import { IGBCoreService } from 'botlib'; +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; import { WelcomeDialog } from './dialogs/WelcomeDialog'; import { WhoAmIDialog } from './dialogs/WhoAmIDialog'; import { GuaribasChannel, GuaribasException, GuaribasInstance, GuaribasPackage } from './models/GBModel'; +/** + * Package for core.gbapp. + */ export class GBCorePackage implements IGBPackage { public static CurrentEngineName = 'guaribas-1.0.0'; - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public loadPackage(core: IGBCoreService, sequelize: Sequelize): void { core.sequelize.addModels([GuaribasInstance, GuaribasPackage, GuaribasChannel, GuaribasException]); } diff --git a/packages/core.gbapp/models/GBError.ts b/packages/core.gbapp/models/GBError.ts new file mode 100644 index 00000000..a0c8366a --- /dev/null +++ b/packages/core.gbapp/models/GBError.ts @@ -0,0 +1,50 @@ +/*****************************************************************************\ +| ( )_ _ | +| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | +| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | +| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | +| | | ( )_) | | +| (_) \___/' | +| | +| General Bots Copyright (c) Pragmatismo.io. All rights reserved. | +| Licensed under the AGPL-3.0. | +| | +| According to our dual licensing model, this program can be used either | +| under the terms of the GNU Affero General Public License, version 3, | +| or under a proprietary license. | +| | +| The texts of the GNU Affero General Public License with an additional | +| permission and of our proprietary license can be found at and | +| in the LICENSE file you have received along with this program. | +| | +| This program is distributed in the hope that it will be useful, | +| but WITHOUT ANY WARRANTY, without even the implied warranty of | +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +| GNU Affero General Public License for more details. | +| | +| "General Bots" is a registered trademark of Pragmatismo.io. | +| The licensing of the program under the AGPLv3 does not imply a | +| trademark license. Therefore any rights, title and interest in | +| our trademarks remain entirely with us. | +| | +\*****************************************************************************/ + +/** + * @fileoverview General Bots server core. + */ + +'use strict'; + +import { + AutoIncrement, + BelongsTo, + Column, + CreatedAt, + ForeignKey, + Model, + PrimaryKey, + Table, + UpdatedAt +} from 'sequelize-typescript'; +import { GuaribasInstance } from './GBModel'; diff --git a/packages/core.gbapp/models/GBModel.ts b/packages/core.gbapp/models/GBModel.ts index cf1dac68..339eb864 100644 --- a/packages/core.gbapp/models/GBModel.ts +++ b/packages/core.gbapp/models/GBModel.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -51,6 +51,9 @@ import { import { IGBInstance } from 'botlib'; +/** + * Base instance data for a bot. + */ @Table export class GuaribasInstance extends Model implements IGBInstance { @@ -81,8 +84,6 @@ export class GuaribasInstance extends Model @Column public enabledAdmin: boolean; - /* Services section on bot.json */ - @Column public engineName: string; @@ -219,8 +220,6 @@ export class GuaribasInstance extends Model @Column public adminPass: string; - /* Settings section of bot.json */ - @Column(DataType.FLOAT) public nlpVsSearch: number; @@ -239,6 +238,9 @@ export class GuaribasInstance extends Model public updatedAt: Date; } +/** + * Each packaged listed for use in a bot instance. + */ @Table export class GuaribasPackage extends Model { @PrimaryKey @@ -265,6 +267,9 @@ export class GuaribasPackage extends Model { public updatedAt: Date; } +/** + * A bot channel. + */ @Table export class GuaribasChannel extends Model { @PrimaryKey @@ -284,7 +289,11 @@ export class GuaribasChannel extends Model { public updatedAt: Date; } +/** + * An exception that has been thrown. + */ @Table +//tslint:disable-next-line:max-classes-per-file export class GuaribasException extends Model { @PrimaryKey @AutoIncrement diff --git a/packages/core.gbapp/services/GBAPIService.ts b/packages/core.gbapp/services/GBAPIService.ts index 03ddc01b..104caf5d 100644 --- a/packages/core.gbapp/services/GBAPIService.ts +++ b/packages/core.gbapp/services/GBAPIService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,11 +36,15 @@ import { TurnContext } from 'botbuilder'; import { WaterfallStepContext } from 'botbuilder-dialogs'; import { GBLog, GBMinInstance } from 'botlib'; import * as request from 'request-promise-native'; -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); import { GBAdminService } from '../../admin.gbapp/services/GBAdminService'; import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService'; import { GBDeployer } from './GBDeployer'; +/** + * @fileoverview General Bots server core. + */ + /** * BASIC system class for extra manipulation of bot behaviour. */ @@ -100,18 +104,18 @@ class SysClass { public async httpGet(url: string, qs) { const options = { - uri: UrlJoin(url , qs) + uri: urlJoin(url , qs) }; - return await request.get(options); + return request.get(options); } } -/** - * @fileoverview General Bots server core. - */ -export default class DialogClass { +/** + * Base services of conversation to be called by BASIC. + */ +export class DialogClass { public min: GBMinInstance; public context: TurnContext; diff --git a/packages/core.gbapp/services/GBConfigService.ts b/packages/core.gbapp/services/GBConfigService.ts index 0b13d92e..65875d85 100644 --- a/packages/core.gbapp/services/GBConfigService.ts +++ b/packages/core.gbapp/services/GBConfigService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -30,16 +30,30 @@ | | \*****************************************************************************/ -import * as fs from 'fs'; +'use strict'; + import { GBLog } from 'botlib'; /** * @fileoverview General Bots server core. */ -'use strict'; - +/** + * Base configuration for the server like storage. + */ export class GBConfigService { + + public static getServerPort(): number { + if (process.env.port !== undefined) { + return Number(process.env.port); + } + if (process.env.PORT !== undefined) { + return Number(process.env.PORT); + } + + return 4242; + } + public static init(): any { try { require('dotenv-extended').load({ @@ -57,7 +71,7 @@ export class GBConfigService { public static get(key: string): string | undefined { let value = GBConfigService.tryGet(key); - if (!value) { + if (value !== undefined) { switch (key) { case 'CLOUD_USERNAME': value = undefined; @@ -117,8 +131,8 @@ export class GBConfigService { } public static tryGet(key: string) { - let value = process.env['container:' + key]; - if (!value) { + let value = process.env[`container:${key}`]; + if (value !== undefined) { value = process.env[key]; } diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index e5e4c184..68024e3c 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | diff --git a/packages/core.gbapp/services/GBDeployer.ts b/packages/core.gbapp/services/GBDeployer.ts index 8d1d70b8..f954e338 100644 --- a/packages/core.gbapp/services/GBDeployer.ts +++ b/packages/core.gbapp/services/GBDeployer.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -37,22 +37,19 @@ 'use strict'; const Path = require('path'); -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); const Fs = require('fs'); const WaitUntil = require('wait-until'); const express = require('express'); const child_process = require('child_process'); const graph = require('@microsoft/microsoft-graph-client'); -import { GBMinInstance, IGBCoreService, IGBInstance, GBLog } from 'botlib'; -import { GBError, IGBPackage } from 'botlib'; +import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBInstance, IGBPackage } from 'botlib'; import { AzureSearch } from 'pragmatismo-io-framework'; -import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService'; -import { GuaribasInstance, GuaribasPackage } from '../models/GBModel'; +import { GuaribasPackage } from '../models/GBModel'; import { GBAdminService } from './../../admin.gbapp/services/GBAdminService'; import { KBService } from './../../kb.gbapp/services/KBService'; import { GBConfigService } from './GBConfigService'; -import { GBCoreService } from './GBCoreService'; import { GBImporter } from './GBImporterService'; import { GBVMService } from './GBVMService'; @@ -73,7 +70,7 @@ export class GBDeployer { } public static getConnectionStringFromInstance(instance: IGBInstance) { - return `Server=tcp:${instance.storageServer}.database.windows.net,1433;Database=${instance.storageName};User ID=${ + return `Server=tcp:torageServer}.database.windows.net,1433;Database=${instance.storageName};User ID=${ instance.storageUsername };Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`; } @@ -91,12 +88,12 @@ export class GBDeployer { let totalPackages = 0; const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH'); let paths = [GBDeployer.deployFolder]; - if (additionalPath) { + if (additionalPath !== undefined) { paths = paths.concat(additionalPath.toLowerCase().split(';')); } - const botPackages = new Array(); - const gbappPackages = new Array(); - let generalPackages = new Array(); + const botPackages: string[] = undefined; + const gbappPackages: string[] = undefined; + let generalPackages: string[]; function doIt(path) { const isDirectory = source => Fs.lstatSync(source).isDirectory(); @@ -138,7 +135,7 @@ export class GBDeployer { GBLog.info(`Waiting for app package deployment...`); cb(appPackagesProcessed === gbappPackages.length); }) - .done(async result => { + .done(async () => { GBLog.info(`App Package deployment done.`); ({ generalPackages, totalPackages } = await this.deployDataPackages( @@ -161,11 +158,9 @@ export class GBDeployer { */ public async deployBot(localPath: string): Promise { - const packageType = Path.extname(localPath); const packageName = Path.basename(localPath); - const instance = await this.importer.importIfNotExistsBotPackage(null, packageName, localPath); - return instance; + return await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath); } public async deployPackageToStorage(instanceId: number, packageName: string): Promise { @@ -175,7 +170,7 @@ export class GBDeployer { }); } - public async deployFromSharePoint(instanceId: number, path: string) { + public async deployFromSharePoint(instanceId: number) { const adminService = new GBAdminService(this.core); const accessToken = adminService.acquireElevatedToken(instanceId); @@ -183,59 +178,30 @@ export class GBDeployer { const client = graph.Client.init({ authProvider: done => { - done(null, accessToken); + done(undefined, accessToken); } }); - - const events = await client - .api('/me/events') - .select('subject,organizer,start,end') - .orderby('createdDateTime DESC') - .get(); } - public deployScriptToStorage(instanceId: number, localPath: string) {} - - public deployTheme(localPath: string) { - // DISABLED: Until completed, "/ui/public". - // FsExtra.copy(localPath, this.workDir + packageName) - // .then(() => { - // }) - // .catch(err => { - // var gberr = GBError.create( - // `GuaribasBusinessError: Error copying package: ${localPath}.` - // ) - // }) - } - - public async deployPackageFromSharePoint(min: GBMinInstance, path: string) {} - - public async deployPackageFromLocalPath(min: GBMinInstance, localPath: string) { + public async deployPackage(min: GBMinInstance, localPath: string) { const packageType = Path.extname(localPath); switch (packageType) { case '.gbot': return this.deployBot(localPath); - case '.gbtheme': - return this.deployTheme(localPath); - - // PACKAGE: Put in package logic. case '.gbkb': const service = new KBService(this.core.sequelize); return service.deployKb(this.core, this, localPath); - case '.gbui': - break; - case '.gbdialog': const vm = new GBVMService(); return vm.loadDialogPackage(localPath, min, this.core, this); default: - const err = GBError.create(`GuaribasBusinessError: Unknown package type: ${packageType}.`); + const err = GBError.create(`Unhandled package type: ${packageType}.`); Promise.reject(err); break; } @@ -248,14 +214,6 @@ export class GBDeployer { const p = await this.getPackageByName(instance.instanceId, packageName); switch (packageType) { - case '.gbot': - // TODO: this.undeployBot(packageName, localPath) - break; - - case '.gbtheme': - // TODO: this.undeployTheme(packageName, localPath) - break; - case '.gbkb': const service = new KBService(this.core.sequelize); @@ -268,7 +226,7 @@ export class GBDeployer { break; default: - const err = GBError.create(`GuaribasBusinessError: Unknown package type: ${packageType}.`); + const err = GBError.create(`Unhandled package type: ${packageType}.`); Promise.reject(err); break; } @@ -288,7 +246,7 @@ export class GBDeployer { try { await search.deleteDataSource(dsName); } catch (err) { - if (err.code != 404) { + if (err.code !== 404) { // First time, nothing to delete. throw err; } @@ -299,7 +257,7 @@ export class GBDeployer { try { await search.deleteIndex(); } catch (err) { - if (err.code != 404) { + if (err.code !== 404) { // First time, nothing to delete. throw err; } @@ -363,11 +321,11 @@ export class GBDeployer { if (Path.extname(filename) === '.gbapp' || Path.extname(filename) === '.gblib') { // Themes for bots. } else if (Path.extname(filename) === '.gbtheme') { - server.use('/themes/' + filenameOnly, express.static(filename)); - GBLog.info(`Theme (.gbtheme) assets accessible at: ${'/themes/' + filenameOnly}.`); + server.use(`/themes/${filenameOnly}`, express.static(filename)); + GBLog.info(`Theme (.gbtheme) assets accessible at: /themes/${filenameOnly}.`); } else if (Path.extname(filename) === '.gbkb') { - server.use('/kb/' + filenameOnly + '/subjects', express.static(UrlJoin(filename, 'subjects'))); - GBLog.info(`KB (.gbkb) assets accessible at: ${'/kb/' + filenameOnly}.`); + server.use(`/kb/${filenameOnly}/subjects`, express.static(urlJoin(filename, 'subjects'))); + GBLog.info(`KB (.gbkb) assets accessible at: /kb/${filenameOnly}.`); } else if (Path.extname(filename) === '.gbui') { // Already Handled } else if (Path.extname(filename) === '.gbdialog') { @@ -387,7 +345,7 @@ export class GBDeployer { GBLog.info(`Waiting for package deployment...`); cb(totalPackages === generalPackages.length); }) - .done(result => { + .done(() => { if (botPackages.length === 0) { GBLog.info('Use ADDITIONAL_DEPLOY_PATH to point to a .gbai package folder (no external packages).'); } else { diff --git a/packages/core.gbapp/services/GBImporterService.ts b/packages/core.gbapp/services/GBImporterService.ts index 515296dd..187d9c5b 100644 --- a/packages/core.gbapp/services/GBImporterService.ts +++ b/packages/core.gbapp/services/GBImporterService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,13 +36,14 @@ 'use strict'; -import { IGBCoreService, IGBInstance } from 'botlib'; +import { IGBCoreService } from 'botlib'; import fs = require('fs'); -import path = require('path'); -import UrlJoin = require('url-join'); -import { SecService } from '../../security.gblib/services/SecService'; +import urlJoin = require('url-join'); import { GuaribasInstance } from '../models/GBModel'; +/** + * Handles the importing of packages. + */ export class GBImporter { public core: IGBCoreService; @@ -51,25 +52,25 @@ export class GBImporter { } public async importIfNotExistsBotPackage(botId: string, packageName: string, localPath: string) { - const packageJson = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8')); - if (!botId) { + const packageJson = JSON.parse(fs.readFileSync(urlJoin(localPath, 'package.json'), 'utf8')); + if (botId !== undefined) { botId = packageJson.botId; } const instance = await this.core.loadInstance(botId); - if (instance) { + if (instance !== undefined) { return instance; } else { - return await this.createInstanceInternal(botId, packageName, localPath, packageJson); + return await this.createInstanceInternal(botId, localPath, packageJson); } } - private async createInstanceInternal(botId: string, packageName: string, localPath: string, packageJson: any) { - const settings = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'settings.json'), 'utf8')); - const servicesJson = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'services.json'), 'utf8')); + private async createInstanceInternal(botId: string, localPath: string, packageJson: any) { + const settings = JSON.parse(fs.readFileSync(urlJoin(localPath, 'settings.json'), 'utf8')); + const servicesJson = JSON.parse(fs.readFileSync(urlJoin(localPath, 'services.json'), 'utf8')); packageJson = { ...packageJson, ...settings, ...servicesJson }; - if (botId) { + if (botId !== undefined) { packageJson.botId = botId; } diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index fa6471c6..73f31f34 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -37,7 +37,7 @@ 'use strict'; const { DialogSet, TextPrompt } = require('botbuilder-dialogs'); -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); const express = require('express'); const request = require('request-promise-native'); @@ -46,20 +46,31 @@ const AuthenticationContext = require('adal-node').AuthenticationContext; import { AutoSaveStateMiddleware, BotFrameworkAdapter, ConversationState, MemoryStorage, UserState } from 'botbuilder'; import { ConfirmPrompt, WaterfallDialog } from 'botbuilder-dialogs'; -import { GBDialogStep, GBLog, GBMinInstance, IGBAdminService, IGBConversationalService, IGBCoreService, IGBInstance, IGBPackage } from 'botlib'; +import { + GBDialogStep, + GBLog, + GBMinInstance, + IGBAdminService, + IGBConversationalService, + IGBCoreService, + IGBInstance, + IGBPackage +} from 'botlib'; + import { GBAnalyticsPackage } from '../../analytics.gblib'; import { GBCorePackage } from '../../core.gbapp'; import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp'; import { GBKBPackage } from '../../kb.gbapp'; +import { AskDialogArgs } from '../../kb.gbapp/dialogs/AskDialog'; import { GBSecurityPackage } from '../../security.gblib'; import { GBWhatsappPackage } from '../../whatsapp.gblib'; -import { GuaribasInstance } from '../models/GBModel'; import { Messages } from '../strings'; import { GBAdminPackage } from './../../admin.gbapp/index'; import { GBDeployer } from './GBDeployer'; -/** Minimal service layer for a bot. */ - +/** + * Minimal service layer for a bot. + */ export class GBMinService { public core: IGBCoreService; public conversationalService: IGBConversationalService; @@ -94,7 +105,7 @@ export class GBMinService { * * @return Loaded minimal bot instance. * - * */ + */ public async buildMin( bootInstance: IGBInstance, @@ -106,7 +117,7 @@ export class GBMinService { // Serves default UI on root address '/'. const uiPackage = 'default.gbui'; - server.use('/', express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build'))); + server.use('/', express.static(urlJoin(GBDeployer.deployFolder, uiPackage, 'build'))); await Promise.all( instances.map(async instance => { @@ -129,7 +140,7 @@ export class GBMinService { // Install default VBA module. - deployer.deployPackageFromLocalPath(min, 'packages/default.gbdialog'); + deployer.deployPackage(min, 'packages/default.gbdialog'); // Call the loadBot context.activity for all packages. @@ -146,10 +157,9 @@ export class GBMinService { // Serves individual URL for each bot user interface. const uiUrl = `/${instance.botId}`; - server.use(uiUrl, express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, 'build'))); + server.use(uiUrl, express.static(urlJoin(GBDeployer.deployFolder, uiPackage, 'build'))); GBLog.info(`Bot UI ${uiPackage} accessible at: ${uiUrl}.`); - const state = `${instance.instanceId}${Math.floor(Math.random() * 1000000000)}`; // Clients get redirected here in order to create an OAuth authorize url and redirect them to AAD. // There they will authenticate and give their consent to allow this app access to @@ -175,12 +185,12 @@ export class GBMinService { throw new Error(msg); } const authenticationContext = new AuthenticationContext( - UrlJoin(min.instance.authenticatorAuthorityHostUrl, min.instance.authenticatorTenant) + urlJoin(min.instance.authenticatorAuthorityHostUrl, min.instance.authenticatorTenant) ); const resource = 'https://graph.microsoft.com'; authenticationContext.acquireTokenWithAuthorizationCode( req.query.code, - UrlJoin(instance.botEndpoint, min.instance.botId, '/token'), + urlJoin(instance.botEndpoint, min.instance.botId, '/token'), resource, instance.authenticatorClientId, instance.authenticatorClientSecret, @@ -193,7 +203,7 @@ export class GBMinService { await this.adminService.setValue(instance.instanceId, 'refreshToken', token.refreshToken); await this.adminService.setValue(instance.instanceId, 'accessToken', token.accessToken); await this.adminService.setValue(instance.instanceId, 'expiresOn', token.expiresOn.toString()); - await this.adminService.setValue(instance.instanceId, 'AntiCSRFAttackState', null); + await this.adminService.setValue(instance.instanceId, 'AntiCSRFAttackState', undefined); res.redirect(min.instance.botEndpoint); } } @@ -202,15 +212,15 @@ export class GBMinService { } private handleOAuthRequests(server: any, min: GBMinInstance) { - server.get(`/${min.instance.botId}/auth`, function(req, res) { - let authorizationUrl = UrlJoin( + server.get(`/${min.instance.botId}/auth`, (req, res) => { + let authorizationUrl = urlJoin( min.instance.authenticatorAuthorityHostUrl, min.instance.authenticatorTenant, '/oauth2/authorize' ); authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${ min.instance.authenticatorClientId - }&redirect_uri=${UrlJoin(min.instance.botEndpoint, min.instance.botId, 'token')}`; + }&redirect_uri=${urlJoin(min.instance.botEndpoint, min.instance.botId, 'token')}`; res.redirect(authorizationUrl); }); } @@ -224,10 +234,10 @@ export class GBMinService { botId = bootInstance.botId; } const instance = await this.core.loadInstance(botId); - if (instance) { + if (instance !== undefined) { const speechToken = await this.getSTSToken(instance); let theme = instance.theme; - if (!theme) { + if (theme !== undefined) { theme = 'default.gbtheme'; } res.send( @@ -284,7 +294,6 @@ export class GBMinService { * */ private async getSTSToken(instance: any) { - // TODO: Make dynamic: https://CHANGE.api.cognitive.microsoft.com/sts/v1.0 const options = { url: 'https://westus.api.cognitive.microsoft.com/sts/v1.0/issueToken', @@ -337,7 +346,7 @@ export class GBMinService { } private invokeLoadBot(appPackages: any[], min: GBMinInstance, server: any) { - const sysPackages = new Array(); + const sysPackages : IGBPackage[] = undefined; // NOTE: A semicolon is necessary before this line. [ GBCorePackage, @@ -354,7 +363,7 @@ export class GBMinService { if (sysPackage.name === 'GBWhatsappPackage') { const url = '/instances/:botId/whatsapp'; server.post(url, (req, res) => { - p['channel'].received(req, res); + (p as any).channel.received(req, res); }); } }, this); @@ -385,9 +394,8 @@ export class GBMinService { ) { await adapter.processActivity(req, res, async context => { // Get loaded user state - const state = await conversationState.get(context); const step = await min.dialogs.createContext(context); - step.context.activity.locale = 'en-US'; // TODO: Make dynamic. + step.context.activity.locale = 'en-US'; try { const user = await min.userProfile.get(context, {}); @@ -401,7 +409,7 @@ export class GBMinService { }); user.loaded = true; user.subjects = []; - user.cb = null; + user.cb = undefined; await min.userProfile.set(step.context, user); } @@ -433,8 +441,6 @@ export class GBMinService { } else if (context.activity.type === 'event') { // Empties dialog stack before going to the target. - // TODO: Understand MSFT changes: await step.endAll(); - await this.processEventActivity(context, step); } await conversationState.saveChanges(context, true); @@ -460,7 +466,7 @@ export class GBMinService { } else if (context.activity.name === 'showFAQ') { await step.beginDialog('/faq'); } else if (context.activity.name === 'answerEvent') { - await step.beginDialog('/answerEvent', { + await step.beginDialog('/answerEvent', { questionId: context.activity.data, fromFaq: true }); @@ -493,13 +499,11 @@ export class GBMinService { // Checks for /menu JSON signature. } else if (context.activity.text.startsWith('{"title"')) { - await step.beginDialog('/menu', { - data: JSON.parse(context.activity.text) - }); + await step.beginDialog('/menu', JSON.parse(context.activity.text)); // Otherwise, continue to the active dialog in the stack. } else { const user = await min.userProfile.get(context, {}); - if (step.activeDialog) { + if (step.activeDialog !== undefined) { await step.continueDialog(); } else { await step.beginDialog('/answer', { diff --git a/packages/core.gbapp/services/GBVMService.ts b/packages/core.gbapp/services/GBVMService.ts index 715fab13..68357f48 100644 --- a/packages/core.gbapp/services/GBVMService.ts +++ b/packages/core.gbapp/services/GBVMService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -41,8 +41,9 @@ import { TSCompiler } from './TSCompiler'; const walkPromise = require('walk-promise'); const vm = require('vm'); -import UrlJoin = require('url-join'); -import DialogClass from './GBAPIService'; +import urlJoin = require('url-join'); +import { DialogClass } from './GBAPIService'; +//tslint:disable-next-line:no-submodule-imports const vb2ts = require('vbscript-to-typescript/dist/converter'); const beautify = require('js-beautify').js; @@ -55,11 +56,13 @@ const beautify = require('js-beautify').js; * translation and enhance classic BASIC experience. */ +/** + * Basic services for BASIC manipulation. + */ export class GBVMService extends GBService { private readonly script = new vm.Script(); public async loadDialogPackage(folder: string, min: GBMinInstance, core: IGBCoreService, deployer: GBDeployer) { - const files = await walkPromise(folder); this.addHearDialog(min); @@ -74,7 +77,7 @@ export class GBVMService extends GBService { const mainName = file.name.replace(/\-|\./g, ''); min.scriptMap[file.name] = mainName; - const filename = UrlJoin(folder, file.name); + const filename = urlJoin(folder, file.name); fs.watchFile(filename, async () => { await this.run(filename, min, deployer, mainName); }); @@ -131,7 +134,7 @@ export class GBVMService extends GBService { // Converts General Bots BASIC into regular VBS const basicCode: string = fs.readFileSync(filename, 'utf8'); - const vbsCode = await this.convertGBASICToVBS(basicCode); + const vbsCode = this.convertGBASICToVBS(basicCode); const vbsFile = `${filename}.compiled`; fs.writeFileSync(vbsFile, vbsCode, 'utf8'); @@ -160,9 +163,9 @@ export class GBVMService extends GBService { let parsedCode = code; const hearExp = /(\w+).*hear.*\(\)/; - let match1; + let match1 = hearExp.exec(code); - while ((match1 = hearExp.exec(code))) { + while (match1 !== undefined) { let pos = 0; // Writes async body. @@ -182,8 +185,9 @@ export class GBVMService extends GBService { let right = 0; let left = 1; - let match2; - while ((match2 = /\{|\}/.exec(tempCode))) { + let match2 = /\{|\}/.exec(tempCode); + + while (match2 !== undefined) { const c = tempCode.substring(match2.index, match2.index + 1); if (c === '}') { @@ -198,6 +202,7 @@ export class GBVMService extends GBService { if (left === right) { break; } + match1 = hearExp.exec(code); } parsedCode += code.substring(start + match1[0].length + 1, pos + match1[0].length); @@ -207,6 +212,7 @@ export class GBVMService extends GBService { // A interaction will be made for each hear. code = parsedCode; + match2 = /\{|\}/.exec(tempCode); } parsedCode = this.handleThisAndAwait(parsedCode); @@ -218,7 +224,6 @@ export class GBVMService extends GBService { const context = vm.createContext(sandbox); vm.runInContext(parsedCode, context); min.sandBoxMap[mainName] = sandbox; - await deployer.deployScriptToStorage(1, filename); // TODO: Per bot storage. GBLog.info(`[GBVMService] Finished loading of ${filename}`); } } @@ -228,13 +233,13 @@ export class GBVMService extends GBService { code = code.replace(/sys\(\)/g, 'this.sys()'); code = code.replace(/("[^"]*"|'[^']*')|\btalk\b/g, ($0, $1) => { - return $1 == undefined ? 'this.talk' : $1; + return $1 === undefined ? 'this.talk' : $1; }); code = code.replace(/("[^"]*"|'[^']*')|\bhear\b/g, ($0, $1) => { - return $1 == undefined ? 'this.hear' : $1; + return $1 === undefined ? 'this.hear' : $1; }); code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/g, ($0, $1) => { - return $1 == undefined ? 'this.sendEmail' : $1; + return $1 === undefined ? 'this.sendEmail' : $1; }); // await insertion. @@ -249,7 +254,7 @@ export class GBVMService extends GBService { min.dialogs.add( new WaterfallDialog('/hear', [ async step => { - step.activeDialog.state.cbId = step.options['id']; + step.activeDialog.state.cbId = (step.options as any).id; return await step.prompt('textPrompt', {}); }, @@ -259,7 +264,7 @@ export class GBVMService extends GBService { const cbId = step.activeDialog.state.cbId; const cb = min.cbMap[cbId]; - cb.bind({ step: step, context: step.context }); // TODO: Necessary or min.sandbox? + cb.bind({ step: step, context: step.context }); await step.endDialog(); diff --git a/packages/core.gbapp/services/TSCompiler.ts b/packages/core.gbapp/services/TSCompiler.ts index 7d5185e8..00ccc045 100644 --- a/packages/core.gbapp/services/TSCompiler.ts +++ b/packages/core.gbapp/services/TSCompiler.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,9 +36,12 @@ 'use strict'; -import * as ts from 'typescript'; import { GBLog } from 'botlib'; +import * as ts from 'typescript'; +/** + * Wrapper for a TypeScript compiler. + */ export class TSCompiler { private static shouldIgnoreError(diagnostic) { @@ -75,7 +78,7 @@ export class TSCompiler { if (!TSCompiler.shouldIgnoreError(diagnostic)) { const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); - if (diagnostic.file) { + if (diagnostic.file !== undefined) { const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); GBLog.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { diff --git a/packages/core.gbapp/tests/core.test.ts b/packages/core.gbapp/tests/core.test.ts index 838d5f2d..00da8ce8 100644 --- a/packages/core.gbapp/tests/core.test.ts +++ b/packages/core.gbapp/tests/core.test.ts @@ -1,13 +1,9 @@ - import { expect } from 'chai'; -import 'mocha'; -import {GBImporter} from '../services/GBImporterService'; +import { GBImporter } from '../services/GBImporterService'; describe('Hello function', () => { - it('should return empty test', () => { - const service = new GBImporter(null); - //service.importIfNotExistsBotPackage(null, null); + const service = new GBImporter(undefined); const result = 0; expect(result).to.equal(0); }); diff --git a/packages/core.gbapp/tests/vm.test.ts b/packages/core.gbapp/tests/vm.test.ts index 1be437b2..67ecffeb 100644 --- a/packages/core.gbapp/tests/vm.test.ts +++ b/packages/core.gbapp/tests/vm.test.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -42,9 +42,7 @@ import { GBVMService } from '../services/GBVMService'; describe('Load function', () => { it('should fail on invalid file', () => { try { - // const service = new GBVMService(); - // TODO: service.loadJS('invalid.file', null, null, null, null); - + const service = new GBVMService(); } catch (error) { expect(error).to.equal(0); } diff --git a/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts b/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts index 96cdd6e7..b5ce198d 100644 --- a/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts +++ b/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -38,12 +38,14 @@ import { BotAdapter } from 'botbuilder'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { GBMinInstance } from 'botlib'; -import { IGBDialog } from 'botlib'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { AzureText } from 'pragmatismo-io-framework'; import { CSService } from '../services/CSService'; import { Messages } from '../strings'; +/** + * Dialog for feedback collecting. + */ export class FeedbackDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -59,13 +61,6 @@ export class FeedbackDialog extends IGBDialog { async step => { const locale = step.context.activity.locale; - // TODO: Migrate to 4.*+ await step.prompt("choicePrompt", Messages[locale].what_about_me, [ - // "1", - // "2", - // "3", - // "4", - // "5" - // ]); return await step.next(); }, async step => { @@ -86,30 +81,26 @@ export class FeedbackDialog extends IGBDialog { const locale = step.context.activity.locale; await step.context.sendActivity(Messages[locale].about_suggestions); - step.activeDialog.state.cbId = step.options['id']; + step.activeDialog.state.cbId = (step.options as any).id; return await step.prompt('textPrompt', Messages[locale].what_about_service); }, async step => { - const locale = step.context.activity.locale; const rate = await AzureText.getSentiment( - min.instance.textAnalyticsKey, - min.instance.textAnalyticsEndpoint, - min.conversationalService.getCurrentLanguage(step), - step.result + min.instance.textAnalyticsKey, + min.instance.textAnalyticsEndpoint, + min.conversationalService.getCurrentLanguage(step), + step.result ); if (rate > 0.5) { await step.context.sendActivity(Messages[locale].glad_you_liked); } else { await step.context.sendActivity(Messages[locale].we_will_improve); - - // TODO: Record. - } + } return await step.replaceDialog('/ask', { isReturning: true }); - } ]) ); diff --git a/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts b/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts index 09b962fd..b9c4ce5e 100644 --- a/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts +++ b/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,14 +36,16 @@ 'use strict'; -import { IGBDialog } from 'botlib'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { BotAdapter } from 'botbuilder'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { GBMinInstance } from 'botlib'; import { CSService } from '../services/CSService'; import { Messages } from '../strings'; +/** + * Dialog for collecting quality of answer. + */ export class QualityDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -62,11 +64,11 @@ export class QualityDialog extends IGBDialog { const score = step.result; setTimeout( - () => min.conversationalService.sendEvent(step, 'stop', null), + () => min.conversationalService.sendEvent(step, 'stop', undefined), 400 ); - if (score == 0) { + if (score === 0) { await step.context.sendActivity(Messages[locale].im_sorry_lets_try); } else { await step.context.sendActivity(Messages[locale].great_thanks); diff --git a/packages/customer-satisfaction.gbapp/index.ts b/packages/customer-satisfaction.gbapp/index.ts index 3850b5d9..052e1ac9 100644 --- a/packages/customer-satisfaction.gbapp/index.ts +++ b/packages/customer-satisfaction.gbapp/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,16 +36,19 @@ 'use strict'; -import { GBMinInstance, IGBCoreService, IGBPackage, GBLog, GBDialogStep } from 'botlib'; -import UrlJoin = require('url-join'); +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; +import urlJoin = require('url-join'); import { FeedbackDialog } from './dialogs/FeedbackDialog'; import { QualityDialog } from './dialogs/QualityDialog'; import { GuaribasQuestionAlternate } from './models/index'; import { Sequelize } from 'sequelize-typescript'; +/** + * Package for customer-satisfaction.gblib. + */ export class GBCustomerSatisfactionPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public getDialogs(min: GBMinInstance) { GBLog.verbose(`getDialogs called.`); } diff --git a/packages/customer-satisfaction.gbapp/models/index.ts b/packages/customer-satisfaction.gbapp/models/index.ts index afcd21e8..f6298e52 100644 --- a/packages/customer-satisfaction.gbapp/models/index.ts +++ b/packages/customer-satisfaction.gbapp/models/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,33 +36,20 @@ 'use strict'; -import { - DataTypeDate, - DataTypeDecimal, - DataTypes, - DataTypeUUIDv4 -} from 'sequelize'; - import { AutoIncrement, BelongsTo, - BelongsToMany, Column, - CreatedAt, - DataType, ForeignKey, - HasMany, - IsUUID, - Length, Model, PrimaryKey, - Sequelize, - Table, - UpdatedAt -} from 'sequelize-typescript'; + Table} from 'sequelize-typescript'; import { GuaribasInstance } from '../../core.gbapp/models/GBModel'; +/** + * List of saved alternate questions. + */ @Table export class GuaribasQuestionAlternate extends Model { diff --git a/packages/customer-satisfaction.gbapp/services/CSService.ts b/packages/customer-satisfaction.gbapp/services/CSService.ts index 0a8b424c..4ef113e9 100644 --- a/packages/customer-satisfaction.gbapp/services/CSService.ts +++ b/packages/customer-satisfaction.gbapp/services/CSService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -33,6 +33,9 @@ import { GuaribasConversation } from '../../analytics.gblib/models'; import { GuaribasQuestionAlternate } from '../models'; +/** + * Customer Satisfaction Service Layer. + */ export class CSService { public async resolveQuestionAlternate( diff --git a/packages/default.gbui/public/css/pragmatismo.css b/packages/default.gbui/public/css/pragmatismo.css index 7f415475..f258e644 100644 --- a/packages/default.gbui/public/css/pragmatismo.css +++ b/packages/default.gbui/public/css/pragmatismo.css @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/public/index.html b/packages/default.gbui/public/index.html index afca6481..b7d3c364 100644 --- a/packages/default.gbui/public/index.html +++ b/packages/default.gbui/public/index.html @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/GBUIApp.js b/packages/default.gbui/src/GBUIApp.js index 588ac9fe..20df55b4 100644 --- a/packages/default.gbui/src/GBUIApp.js +++ b/packages/default.gbui/src/GBUIApp.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/components/ChatPane.js b/packages/default.gbui/src/components/ChatPane.js index abe17888..d77961a2 100644 --- a/packages/default.gbui/src/components/ChatPane.js +++ b/packages/default.gbui/src/components/ChatPane.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/components/Footer.js b/packages/default.gbui/src/components/Footer.js index 0cfaa9b2..09b149af 100644 --- a/packages/default.gbui/src/components/Footer.js +++ b/packages/default.gbui/src/components/Footer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/components/GBCss.js b/packages/default.gbui/src/components/GBCss.js index c5dc69f1..09ba58ee 100644 --- a/packages/default.gbui/src/components/GBCss.js +++ b/packages/default.gbui/src/components/GBCss.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/components/NavBar.js b/packages/default.gbui/src/components/NavBar.js index 6c2e49eb..2a8a00e0 100644 --- a/packages/default.gbui/src/components/NavBar.js +++ b/packages/default.gbui/src/components/NavBar.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/components/SidebarMenu.js b/packages/default.gbui/src/components/SidebarMenu.js index fda919d2..43fa3ee2 100644 --- a/packages/default.gbui/src/components/SidebarMenu.js +++ b/packages/default.gbui/src/components/SidebarMenu.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/index.js b/packages/default.gbui/src/index.js index 6d320a9c..9c82fac3 100644 --- a/packages/default.gbui/src/index.js +++ b/packages/default.gbui/src/index.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/players/GBBulletPlayer.js b/packages/default.gbui/src/players/GBBulletPlayer.js index 46cabc34..48304c27 100644 --- a/packages/default.gbui/src/players/GBBulletPlayer.js +++ b/packages/default.gbui/src/players/GBBulletPlayer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/players/GBImagePlayer.js b/packages/default.gbui/src/players/GBImagePlayer.js index 6e337985..f2f3a54d 100644 --- a/packages/default.gbui/src/players/GBImagePlayer.js +++ b/packages/default.gbui/src/players/GBImagePlayer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/players/GBLoginPlayer.js b/packages/default.gbui/src/players/GBLoginPlayer.js index c5ed0fbd..4274c55a 100644 --- a/packages/default.gbui/src/players/GBLoginPlayer.js +++ b/packages/default.gbui/src/players/GBLoginPlayer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/players/GBMarkdownPlayer.js b/packages/default.gbui/src/players/GBMarkdownPlayer.js index 90d0efd7..5b108107 100644 --- a/packages/default.gbui/src/players/GBMarkdownPlayer.js +++ b/packages/default.gbui/src/players/GBMarkdownPlayer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/players/GBPowerBIPlayer.js b/packages/default.gbui/src/players/GBPowerBIPlayer.js index 284c65f0..ad30195c 100644 --- a/packages/default.gbui/src/players/GBPowerBIPlayer.js +++ b/packages/default.gbui/src/players/GBPowerBIPlayer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/default.gbui/src/players/GBVideoPlayer.js b/packages/default.gbui/src/players/GBVideoPlayer.js index e10c279f..8de4dcd0 100644 --- a/packages/default.gbui/src/players/GBVideoPlayer.js +++ b/packages/default.gbui/src/players/GBVideoPlayer.js @@ -2,14 +2,14 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | | | | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | -| | +| | | According to our dual licensing model, this program can be used either | | under the terms of the GNU Affero General Public License, version 3, | | or under a proprietary license. | diff --git a/packages/kb.gbapp/dialogs/AskDialog.ts b/packages/kb.gbapp/dialogs/AskDialog.ts index 5be2cace..e940d97c 100644 --- a/packages/kb.gbapp/dialogs/AskDialog.ts +++ b/packages/kb.gbapp/dialogs/AskDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -38,12 +38,22 @@ import { BotAdapter } from 'botbuilder'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { IGBDialog, GBLog } from 'botlib'; -import { GBMinInstance } from 'botlib'; +import { GBLog, GBMinInstance, IGBDialog } from 'botlib'; import { AzureText } from 'pragmatismo-io-framework'; import { Messages } from '../strings'; import { KBService } from './../services/KBService'; +/** + * Dialog arguments. + */ +export class AskDialogArgs { + public questionId: number; + public fromFaq: boolean; +} + +/** + * Handle the ask loop on knowledge base data or delegate to other services. + */ export class AskDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -53,159 +63,135 @@ export class AskDialog extends IGBDialog { */ public static setup(bot: BotAdapter, min: GBMinInstance) { const service = new KBService(min.core.sequelize); + min.dialogs.add(new WaterfallDialog('/answerEvent', AskDialog.getAnswerEventDialog(service, min))); + min.dialogs.add(new WaterfallDialog('/answer', AskDialog.getAnswerDialog(min, service))); + min.dialogs.add(new WaterfallDialog('/ask', AskDialog.getAskDialog(min))); + } - min.dialogs.add( - new WaterfallDialog('/answerEvent', [ - async step => { - if (step.options && step.options['questionId']) { - const question = await service.getQuestionById(min.instance.instanceId, step.options['questionId']); - const answer = await service.getAnswerById(min.instance.instanceId, question.answerId); - - // Sends the answer to all outputs, including projector. - - await service.sendAnswer(min.conversationalService, step, answer); - - await step.replaceDialog('/ask', { isReturning: true }); - } + private static getAskDialog(min: GBMinInstance) { + return [ + async step => { + const locale = step.context.activity.locale; + const user = await min.userProfile.get(step.context, {}); + user.isAsking = true; + if (!user.subjects) { + user.subjects = []; + } + let text; + // Three forms of asking. + if (step.options && step.options.firstTime) { + text = Messages[locale].ask_first_time; + } else if (step.options && step.options.isReturning) { + text = Messages[locale].anything_else; + } else if (user.subjects.length > 0) { + text = Messages[locale].which_question; + } else { + throw new Error('Invalid use of /ask'); + } + if (text.length > 0) { + return await step.prompt('textPrompt', text); + } + return await step.next(); + }, + async step => { + if (step.result) { + return await step.replaceDialog('/answer', { query: step.result }); + } else { return await step.next(); } - ]) - ); + } + ]; + } - min.dialogs.add( - new WaterfallDialog('/answer', [ - async step => { - const user = await min.userProfile.get(step.context, {}); - let text = step.options['query']; - if (!text) { - throw new Error(`/answer being called with no args query text.`); + private static getAnswerDialog(min: GBMinInstance, service: KBService) { + return [ + async step => { + const user = await min.userProfile.get(step.context, {}); + let text = step.options.query; + if (!text) { + throw new Error(`/answer being called with no args query text.`); + } + const locale = step.context.activity.locale; + // Stops any content on projector. + await min.conversationalService.sendEvent(step, 'stop', undefined); + // Handle extra text from FAQ. + if (step.options && step.options.query) { + text = step.options.query; + } else if (step.options && step.options.fromFaq) { + await step.context.sendActivity(Messages[locale].going_answer); + } + // Spells check the input text before sending Search or NLP. + if (min.instance.spellcheckerKey !== undefined) { + const data = await AzureText.getSpelledText(min.instance.spellcheckerKey, text); + if (data !== text) { + GBLog.info(`Spelling corrected: ${data}`); + text = data; } + } - const locale = step.context.activity.locale; + // Searches KB for the first time. + user.lastQuestion = text; + await min.userProfile.set(step.context, user); + const resultsA = await service.ask(min.instance, text, min.instance.searchScore, user.subjects); - // Stops any content on projector. - - await min.conversationalService.sendEvent(step, 'stop', null); - - // Handle extra text from FAQ. - - if (step.options && step.options['query']) { - text = step.options['query']; - } else if (step.options && step.options['fromFaq']) { - await step.context.sendActivity(Messages[locale].going_answer); - } - - // Spells check the input text before sending Search or NLP. - - if (min.instance.spellcheckerKey) { - const data = await AzureText.getSpelledText(min.instance.spellcheckerKey, text); - - if (data != text) { - GBLog.info(`Spelling corrected: ${data}`); - text = data; - } - } - - // Searches KB for the first time. - - user.lastQuestion = text; + // If there is some result, answer immediately. + if (resultsA !== undefined && resultsA.answer !== undefined) { + // Saves some context info. + user.isAsking = false; + user.lastQuestionId = resultsA.questionId; await min.userProfile.set(step.context, user); - const resultsA = await service.ask(min.instance, text, min.instance.searchScore, user.subjects); + // Sends the answer to all outputs, including projector. + await service.sendAnswer(min.conversationalService, step, resultsA.answer); + + // Goes to ask loop, again. + return await step.replaceDialog('/ask', { isReturning: true }); + } else { + // Second time running Search, now with no filter. + const resultsB = await service.ask(min.instance, text, min.instance.searchScore, undefined); // If there is some result, answer immediately. - if (resultsA && resultsA.answer) { + if (resultsB !== undefined && resultsB.answer !== undefined) { // Saves some context info. - - user.isAsking = false; - user.lastQuestionId = resultsA.questionId; - await min.userProfile.set(step.context, user); - + const user2 = await min.userProfile.get(step.context, {}); + user2.isAsking = false; + user2.lastQuestionId = resultsB.questionId; + await min.userProfile.set(step.context, user2); + // Informs user that a broader search will be used. + if (user2.subjects.length > 0) { + await step.context.sendActivity(Messages[locale].wider_answer); + } // Sends the answer to all outputs, including projector. - - await service.sendAnswer(min.conversationalService, step, resultsA.answer); - - // Goes to ask loop, again. + await service.sendAnswer(min.conversationalService, step, resultsB.answer); return await step.replaceDialog('/ask', { isReturning: true }); } else { - // Second time running Search, now with no filter. - - const resultsB = await service.ask(min.instance, text, min.instance.searchScore, null); - - // If there is some result, answer immediately. - - if (resultsB && resultsB.answer) { - // Saves some context info. - - const user = await min.userProfile.get(step.context, {}); - user.isAsking = false; - user.lastQuestionId = resultsB.questionId; - await min.userProfile.set(step.context, user); - - // Informs user that a broader search will be used. - - if (user.subjects.length > 0) { - const subjectText = `${KBService.getSubjectItemsSeparatedBySpaces(user.subjects)}`; - await step.context.sendActivity(Messages[locale].wider_answer); - } - - // Sends the answer to all outputs, including projector. - - await service.sendAnswer(min.conversationalService, step, resultsB.answer); + if (!(await min.conversationalService.routeNLP(step, min, text))) { + await step.context.sendActivity(Messages[locale].did_not_find); return await step.replaceDialog('/ask', { isReturning: true }); - } else { - if (!(await min.conversationalService.routeNLP(step, min, text))) { - await step.context.sendActivity(Messages[locale].did_not_find); - - return await step.replaceDialog('/ask', { isReturning: true }); - } } } } - ]) - ); + } + ]; + } - min.dialogs.add( - new WaterfallDialog('/ask', [ - async step => { - const locale = step.context.activity.locale; - const user = await min.userProfile.get(step.context, {}); - user.isAsking = true; - if (!user.subjects) { - user.subjects = []; - } - let text; - - // Three forms of asking. - - if (step.options && step.options['firstTime'] ) { - text = Messages[locale].ask_first_time; - } else if (step.options && step.options['isReturning']) { - text = Messages[locale].anything_else; - } else if (user.subjects.length > 0) { - text = Messages[locale].which_question; - } else { - throw new Error('Invalid use of /ask'); - } - - if (text.length > 0) { - return await step.prompt('textPrompt', text); - } - - return await step.next(); - }, - async step => { - if (step.result) { - return await step.replaceDialog('/answer', { query: step.result }); - } else { - return await step.next(); - } + private static getAnswerEventDialog(service: KBService, min: GBMinInstance) { + return [ + async step => { + const data = step.options as AskDialogArgs; + if (data !== undefined && data.questionId !== undefined) { + const question = await service.getQuestionById(min.instance.instanceId, data.questionId); + const answer = await service.getAnswerById(min.instance.instanceId, question.answerId); + // Sends the answer to all outputs, including projector. + await service.sendAnswer(min.conversationalService, step, answer); + await step.replaceDialog('/ask', { isReturning: true }); } - ]) - ); + return await step.next(); + } + ]; } } diff --git a/packages/kb.gbapp/dialogs/FaqDialog.ts b/packages/kb.gbapp/dialogs/FaqDialog.ts index f2c18ebb..448d8b33 100644 --- a/packages/kb.gbapp/dialogs/FaqDialog.ts +++ b/packages/kb.gbapp/dialogs/FaqDialog.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -38,11 +38,13 @@ import { BotAdapter } from 'botbuilder'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { IGBDialog } from 'botlib'; -import { GBMinInstance } from 'botlib'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { Messages } from '../strings'; import { KBService } from './../services/KBService'; +/** + * Handle display of FAQ allowing direct access to KB. + */ export class FaqDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -56,9 +58,9 @@ export class FaqDialog extends IGBDialog { min.dialogs.add(new WaterfallDialog('/faq', [ async step => { - const data = await service.getFaqBySubjectArray('faq', null); + const data = await service.getFaqBySubjectArray('faq', undefined); const locale = step.context.activity.locale; - if (data) { + if (data !== undefined) { await min.conversationalService.sendEvent(step, 'play', { playerType: 'bullet', data: data.slice(0, 10) diff --git a/packages/kb.gbapp/dialogs/MenuDialog.ts b/packages/kb.gbapp/dialogs/MenuDialog.ts index b020c189..9904fedc 100644 --- a/packages/kb.gbapp/dialogs/MenuDialog.ts +++ b/packages/kb.gbapp/dialogs/MenuDialog.ts @@ -1,9 +1,8 @@ - /*****************************************************************************\ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -37,17 +36,26 @@ 'use strict'; -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); import { BotAdapter, CardFactory, MessageFactory } from 'botbuilder'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { IGBDialog } from 'botlib'; -import { GBMinInstance } from 'botlib'; -import { AzureText } from 'pragmatismo-io-framework'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { GuaribasSubject } from '../models'; import { KBService } from '../services/KBService'; import { Messages } from '../strings'; +/** + * Dialog arguments. + */ +export class MenuDialogArgs { + public to: string; + public subjectId: string; +} + +/** + * Dialogs for handling Menu control. + */ export class MenuDialog extends IGBDialog { /** * Setup dialogs flows and define services call. @@ -58,71 +66,54 @@ export class MenuDialog extends IGBDialog { public static setup(bot: BotAdapter, min: GBMinInstance) { const service = new KBService(min.core.sequelize); - min.dialogs.add(new WaterfallDialog('/menu', [ + min.dialogs.add(new WaterfallDialog('/menu', MenuDialog.getMenuDialog(min, service))); + } + + private static getMenuDialog(min: GBMinInstance, service: KBService) { + return [ async step => { const locale = step.context.activity.locale; - let rootSubjectId = null; + const user = await min.userProfile.get(step.context, {}); + const args: MenuDialogArgs = step.options; - if (step.options && step.options['data']) { - const subject = step.options ['data']; + let rootSubjectId; + if (args !== undefined) { // If there is a shortcut specified as subject destination, go there. + if (args.to !== undefined) { + const dialog = args.to.split(':')[1]; - if (subject.to) { - const dialog = subject.to.split(':')[1]; - await step.replaceDialog('/' + dialog); - await step.endDialog(); - - return; + return await step.replaceDialog(`/${dialog}`); } - // Adds to bot a perception of a new subject. - - const user = await min.userProfile.get(step.context, {}); - user.subjects.push(subject); - rootSubjectId = subject.subjectId; + user.subjects.push(args); + rootSubjectId = args.subjectId; // Whenever a subject is selected, shows a faq about it. - if (user.subjects.length > 0) { - const data = await service.getFaqBySubjectArray( - 'menu', - user.subjects - ); + const list = await service.getFaqBySubjectArray('menu', user.subjects); await min.conversationalService.sendEvent(step, 'play', { playerType: 'bullet', - data: data.slice(0, 10) + data: list.slice(0, 10) }); } } else { - const user = await min.userProfile.get(step.context, {}); user.subjects = []; - - await step.context.sendActivity(Messages[locale].here_is_subjects); // TODO: Handle rnd. + await step.context.sendActivity(Messages[locale].here_is_subjects); user.isAsking = false; } - const msg = MessageFactory.text(''); const attachments = []; - - const data = await service.getSubjectItems( - min.instance.instanceId, - rootSubjectId - ); - + const data = await service.getSubjectItems(min.instance.instanceId, rootSubjectId); msg.attachmentLayout = 'carousel'; - - data.forEach(function(item: GuaribasSubject) { + data.forEach((item: GuaribasSubject) => { const subject = item; const card = CardFactory.heroCard( subject.title, subject.description, - CardFactory.images([ - UrlJoin('/kb', min.instance.kb, 'subjects', 'subject.png') - ]), + CardFactory.images([urlJoin('/kb', min.instance.kb, 'subjects', 'subject.png')]), CardFactory.actions([ - { - channelData: null, + { type: 'postBack', title: Messages[locale].menu_select, value: JSON.stringify({ @@ -135,31 +126,23 @@ export class MenuDialog extends IGBDialog { } ]) ); - attachments.push(card); }); - if (attachments.length === 0) { - const user = await min.userProfile.get(step.context, {}); if (user.subjects && user.subjects.length > 0) { await step.context.sendActivity( - Messages[locale].lets_search( - KBService.getFormattedSubjectItems(user.subjects) - ) + Messages[locale].lets_search(KBService.getFormattedSubjectItems(user.subjects)) ); } - } else { msg.attachments = attachments; await step.context.sendActivity(msg); } - - const user = await min.userProfile.get(step.context, {}); user.isAsking = true; return await step.next(); } - ])); + ]; } } diff --git a/packages/kb.gbapp/index.ts b/packages/kb.gbapp/index.ts index 628c035e..9e727fd1 100644 --- a/packages/kb.gbapp/index.ts +++ b/packages/kb.gbapp/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,19 +36,18 @@ 'use strict'; -import UrlJoin = require('url-join'); - -import { GBDialogStep, GBLog, GBMinInstance, IGBPackage } from 'botlib'; -import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from './models/index'; - -import { IGBCoreService } from 'botlib'; +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; import { AskDialog } from './dialogs/AskDialog'; import { FaqDialog } from './dialogs/FaqDialog'; import { MenuDialog } from './dialogs/MenuDialog'; +import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from './models/index'; +/** + * Package for kb.gbapp. + */ export class GBKBPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public getDialogs(min: GBMinInstance) { GBLog.verbose(`getDialogs called.`); } diff --git a/packages/kb.gbapp/models/index.ts b/packages/kb.gbapp/models/index.ts index df86b844..913c9df5 100644 --- a/packages/kb.gbapp/models/index.ts +++ b/packages/kb.gbapp/models/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -60,6 +60,9 @@ import { } from '../../core.gbapp/models/GBModel'; import { GuaribasUser } from '../../security.gblib/models'; +/** + * Subjects to group the pair of questions and answers. + */ @Table export class GuaribasSubject extends Model { @PrimaryKey @@ -111,6 +114,9 @@ export class GuaribasSubject extends Model { public package: GuaribasPackage; } +/** + * A question and its metadata. + */ @Table export class GuaribasQuestion extends Model { @PrimaryKey @@ -155,6 +161,7 @@ export class GuaribasQuestion extends Model { @UpdatedAt public updatedAt: Date; + //tslint:disable-next-line:no-use-before-declare @ForeignKey(() => GuaribasAnswer) @Column public answerId: number; @@ -174,6 +181,9 @@ export class GuaribasQuestion extends Model { public package: GuaribasPackage; } +/** + * An answer and its metadata. + */ @Table export class GuaribasAnswer extends Model { @PrimaryKey diff --git a/packages/kb.gbapp/services/KBService.ts b/packages/kb.gbapp/services/KBService.ts index 70250f14..7b581b8f 100644 --- a/packages/kb.gbapp/services/KBService.ts +++ b/packages/kb.gbapp/services/KBService.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,14 +36,13 @@ const Path = require('path'); const Fs = require('fs'); -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); const marked = require('marked'); const path = require('path'); const asyncPromise = require('async-promises'); const walkPromise = require('walk-promise'); -// tslint:disable:no-unsafe-any +// tslint:disable-next-line:newline-per-chained-call const parse = require('bluebird').promisify(require('csv-parse')); -// tslint:enable:no-unsafe-any import { GBDialogStep, GBLog, IGBConversationalService, IGBCoreService, IGBInstance } from 'botlib'; import { AzureSearch } from 'pragmatismo-io-framework'; @@ -275,7 +274,7 @@ export class KBService { // Extracts answer from external media if any. if (answer.indexOf('.md') > -1) { - const mediaFilename = UrlJoin(path.dirname(filePath), '..', 'articles', answer); + const mediaFilename = urlJoin(path.dirname(filePath), '..', 'articles', answer); if (Fs.existsSync(mediaFilename)) { answer = Fs.readFileSync(mediaFilename, 'utf8'); format = '.md'; @@ -393,7 +392,7 @@ export class KBService { ): Promise { // Imports subjects tree into database and return it. - await this.importSubjectFile(packageStorage.packageId, UrlJoin(localPath, 'subjects.json'), instance); + await this.importSubjectFile(packageStorage.packageId, urlJoin(localPath, 'subjects.json'), instance); // Import all .tsv files in the tabular directory. @@ -401,12 +400,12 @@ export class KBService { } public async importKbTabularDirectory(localPath: string, instance: IGBInstance, packageId: number): Promise { - const files = await walkPromise(UrlJoin(localPath, 'tabular')); + const files = await walkPromise(urlJoin(localPath, 'tabular')); return Promise.all( files.map(async file => { if (file.name.endsWith('.tsv')) { - return this.importKbTabularFile(UrlJoin(file.root, file.name), instance.instanceId, packageId); + return this.importKbTabularFile(urlJoin(file.root, file.name), instance.instanceId, packageId); } }) ); @@ -465,7 +464,7 @@ export class KBService { const packageType = Path.extname(localPath); const packageName = Path.basename(localPath); GBLog.info(`[GBDeployer] Opening package: ${localPath}`); - const packageObject = JSON.parse(Fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8')); + const packageObject = JSON.parse(Fs.readFileSync(urlJoin(localPath, 'package.json'), 'utf8')); const instance = await core.loadInstance(packageObject.botId); GBLog.info(`[GBDeployer] Importing: ${localPath}`); diff --git a/packages/security.gblib/index.ts b/packages/security.gblib/index.ts index cd54966f..6c589138 100644 --- a/packages/security.gblib/index.ts +++ b/packages/security.gblib/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,15 +36,18 @@ 'use strict'; -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from './models'; +/** + * Package for the security module. + */ export class GBSecurityPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public getDialogs(min: GBMinInstance) { GBLog.verbose(`getDialogs called.`); } diff --git a/packages/security.gblib/models/index.ts b/packages/security.gblib/models/index.ts index 784e8c97..e5e0e924 100644 --- a/packages/security.gblib/models/index.ts +++ b/packages/security.gblib/models/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -63,6 +63,9 @@ import { import { GuaribasInstance } from '../../core.gbapp/models/GBModel'; +/** + * A user and its metadata. + */ @Table export class GuaribasUser extends Model { @PrimaryKey @@ -90,6 +93,9 @@ export class GuaribasUser extends Model { public instance: GuaribasInstance; } +/** + * A group of users. + */ @Table export class GuaribasGroup extends Model { @PrimaryKey @@ -109,6 +115,9 @@ export class GuaribasGroup extends Model { public instance: GuaribasInstance; } +/** + * Relation of groups and users. + */ @Table export class GuaribasUserGroup extends Model { @ForeignKey(() => GuaribasUser) diff --git a/packages/security.gblib/services/SecService.ts b/packages/security.gblib/services/SecService.ts index d1fee375..358da06b 100644 --- a/packages/security.gblib/services/SecService.ts +++ b/packages/security.gblib/services/SecService.ts @@ -1,28 +1,31 @@ const Fs = require('fs'); -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); import { GBService, IGBInstance } from 'botlib'; import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from '../models'; +/** + * Security service layer. + */ export class SecService extends GBService { public async importSecurityFile(localPath: string, instance: IGBInstance) { - const security = JSON.parse(Fs.readFileSync(UrlJoin(localPath, 'security.json'), 'utf8')); + const security = JSON.parse(Fs.readFileSync(urlJoin(localPath, 'security.json'), 'utf8')); security.groups.forEach(group => { const groupDb = GuaribasGroup.build({ instanceId: instance.instanceId, displayName: group.displayName }); - groupDb.save().then(groupDb => { + groupDb.save().then(g1 => { group.users.forEach(user => { const userDb = GuaribasUser.build({ instanceId: instance.instanceId, - groupId: groupDb.groupId, + groupId: g1.groupId, userName: user.userName }); - userDb.save().then(userDb => { + userDb.save().then(user2 => { const userGroup = GuaribasUserGroup.build(); - userGroup.groupId = groupDb.groupId; - userGroup.userId = userDb.userId; + userGroup.groupId = g1.groupId; + userGroup.userId = user2.userId; userGroup.save(); }); }); diff --git a/packages/whatsapp.gblib/index.ts b/packages/whatsapp.gblib/index.ts index fbb4e983..43f0a5ec 100644 --- a/packages/whatsapp.gblib/index.ts +++ b/packages/whatsapp.gblib/index.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -36,22 +36,22 @@ 'use strict'; -import UrlJoin = require('url-join'); - -import { GBMinInstance, IGBCoreService, IGBPackage, GBLog, GBDialogStep } from 'botlib'; - +import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib'; import { Sequelize } from 'sequelize-typescript'; import { WhatsappDirectLine } from './services/WhatsappDirectLine'; +/** + * Package for whatsapp.gblib + */ export class GBWhatsappPackage implements IGBPackage { - public sysPackages: IGBPackage[] = undefined; + public sysPackages: IGBPackage[]; public channel: WhatsappDirectLine; public loadBot(min: GBMinInstance): void { // Only loads engine if it is defined on services.json. - if (min.instance.whatsappBotKey) { + if (min.instance.whatsappBotKey !== undefined) { this.channel = new WhatsappDirectLine( min.botId, min.instance.whatsappBotKey, @@ -63,9 +63,19 @@ export class GBWhatsappPackage implements IGBPackage { } } - public getDialogs(min: GBMinInstance) {GBLog.verbose (`getDialogs called.`);} - public loadPackage(core: IGBCoreService, sequelize: Sequelize): void {GBLog.verbose (`loadPackage called.`);} - public unloadPackage(core: IGBCoreService): void {GBLog.verbose (`unloadPackage called.`);} - public unloadBot(min: GBMinInstance): void {GBLog.verbose (`unloadBot called.`);} - public onNewSession(min: GBMinInstance, step: GBDialogStep): void {GBLog.verbose (`onNewSession called.`);} + public getDialogs(min: GBMinInstance) { + GBLog.verbose(`getDialogs called.`); + } + public loadPackage(core: IGBCoreService, sequelize: Sequelize): void { + GBLog.verbose(`loadPackage called.`); + } + public unloadPackage(core: IGBCoreService): void { + GBLog.verbose(`unloadPackage called.`); + } + public unloadBot(min: GBMinInstance): void { + GBLog.verbose(`unloadBot called.`); + } + public onNewSession(min: GBMinInstance, step: GBDialogStep): void { + GBLog.verbose(`onNewSession called.`); + } } diff --git a/packages/whatsapp.gblib/services/WhatsappDirectLine.ts b/packages/whatsapp.gblib/services/WhatsappDirectLine.ts index c3d61aaf..444a8d82 100644 --- a/packages/whatsapp.gblib/services/WhatsappDirectLine.ts +++ b/packages/whatsapp.gblib/services/WhatsappDirectLine.ts @@ -1,10 +1,13 @@ -import UrlJoin = require('url-join'); +import urlJoin = require('url-join'); const Swagger = require('swagger-client'); const rp = require('request-promise'); -import { GBService, GBLog } from 'botlib'; +import { GBLog, GBService } from 'botlib'; import * as request from 'request-promise-native'; +/** + * Support for Whatsapp. + */ export class WhatsappDirectLine extends GBService { public pollInterval = 1000; public directLineClientName = 'DirectLineClient'; @@ -16,7 +19,7 @@ export class WhatsappDirectLine extends GBService { public whatsappServiceUrl: string; public whatsappServiceWebhookUrl: string; public botId: string; - public watermark: string = null; + public watermark: string; public conversationIds = {}; @@ -36,7 +39,6 @@ export class WhatsappDirectLine extends GBService { this.whatsappServiceUrl = whatsappServiceUrl; this.whatsappServiceWebhookUrl = whatsappServiceWebhookUrl; - // TODO: Migrate to Swagger 3. this.directLineClient = rp(this.directLineSpecUrl) .then(spec => { return new Swagger({ @@ -47,12 +49,12 @@ export class WhatsappDirectLine extends GBService { .then(async client => { client.clientAuthorizations.add( 'AuthorizationBotConnector', - new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header') + new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${directLineSecret}`, 'header') ); const options = { method: 'POST', - url: UrlJoin(this.whatsappServiceUrl, 'webhook'), + url: urlJoin(this.whatsappServiceUrl, 'webhook'), qs: { token: this.whatsappServiceKey, webhookUrl: `${this.whatsappServiceWebhookUrl}/instances/${this.botId}/whatsapp`, @@ -64,7 +66,7 @@ export class WhatsappDirectLine extends GBService { }; try { - const result = await request.post(options); + const result = request.post(options); GBLog.info(result); } catch (error) { GBLog.error(`Error initializing 3rd party Whatsapp provider(1) ${error}`); @@ -91,17 +93,17 @@ export class WhatsappDirectLine extends GBService { const conversationId = this.conversationIds[from]; this.directLineClient.then(client => { - if (this.conversationIds[from] == undefined) { + if (this.conversationIds[from] === undefined) { GBLog.info(`GBWhatsapp: Starting new conversation on Bot.`); client.Conversations.Conversations_StartConversation() .then(response => { return response.obj.conversationId; }) - .then(conversationId => { - this.conversationIds[from] = conversationId; - this.inputMessage(client, conversationId, text, from, fromName); + .then(generatedConversationId => { + this.conversationIds[from] = generatedConversationId; + this.inputMessage(client, generatedConversationId, text, from, fromName); - this.pollMessages(client, conversationId, from, fromName); + this.pollMessages(client, generatedConversationId, from, fromName); }) .catch(err => { GBLog.error(`Error starting conversation ${err}`); @@ -183,9 +185,11 @@ export class WhatsappDirectLine extends GBService { break; case 'image/png': - GBLog.info('Opening the requested image ' + attachment.contentUrl); + GBLog.info(`Opening the requested image ${attachment.contentUrl}`); output += `\n${attachment.contentUrl}`; break; + default: + GBLog.info(`Unknown content type: ${attachment.contentType}`); } }); } @@ -200,7 +204,7 @@ export class WhatsappDirectLine extends GBService { public async sendToDevice(to, msg) { const options = { method: 'POST', - url: UrlJoin(this.whatsappServiceUrl, 'message'), + url: urlJoin(this.whatsappServiceUrl, 'message'), qs: { token: this.whatsappServiceKey, phone: to, diff --git a/src/app.ts b/src/app.ts index a5b0ba64..d87c942d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,7 +3,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -37,13 +37,12 @@ 'use strict'; -const logger = require('./logger'); const express = require('express'); const bodyParser = require('body-parser'); -import { IGBCoreService, IGBInstance, IGBPackage, GBLog } from 'botlib'; + +import { GBLog, IGBCoreService, IGBInstance, IGBPackage } from 'botlib'; import { GBAdminService } from '../packages/admin.gbapp/services/GBAdminService'; import { AzureDeployerService } from '../packages/azuredeployer.gbapp/services/AzureDeployerService'; -import { GuaribasInstance } from '../packages/core.gbapp/models/GBModel'; import { GBConfigService } from '../packages/core.gbapp/services/GBConfigService'; import { GBConversationalService } from '../packages/core.gbapp/services/GBConversationalService'; import { GBCoreService } from '../packages/core.gbapp/services/GBCoreService'; @@ -51,7 +50,7 @@ import { GBDeployer } from '../packages/core.gbapp/services/GBDeployer'; import { GBImporter } from '../packages/core.gbapp/services/GBImporterService'; import { GBMinService } from '../packages/core.gbapp/services/GBMinService'; -const appPackages = new Array(); +const appPackages: IGBPackage[] = undefined; /** * General Bots open-core entry point. @@ -68,7 +67,7 @@ export class GBServer { // bot instance. This allows the same server to attend multiple Bot on // the Marketplace until GB get serverless. - const port = process.env.port || process.env.PORT || 4242; + const port = GBConfigService.getServerPort(); const server = express(); server.use(bodyParser.json()); // to support JSON-encoded bodies @@ -79,7 +78,6 @@ export class GBServer { }) ); - let bootInstance: IGBInstance; server.listen(port, () => { (async () => { try { @@ -103,7 +101,7 @@ export class GBServer { // Creates a boot instance or load it from storage. - let bootInstance: IGBInstance = null; + let bootInstance: IGBInstance; try { await core.initStorage(); } catch (error) { @@ -132,7 +130,7 @@ export class GBServer { await core.saveInstance(fullInstance); let instances: IGBInstance[] = await core.loadAllInstances(core, azureDeployer, proxyAddress); instances = await core.ensureInstances(instances, bootInstance, core); - if (!bootInstance) { + if (bootInstance !== undefined) { bootInstance = instances[0]; } diff --git a/tslint.json b/tslint.json index 10699ef4..142f27d9 100644 --- a/tslint.json +++ b/tslint.json @@ -12,17 +12,20 @@ "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], "jsRules": {}, "rules": { - "no-unsafe-any":false, "newline-per-chained-call": false, + "no-unsafe-any": false, "no-floating-promises": false, "no-var-requires": false, "typedef": false, "variable-name": false, "no-parameter-properties": false, + "max-line-length": [true, { "limit": 120, "ignore-pattern": "^\\s+\\*" }], + "await-promise": [true, "Bluebird"], "no-reserved-keywords": false, "no-unnecessary-class": false, "no-require-imports": false, "function-name": false, + "no-relative-imports": false, "no-redundant-jsdoc": false, "no-return-await": false, "prefer-type-cast": false, @@ -35,9 +38,6 @@ "switch-final-break": false, "no-parameter-reassignment": false, "export-name": false, - "no-relative-imports": false, - "no-backbone-get-set-outside-model": false, - "max-line-length": [true, { "limit": 120, "ignore-pattern": "^\\s+\\*" }], - "await-promise": [true, "Bluebird"] + "no-backbone-get-set-outside-model": false } }